1

I am new to this. I am trying to do a Audio Message Player on Rasp Pi 3 with Win IoT core. I manage to play audio file from my USB thumbdrive but I need to know when the audio file has completed playing.

 mediaPlayer = new MediaPlayer();
 mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;

 private void MediaPlayer_MediaEnded(MediaPlayer sender, object args)
    {
        GeneralMessage.Text = "Message Complete!";
    }

i get an error message with the above code.

System.Exception occurred
  HResult=0x8001010E
  Message=The application called an interface that was marshalled for a 
different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Please help.

JBC
  • 667
  • 1
  • 9
  • 21
mylim
  • 313
  • 4
  • 16
  • You are trying to modify a UI Element from a thread that is not the UI Thread. Usually you would use something like "Control.Invoke" to marshal that modification to the UI Thread. – Fildor Sep 13 '17 at 13:08
  • Is there anyway for me to display a string to indicated the file has completed playing? – mylim Sep 13 '17 at 13:09
  • Yes, use Invoke on GeneralMessage. I'll try to find an example ... – Fildor Sep 13 '17 at 13:10
  • https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls – Fildor Sep 13 '17 at 13:11
  • pardon my knowledge on c# may i know how to invoke a thread? – mylim Sep 13 '17 at 13:12
  • Not sure if this is applicable to Win IoT core, though. – Fildor Sep 13 '17 at 13:12
  • thanks.. I will try it and update here to share. – mylim Sep 13 '17 at 13:13
  • I just saw, it will probably **not** be applicable. Maybe this will help instead: https://stackoverflow.com/a/38207907/982149 It is about updating an int Property, but you can use Progress. – Fildor Sep 13 '17 at 13:24

2 Answers2

0

The reason of your problem is that, UI changes must be made on the UI thread but MediaEnded event is raised on a different thread.

In windows IoT Core, when you update the element in UI from another thread, please use the Dispatcher.RunAsync method.

Task.Run(async () =>
{
     //this part is run on a background thread...

     await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, 
        ()=> 
        {
             //this part is being executed back on the UI thread...
             GeneralMessage.Text = "Message Complete!";
        });
});

Please reference here Media items, playlists, and tracks.This article showed how to use MediaSource , and included the operations performed within a CoreDispatcher.RunAsync call.

Michael Xu
  • 4,382
  • 1
  • 8
  • 16
  • Hi Micheal, thanks. But it shows 'the name Task.Run does not exist in current context'. Any idea? – mylim Sep 18 '17 at 04:18
0

i manage to solve the invoke thingy.. code as follow

private async void MediaPlayer_MediaEnded(MediaPlayer sender, object args)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            GeneralMessage.Text = "Done playing.";

     });
mylim
  • 313
  • 4
  • 16