5

I have a sound player class that doesn't have any visuals at all, and I am trying to use a MediaElement to play my sounds. In all the test projects, in which the MediaElement is embedded in the XAML code, it works fine. However, in my code-only version, is doesn't play anything at all, even though the file has been loaded perfectly (I could see in the Debugger). I am doing the following:

public class MySoundPlayer
{
    private MediaElement player = new MediaElement();

    public MySoundPlayer()
    {
        player.LoadedBehavior = MediaState.Manual;
        player.UnloadedBehavior = MediaState.Stop;
        player.Volume = 1.0;
        player.MediaEnded  += player_MediaEnded;
        player.MediaOpened += playerr_MediaOpened;
        player.MediaFailed += player_MediaFailed;
    }

    private void player_MediaEnded(object sender, EventArgs e)
    {
        player.Stop();
        Debug.WriteLine("Stopped");
     }

    private void player_MediaOpened(object sender, EventArgs e)
    {
        Debug.WriteLine("Opened");
    }

    private void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
    {
        Debug.WriteLine("Failed");
    }

    public void PlayFile(string fileName, bool loop)
    {
        player.Source = new Uri(fileName, UriKind.RelativeOrAbsolute);
        player.Play();
        player.Volume = 1.0;
    }
}

I double-checked if the file exist, which it does (and it is even loaded correctly), and that my sound is turned on. :-) Also, when I change the MediaElement by SoundPlayer, it works perfectly fine. The only difference I can find is that I do not have it embedded in the XAML code. Is this a requirement?

Yellow
  • 3,955
  • 6
  • 45
  • 74

1 Answers1

7

In order to work the MediaElement must be part of the logical tree of your application and therefore must be added to some container (Grid, StackPanel) in your application.

You can add the MediaElement via XAML (as you have done it before) or you can add it during runtime via

LayoutRoot.Children.Add(player);

Instead of using the MediaElement you should use the MediaPlayer class. This will work (at least for me) without attaching it to XAML.

MediaPlayer player = new MediaPlayer();
player.Open(new Uri(fileName, UriKind.RelativeOrAbsolute));
player.Play();
Jehof
  • 34,674
  • 10
  • 123
  • 155
  • But my class is literally just this (code in question), so it doesn't have a layout, and therefore no `LayoutRoot`. Do I have to extend a `UserControl` in order to use the `MediaElement`? – Yellow Oct 28 '13 at 10:30
  • Aha, I didn't know of the existence of this `MediaPlayer`. That's what happens when you're new to an API. This works smoothly! – Yellow Oct 28 '13 at 10:38
  • You can also use MediaPlayer to draw a video onto a visual, so if you have audio 90% of the time, you won't need a MediaElement in the visual tree just for that 10% of the time. – Nick Oct 28 '13 at 13:30
  • Trying to instantiate MediaPlayer in a Windows Store Universal Project for 8.1 gives me this: `The type 'Windows.Media.Playback.MediaPlayer' has no constructors defined`. – Michael Antipin Mar 02 '16 at 10:27
  • Aha, nevermind. Looks like it is meant to be accessed through `BackgroundMediaPlayer.Current`. I daresay, MS has the most intertwined references of their assorted platform flavors. – Michael Antipin Mar 02 '16 at 10:48