0

I have two MediaElements to play two videos at a time. For that I have to wait for both to be loaded first. Otherwise, both videos will be played out of sync. To achieve this, I have set two boolean values to true when the MediaOpened event of MediaElement is fired. I want to play the videos once both variables are true. How can I do that?

bool IsOpened1=false;
bool Isopened2=false;
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
    if (IsOpened1 == true && IsOpened2== true) //have to wait here until it is true
    {
        MediaEL.LoadedBehavior = MediaState.Play;
        MediaEL2.LoadedBehavior = MediaState.Play;    
    }
}

private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
{               
    Isopened1 = true;
}

private void MediaEL2_MediaOpened(object sender, RoutedEventArgs e)
{
    Isopened2 = true;
}
3
  • 1
    Make the two bools as volatile bool. From each Media Element opened events - fire a Task. Task should first check for both bools to be true and then do the MediaLoadedBehavior change (May be on Dispatcher.Invoke etc). Commented Jul 6, 2020 at 6:04
  • Can you please explain with above code? user will call btnPlay_Click when clicking on Play button. There have to perform other functions after setting LoadedBehavior to play Commented Jul 6, 2020 at 6:27
  • @user2431727 Have you considered to use AsyncCountDownEvent (1, 2) for syncronization? You initialize a countdown with 2 and you call Signal when a given video is loaded. And in your event handler you are awaiting the WaitAsync to decrease the countdown to zero. Commented Jul 6, 2020 at 7:48

3 Answers 3

1

If you want your users to not be able to playback the videos until both are loaded, you could disable the play button of the MediaElement. This way, your user interface is not blocked and the user has an indication when the media is loaded. Since you use an event handler, I assume that you use code-behind, where you should be able to access the play button. Suppose this is your button in XAML.

<Button Name="btnPlay" Click="btnPlay_Click">Play</Button>

Then, in your code-behind you can set its IsEnabled property to true when both videos are loaded.

private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
{               
    Isopened1 = true;
    btnPlay.IsEnabled = AreBothVideosOpened();
}

private void MediaEL2_MediaOpened(object sender, RoutedEventArgs e)
{
    Isopened2 = true;
    btnPlay.IsEnabled = AreBothVideosOpened();
}

private bool AreBothVideosOpened()
{
    return IsOpened1 && IsOpened2;
}

This way you do not need to wait in your event handler. Note, that if you would wait on the UI thread, your user interface would be blocked until both videos are loaded. If you would wait asynchronously to not block the user interface, there would be no benefit at all for the user, because then he could click the play button multiple times without any feedback if the videos are loaded or your button just does not work.

Sign up to request clarification or add additional context in comments.

Comments

0

It could be easier by using Task.Delay to sleep for a duration (ex 1 sec), then check it back. But we should also give it a timeout when it's too long to prevent freezing application. Since Play button is clicked, it will be disabled until the timeout is reached or the media state is changed.

bool IsOpened1 = false;
bool IsOpened2 = false;

int Step = 1000;
int MaxSleepTime = 10000;

private async void btnPlay_Click(object sender, RoutedEventArgs e)
{
    btnPlay.Enable = false;

    int sleepTime = 0;

    while (MaxSleepTime > sleepTime)
    {
        if (IsOpened1 && IsOpened2)
        {
            MediaEL.LoadedBehavior = MediaState.Play;
            MediaEL2.LoadedBehavior = MediaState.Play;
            break;
        }

        sleepTime += Step;
        await Task.Delay(Step);
    }

    btnPlay.Enable = true;
    //Timeout
}

It's my quick code without testing, give me feedback if it's not working.

Update: I have updated my code from Thread.Sleep to Task.Delay because Thread.sleep will block the UI thread when Task.Delay is not.

4 Comments

With thread.sleep on UI thread - you are causing the UI to freeze. Not good.
@PrateekShrivastava I see, so await Task.Delay(milliseconds) would solve this?
Cant predict the time as one second. Usually it takes minimum of 30 seconds to load the videos. This may vary.
@user2431727 My code is giving 10 seconds timeout, you might give a minutes to it.
0

Since everything happens on the same thread, you could just execute btnPlay_Click (also) whenever any of the fields are set:

private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
{
    IsOpened1 = true;
    btnPlay_Click(btnPlay, EventArgs.Empty);
}

private void MediaEL2_MediaOpened(object sender, RoutedEventArgs e)
{
    IsOpened2 = true;
    btnPlay_Click(btnPlay, EventArgs.Empty);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.