I have a MediaPlayerElement and the following class to control it:
class MediaPlayer : INotifyPropertyChanged
{
private MediaPlaybackState _State;
public MediaPlaybackState State
{
get
{
return _State;
}
set
{
_State = value;
OnPropertyChanged();
}
}
public BitmapImage AlbumArt;
public string Title;
public string Subtitle;
private MediaPlayerElement mediaPlayer;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public void PlayerStateChanged(MediaPlaybackSession session, object sender)
{
State = session.PlaybackState;
}
public void SetMediaElement(MediaPlayerElement param)
{
mediaPlayer = param;
}
public void PlayFromSearchResult(SearchResult result)
{
AlbumArt = new BitmapImage();
AlbumArt.UriSource = new Uri(result.StationImage);
Title = result.StationName;
Subtitle = result.Subtext;
PlayFromRemoteM3U(result.StreamURL);
}
public void Pause()
{
mediaPlayer.MediaPlayer.Pause();
}
public void Play()
{
mediaPlayer.MediaPlayer.Play();
mediaPlayer.MediaPlayer.PlaybackSession.PlaybackStateChanged += PlayerStateChanged;
}
public async void PlayFromRemoteM3U(string url)
{
--SNIP--
mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(streamDownloadUrl));
Play();
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
I would like to have a play/pause button that changes it's content based on the current player state, I'm currently debugging with a TextBlock to display the current state:
<TextBlock x:Name="media_player_state" x:FieldModifier="public" FontSize="20" Text="{x:Bind MediaPlayerInstance.State, Mode=OneWay}">Play</TextBlock>
When I run the application and start a stream so the state changes, I get the following error:
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
I want to know if there I am trying to accomplish this the right way or how to fix this.
Thanks
Because you're calling it from another thread, you need to use a dispatcher
public void PlayerStateChanged(MediaPlaybackSession session, object sender)
{
DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
State = session.PlaybackState;
});
}
please note 2 things:
1- DispatcherHelper is part of the windows community toolkit nuget package (https://www.nuget.org/profiles/Microsoft.Toolkit)
2- DispatcherHelper will be deprecated in favor of the better DispatcherQueueHelper in the 7.0 release
Because you are not setting the state everytime you Play() or Pause(). Change the _State value and then use OnpropertyChanged("State")
User contributions licensed under CC BY-SA 3.0