Is it possible to dynamically import files (i.e. .wav) during runtime using Blueprints?

I’m looking for a way to load files (specifically audio files in .wav format) from any directory folder (or sub-folder) during run-time using blueprints. I am currently using Unreal Engine 4.7.6.

What I am doing is having the users open and form a LAN network using ‘shared’ files on a remote storage location. At the moment I tweaked the Multiplayer “Shootout” tutorial provided in the learning section to hook up a Network connection between two computers that open the same unreal project executable from a remote storage on an internal network. I intend the users to be able to access a sub-folder within the project’s directory - or another folder on the network where I can have the user’s drop their own in-game music (.wav files) and then during the game, they can select their files (or another user’s) music (.wav) file to use as the background music without the need for importing the music into the editor. If it requires a restart of the unrealproject.exe, that would be acceptable.

Another way to think of it is for user created maps in games like Sins of a Solar Empire, Starcraft, Age of Empires, &c to be loaded without needing to edit the project’s code.

I have looked at a simple save/load example, but have not played with it yet (Unreal Engine, Save & Load game data - UE4U.XYZ - YouTube). Would I simply load with an extension of .wav, or will Unreal expect this information to be saved first in a format (perhaps.save) that it recognizes?

[As a side note, for performance I edited the user’s profile to force the program to open in the lowest settings located in \WindowsNoEditor\Intermediate\Config.]

I’m hoping to use a “fancy read/load” of files in Blueprints.
Is this something I should use C++ for?

Thanks in advance,

SmashRash

1 Like

Updating 11/06/2015: I am currently looking into a method of using C++ coding and importing that into Blueprints to use those libraries to import, at run-time, files and browse directories. I did not have any luck in using Blueprints directly. I’m currently collaborating with a friend of mine who writes more extensively and is more familiar with the C++ methods.

Additionally I found and am comparing with Rama’s and yRazaei’s to produce only what I need.

I suspect needing to possibly troubleshoot the C++ code after packaging as some users have experienced coding snaffoos at that phase.

I’ve worked with some Basic code in the past and it included the ability to browse file directories. Point is I would like to suggest the feature in Blueprint form to browse user’s file directories (when I get a more solid foundation of the steps to figure this out, I may place that suggestion in a more appropriate place instead of on this forum). And then maybe it exists beautifully in C++ and simple adding the C++ code or plugin, but its visibility on the internet is difficult - at least for myself.

You are right in following/using Rama’s code. Ther is no such thing in Blueprints. I suspect you also need to write some code to be able to play those wav files.

Here is what I got working for importing a WAV file into a USoundWave during runtime.

USoundWave* SpeechSystem::GetSoundWaveFromFile(const FString& filePath)
{
	USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass());

	if (!sw)
		return nullptr;

	TArray < uint8 > rawFile;

	FFileHelper::LoadFileToArray(rawFile, filePath.GetCharArray().GetData());
	FWaveModInfo WaveInfo;

	if (WaveInfo.ReadWaveInfo(rawFile.GetData(), rawFile.Num()))
	{
		sw->InvalidateCompressedData();

		sw->RawData.Lock(LOCK_READ_WRITE);
		void* LockedData = sw->RawData.Realloc(rawFile.Num());
		FMemory::Memcpy(LockedData, rawFile.GetData(), rawFile.Num());
		sw->RawData.Unlock();
		
		int32 DurationDiv = *WaveInfo.pChannels * *WaveInfo.pBitsPerSample * *WaveInfo.pSamplesPerSec;
		if (DurationDiv)
		{
			sw->Duration = *WaveInfo.pWaveDataSize * 8.0f / DurationDiv;
		}
		else
		{
			sw->Duration = 0.0f;
		}
		sw->SampleRate = *WaveInfo.pSamplesPerSec;
		sw->NumChannels = *WaveInfo.pChannels;
		sw->RawPCMDataSize = WaveInfo.SampleDataSize;
		sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
	}
	else {
		return nullptr;
	}

	return sw;
}

[Edit]
Initially I said this wasn’t working, however it actually does work - I had a problem in a different code path.

1 Like

Thanks Judgementalex!,

I will play with this. I apologize for the delayed response. I spent last week looking at Rama’s code when I should have paid more attention to my own thread. I’ll get back to you (and this thread) with my own results hopefully by the end of this week.

Standby for phase jump,
SmashRash

Hey man,

So I did some testing with this, and while it works in the editor - with a standalone build I get the following error:

[2015.11.16-02.16.28:700][208]LogAudio:Error: Attempt to access the DDC when there is none available on sound 'SoundWave /Script/Engine.SoundWave:SoundWave_0', format = OGG. Should have been cooked.
[2015.11.16-02.16.28:700][208]LogXAudio2:Warning: Failed to create audio buffer for 'SoundWave /Script/Engine.SoundWave:SoundWave_0'

