1

I have this code:

    MediaElement player = new MediaElement();
    Windows.Storage.StorageFolder folder;
    Windows.Storage.StorageFile file;
    string FileName = "";

    private async void Play(string Tno, string Cno)
    {
        folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");

        for (int i = 1; i <= 4; i++)
        {
            switch (i)
            {
                case 1:
                    FileName = "Sound\\mysound1.wav";
                    break;
                case 2:
                    FileName = "Sound\\mysound2.wav";
                    break;
                case 3:
                    FileName = "Sound\\mysound3.wav";
                    break;
                case 4:
                    FileName = "Sound\\mysound4.wav";
                    break;
            }

            file = await folder.GetFileAsync(FileName);
            player.SetSource(await file.OpenAsync(Windows.Storage.FileAccessMode.Read), file.ContentType);
            player.Play();
    }
}

It plays sound "mysound4.wav". When I tracked the code, it plays the 4 files too quickly without any delays. So how can I play the second file only when the first one is finished?

mm8
  • 163,881
  • 10
  • 57
  • 88
Ammar
  • 33
  • 7
  • If it was me i'd wrap up each wav in descriptor-wrapper class that hold data on file e.g path, duration etc... Enqueue the wrapper to special queue that knows when to dequeue (you must remember the last time item was deqeue and check if duration has ended) an item and play it – ilansch Apr 04 '17 at 08:53
  • Try using the CurrentState property of the Mediaelmement: https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.mediaelement#Windows_UI_Xaml_Controls_MediaElement_CurrentState – Svein Terje Gaup Apr 04 '17 at 08:55
  • What if this method is called in a multi threaded env. You want only one media to play at a time. – ilansch Apr 04 '17 at 09:00
  • Why not try [PlaySync](http://msdn.microsoft.com/en-us/library/system.media.soundplayer.playsync.aspx) – sharp Apr 04 '17 at 09:21
  • Possible duplicate of [WPF, how to determine when a MediaElement has finished playing the movie?](http://stackoverflow.com/questions/1738967/wpf-how-to-determine-when-a-mediaelement-has-finished-playing-the-movie) – Sinatr Apr 04 '17 at 09:30

1 Answers1

2

In a WPF application a solution can be to use a Queue like this...

public partial class MainWindow : Window
{
    private readonly Queue<string> _audioFilesQueue = new Queue<string>();
    private readonly MediaElement _player;

    public MainWindow()
    {
        InitializeComponent();

        _player = new MediaElement();
        _player.LoadedBehavior = MediaState.Manual;
        _player.UnloadedBehavior = MediaState.Manual;
        _player.MediaEnded += Player_MediaEnded;
    }

    private void Player_MediaEnded(object sender, RoutedEventArgs e)
    {
        OnProcessQueue();
    }

    private void Btn_OnClick(object sender, RoutedEventArgs e)
    {
        PlayCascade(new[]
        {
            "X:\\Library\\Sounds\\Other\\sound1.wav",
            "X:\\Library\\Sounds\\Other\\sound2.wav",
            "X:\\Library\\Sounds\\Other\\sound3.wav"
        });
    }

    private void PlayCascade(string[] sequence)
    {
        foreach (var file in sequence)
        {
            _audioFilesQueue.Enqueue(file);
        }
        OnProcessQueue();
    }

    private void OnProcessQueue()
    {
        Dispatcher.Invoke(() =>
        {
            if (_audioFilesQueue.Any())
            {
                var toPlay = _audioFilesQueue.Dequeue();
                _player.Source = new Uri(toPlay);
                _player.Play();
            }
        });
    }
Grappachu
  • 1,259
  • 13
  • 21
  • 1
    The queue is a very nice touch, but you should put more emphasis in answering the question (the part of your code that _really_ answers the question is the event callbacks). Don't get me wrong, Queues were _made_ for this, but it's just a quality improvement that swamps the real answer in this case. Maybe add 2 snippets: one just explaining how the callbacks work, and this one, with the queue. – This company is turning evil. Apr 04 '17 at 09:24
  • IT is really good code, thank you but unfortunately VS 2017 does not contains MediaState.Manual so i comment those codes and it didn't work _player.LoadedBehavior = MediaState.Manual; _player.UnloadedBehavior = MediaState.Manual; any advice? – Ammar Apr 08 '17 at 20:11
  • It's not question of VS, i think you are not working on a WPF application but on a UWP. However my code refers to a WPF desktop application so don't mind removing lines or adapt to your needs – Grappachu Apr 09 '17 at 21:58
  • Yes it is working when I added PresentationCore.dll I have another weird error in the dll file but at least I got the code. Thank you so much – Ammar Apr 10 '17 at 16:06