[4.18] How to change volume of MediaPlayer playback?

I’m trying to implement multiple video playback on my VR application. I don’t know how to change the volume for specific separate MediaPlayer in C++. I’m working in UE 4.18.

User can dynamically import certain video from folder and display it as video player in 3D with controls panel: play/ pause/ volume slider. MediaPlayer creation is handled in C++ by wrapping it in my custom UObject-derived class.
Previous version of Media Framework allows me to control each video volume by changing it in UMediaSoundWave. Since UMediaSoundWave was replaced/integrated into UMediaSoundComponent i have no idea how to implement volme change properly.

I tried to create my own USoundClass and USoundMix and registering them in FAudioDevice:

Player	= NewObject< UMediaPlayer >( this );
...
SoundClass		= NewObject< USoundClass >( this );
SoundMix		= NewObject< USoundMix >( this );

FAudioDevice * audioDevice = FAudioDevice::GetMainAudioDevice();
if( audioDevice )
{
	audioDevice->RegisterSoundClass( SoundClass );
	audioDevice->PushSoundMixModifier( SoundMix );
}

Player->OpenFile( filepath );

then setting MediaPlayer and SoundClass in MediaSoundComponent:

this->SoundComponent	= CreateDefaultSubobject< UMediaSoundComponent >(TEXT("SoundComponent"));
this->SoundComponent->SetupAttachment(this->RootScene);
...

this->SoundComponent->MediaPlayer	= Player;
this->SoundComponent->SoundClass	= SoundClass;

so finally volume change is done like this:

if( !SoundClass )
	return;

FAudioDevice * audioDevice = FAudioDevice::GetMainAudioDevice();
if( audioDevice )
{
	audioDevice->SetSoundMixClassOverride( SoundMix, SoundClass, volume, 1.0f, 0.0f, false );
}

This code seems to not work, I can’t hear any volume change as an effect. How is the correct way to make this in new MediaFramework ?

When you say it’s not working, how are you evaluating that? Are you playing in PIE and not hearing the change? If so, that would be because you’re setting the sound class mix override on the main audio device. PIE, by default, does not use the “main” audio device. The “main” audio device in editor is the audio device used for content preview, etc. Another audio device is created and is associated with the UWorld used for the viewport that creates the PIE. The code you have to GetMainAudioDevice() won’t be sufficient. You’ll need to find the specific audio device that is playing the sound. That can be done from finding the UWorld the asset is associated with, then calling the GetAudioDevice() function associated with the UWorld. There should be plenty of examples if you check out the static gameplay functions (like SpawnSoundAttached, PlaySoundAtLocation, etc.).

1 Like

I found out my approach overcomplicated. Instead of using dynamically created USoundClass I can directly change audio volume in UMediaSoundComponent by accessing it’s UAudioComponent property and then using AdjustVolume method:

UAudioComponent * audioComponent = SoundComponent->GetAudioComponent();
audioComponent->AdjustVolume( 0.0f, volume );

GetAudiocomponent requires you to add “AudioMixer” module in your .Build.cs file.

Appendix:

If somone would wonder how to dynamically create USoundClass and use it with UMediaSoundComponent I got it working. The key is to restart UAudioComponent obtained from MediaSound by using Stop and Play methods after setting it’s SoundClassOverride property. There is also important note from @Minus_Kelvin about getting proper FAudioDevice from object’s UWorld context.

MediaPlayer = NewObject< UMediaPlayer >( this );
SoundClass	= NewObject< USoundClass >( this );
SoundMix	= NewObject< USoundMix >( this );


UWorld * world = MediaSoundComponent->GetWorld();
FAudioDevice * audioDevice = world->GetAudioDevice();

UAudioComponent * audioComponent = MediaSoundComponent->GetAudioComponent();

if( audioDevice && audioComponent )
{
	audioDevice->RegisterSoundClass( SoundClass );
	audioDevice->PushSoundMixModifier( SoundMix );

	audioComponent->SoundClassOverride = SoundClass;
	audioComponent->Stop();
	audioComponent->Play();
}

...

audioDevice->SetSoundMixClassOverride( SoundMix, SoundClass, volume, 1.0f, 0.0f, false );
2 Likes

Hey thanks for following up with this :slight_smile:

Hi, is there a way to get the AudioComponent from a MediaSound component via blueprints? I cna’t see a way to change the volume of a MediaPlayer without diving into C++.

I know how to do it by using SoundClass/SoundMix approach in Editor. Create SoundClass and SoundMix assets in Editor content browser. In your MediaSoundComponent set SoundClass property to asset you’ve created. In blueprint register your SoundMix using PushSoundMixModifier BP node. Then call SetSoundMixClassOverride node which allows you to change volume by using your SoundClass and SoundMix assets.

Would not have guessed that. Thanks @JohnKovalsky

Sadly, trying to use SoundMix and SoundClass doesn’t not affect the volume of the Media Player. It works for Play Sound 2D, but not for controlling Media Player sound.

I cannot control the volume of the Media Player no matter what I try:

i have the same issue … do you found a solution ?
Thanks