If anyone can spot the problem here, it would be greatly appreciated.

I’m able to get my standalone game up and running in Unreal Engine v.4.7.6 however the classes I make (actor, player controller, character) themselves fail to perform their functions.

At first I thought my .wav file was failing to load due to some strange file path and permissions, but tested multiple locations on my computer (i.e. C:, my user music folder, and even the packaged project’s directory), different classes and then simple print statements on “Event Begin Play” and “Event Ticks” and none of my Blueprints in a standalone game operate - or so it appears since none of the simple “Print String” nodes are firing off.

   To state the more obvious to your question/problem - did you cook your content? I'm not sure that will help, but it may. I'm on a Windows machine and it is located in File >> Cook Content for Windows. I assume you have more detail in your program which is causing a conflict.

   When I've been testing this code I've been doing it from a new project and have stock classes. Then I create a C++ class, add the working (in editor at least) code to that C++ class, replace "SpeechSystem" to match my class name in the .cpp code, edit the associating header (.h) file with something like: 
	//
	UFUNCTION(BlueprintCallable, Category = "AudioLoad")
		virtual USoundWave* LoadSoundFromFile(const FString& filePath);
I also added the step of setting the "Build Configuration" in Visual Studio 2013 to reflect my package options in Unreal Editor. So in my current tests that would be "Shipping" and "Windows" (32bit if option available).

As for the ".ogg" I have not yet tried file formats outside of .wav.

I'll let you know if I can get something working in the standalone game. 

 - I intend to try trigger events (user input) and 
 - Test it out on UEv4.9.2.
 - A comparison with known and tested working code (i.e. Rama's Victory Plugin).

Well the odd thing with the “ogg” error is that I haven’t been loading OGG files, only 16bit WAV files. The sounds are generated at runtime, hence my need to import them dynamically. This means of course that there is no way of cooking those assets. I’ll play around a bit more since Rama’s code works for standalone builds afaik.

First, I resolved why my Blueprints were not functioning properly. Turns out I forgot to specify that the UCLASS(Blueprintable) in the header file. So even though my blueprints had their parent class (in the blueprint Default Settings) assigned as my C++ code class, their nodes never fired.
However the sound is still not loading - although I have no errors, I’m certain some part of the code is failing during the standalone; not yet certain which but I’ve been minimizing the code (next I think I will prepare ‘dummy’ return statements).

I did test it out on UEv4.9.2 with no difference in results.

Thanks to judgementalex I’ve started to change my thinking from how to get the sound loaded into more of what the difference between the standalone and the .uproject are (in particular with USoundWave and FWaveModInfo)- for why code would run on one but not the other. I’ll keep you informed of my results for where the code is malfunctioning in the standalone.

Note: Due to Thanksgiving holiday I will likely not be actively working to resolve this until December 1st. I came across my Build.cs needing to include the OnlineSubSystem keywords due to C++ code existing - otherwise I get a Failed Network Connection. Due to this, the node ‘functioning’, but not, I thought maybe my soundwave import at runtime may be having a similar issue. Still need to run break tests on the C++ code. ~Happy Thanksgiving!~
Within the .Build.cs file (and uncomment the online comment features):

PublicDependencyModuleNames.AddRange(
new string[] {
“Core”,
“CoreUObject”,
“Engine”,
“InputCore”,

            //Enable Online LAN/Internet Functionality
            "OnlineSubsystem", 
            "OnlineSubsystemNull", 
            "OnlineSubsystemUtils" 
        });

Interestingly enough I got my hands back into testing this and was able to succeed when packaging the project as a 64-bit Development Build! Imagine my happiness. I’m continuing my investigation as for the differences between the Shipping and Development build but that has me on the correct track I think.

Additionally of note may be that I am running the program on a 64-bit operating System of Windows 8.1 Pro ~ in case that is also affecting the difference (i.e. Shipping packages in a 32-bit version and not a 64-bit version).

This lead me to something like the following forum thread: Development versus Shipping Build Errors - Programming & Scripting - Unreal Engine Forums

Edit: I Only got it to work once in Development Packaging on 12/04/2015. Not certain what happened between then and the time I tried it again in another Development package. I tried removing .ini files from %APPDATA%\Local and still had the same issues ~ a good experience about .ini and configuration files, use and location. Will continue to troubleshoot after advancing the program’s features that I can do something about.

Doing this on iPhone I get an alignment issue with the pointers.

Copying into local variable fixes the alignment problems but no sound playing at this moment.

//Copy into aligned local variables. Probably faster way to do this but ay okay

uint16 bitspersample; //WaveInfo.pBitsPerSample
	FMemory::Memcpy(bitspersample, *WaveInfo.pBitsPerSample);
	uint32 samplespersec;//WaveInfo.pSamplesPerSec
	FMemory::Memcpy(samplespersec, *WaveInfo.pSamplesPerSec);
	uint16 nchannels;//*WaveInfo.pChannels
	FMemory::Memcpy(nchannels, *WaveInfo.pChannels);
	uint32 wavedatasize;// = WaveInfo.pWaveDataSize;
	FMemory::Memcpy(wavedatasize, *WaveInfo.pWaveDataSize);

	int32 DurationDiv = nchannels * bitspersample * samplespersec;
	if (DurationDiv)
	{
		sw->Duration = ((float)wavedatasize) * 8.0f / (float)DurationDiv;
	}
	else
	{
		sw->Duration = 0.0f;
	}
	sw->SampleRate = samplespersec;
	sw->NumChannels = nchannels;

And actually it crashes, just not on the first couple of sounds I tried. Also get’s the “should cook” error only with format = ADPCM and on PC WindowsNoEditor I get the OGG error you have above.

So… Any ideas?

[Detagged Matt, I wanted MattG] @Rama any ideas if this is even possible or who would know? If not then it seems UGC audio content becomes a lot harder with a requirement to cook assets per platform.

If that is the case, rather than getting the editor to the user my first thought is to have it running on a server taking requests for asset cooking and returning files to content creators, somehow.

Were you ever able to figure this out? I can’t get it working in packaged builds either :confused:

No sir, had to drop the feature

Jared Therriault,

Unfortunately as Judgementalex suggests I too had to not use the feature (thanks again Judgementalex for your assistance with this → I’ve had projects named after you). I do remember getting it to work once but not consistently - and that’s where my thoughts turned to the differences in the development build (with the command debug console) and the shipping build. But tests afterward were unable to replicate the success even once.

I did get Rama’s attention in an email, but did not get a second reply on scheduling a time to screen share due to Rama’s agenda. I’m still interested in it, but have moved to other projects and feature testing so effectively I suspended my project which involves this feature. Additionally since then I have searched for run-time changes to landscape which also seem scarce in UE4 but some people have made projects that make it more doable. With GDC in full swing at the moment it does look like there will be improvements to Matinee (the new Sequencer I believe).

Happy Belated St. Patrick’s Day and

Thanks for your interest,
SmashRash

My final solution to this is horrible btw - I send the WAV files to a server running the editor and a custom plugin that bakes the assets. Not sure I’m going to use this in a live environment yet and I wouldn’t in its current form but the POC passed it’s tests.

Hi folks -

Did you ever get to the bottom of how ot do this as I’d like to be able to import music at runtime too.

Cheers,

P

P,

Sorry, there was no “silver bullet” at the time. I have not revisited this. I’m sure it is possible in the C++, as far as using UE4’s graphic user interface I thought up ways to add to the content browser within or use a server. Neither were/are worth my effort at this time. I’ll likely revisit this at some point, but at the moment I’ve moved onto a different project.

I do get the feeling since this post, Epic Inc has made some promising improvements to their engine’s capabilities, but I do not believe this was one of them yet.

Keep on keeping on,
SmashRash

Yes, you can load .wav (and other media) files dynamically at runtime using only blueprints. This will work both in the editor and in builds.

  • In the content browser, create a “Media Player”. Open it and ensure that “Play on Open” is checked.

  • Create an actor blueprint and open it.

  • In the “Components” pane of the blueprint (upper left corner), use “Add Component”, “Media Sound”.

  • Select the newly created media sound, and in the “Details” panel on the right, under “Media”, select your Media Player asset that you created in step 1.

  • In the “My Blueprint” pane, under Variables/Components, drag the media sound into the event graph and chose “get”.

  • From this node, drag and search for “Get Media Player”.

  • Create a variable of type Media Player. Drag it into the event graph and select “set”.

  • From the “BeginPlay” event, set your Media Player variable from the “Get Media Player” node

  • When you’re ready, get the input filepath to the audio file by whatever means you choose.

  • Use the Utilities/String/Replace node to replace all backslashes with forward slashes in the filepath.

  • Prepend the filepath with “file://” using the String/Append node. Your filepath is now a url.

  • Optionally, use the MediaPlayer “Can Play Url” node to validate the audio url before opening.

  • Drag the Media Player variable into the graph with “get”, and drag off of that and search for “open url”. This will begin playing the audio file.

  • On windows, if you run into issues with playback (such as stuttering or audio ending too early), try fiddling with these, hit “set as default”, and restart UE4:

  • Project Settings → Plugins → WMF Media → Media → Allow Non-Standard Codecs

  • Project Settings → Plugins → WMF Media → Media → Low Latency

  • Project Settings → Plugins → WMF Media → Debug → Native Audio Out

3 Likes