locked
[UWP] MediaElement cannot play WAV file RRS feed

  • Question

  • Hello,

    Build 10074, VS 2015 RC.
    I'm actually trying to use a MediaElement to play a stream coming from the Oxford TTS API (format is riff-16khz-16bit-mono-pcm). As it does not output anything when I specified audio/x-wav as the MIME type for the second parameter of MediaElement.SetSource, I'm now trying to play a plain WAV file I stored in my assets and it doesn't output anything either (nor does it raise any exception):

    var audio = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\Audio.wav");
    using (var file = await audio.OpenAsync(Windows.Storage.FileAccessMode.Read)) {
        media.SetSource(file, "audio/x-wav"); // audio/vnd.wave
        media.Play();
    }

    Am I doing something wrong or is it a limitation of the current build?

    Thanks!


    Yves Dolce


    Monday, May 18, 2015 7:49 PM

Answers

  • Hello,

    You need to make sure the MediaElement (ME) is at the page scope and not created in the body of a function. The best way to do this is to create the ME in XAML and set its visibility to "collapsed". Give this a try and let me know if it works for you.

    We have a number of audio playback APIs for Universal apps:

    WASAPI

    XAudio

    AudioGraph

    Using the MediaElement is by far the easiest way to play audio. You can load the audio data from the network, save it in a random access stream and set the stream to the source of the ME. The key to being successful with this scenario is that you must have all of the audio data saved to the random access stream before passing the data to the ME. In other words you cannot continue to add data to the random access stream once you pass it to the ME.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 11:12 PM

All replies

  • Hello,

    The media stack is not working on some interim builds but should work properly on 100074. I have a later build and will check to see if I can get it working. Can you please upload a small wave file to your OneDrive and post a link here?

    Are you handling the MediaFailed event? I would also recommend handling the CurrentStateChanged event and log the state transitions. Between these two it should give you some idea as to why playback is failing.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 8:06 PM
  • Thanks James. While I follow your advice, here is the whole file, it's just 101KB.
    https://onedrive.live.com/redir?resid=e51945a31b297e91!252826&authkey=!ACyHlowzsEjwut0&ithint=file%2cwav
    I'll report back here.

    Yves Dolce

    Monday, May 18, 2015 8:17 PM
  • I unfortunately don't see anything w/ that code, nor does it break if I set BPs in the event handlers:

    var media = new MediaElement() {
        AutoPlay = false,
    };
    var audio = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\Audio.wav");
    using (var file = await audio.OpenAsync(Windows.Storage.FileAccessMode.Read)) {
        media.MediaFailed += Media_MediaFailed;
        media.CurrentStateChanged += Media_CurrentStateChanged;
        media.SetSource(file, "audio/x-wav"); // audio/vnd.wave
        media.Play();
    }
    
    private void Media_CurrentStateChanged(object sender, RoutedEventArgs e) {
        Debug.WriteLine("Media_CurrentStateChanged");
    }
    
    private void Media_MediaFailed(object sender, ExceptionRoutedEventArgs e) {
        Debug.WriteLine($"Media_MediaFailed({e.ErrorMessage})");
    }


    Monday, May 18, 2015 8:24 PM
  • Hello Yves,

    Well that is totally unexpected. You should get at least one CurrentStateChanged event raised. Make sure "AutoPlay" is set to "true" and remove your explicit call to "Play". See if that changes the behavior any. If the file is in the appx package you can just set the URI of the source rather than opening the storage file.

    Can you play the file with the UWP media player?

    I'm having problems with VS running on my later build. I need to find the correct version of VS to run on this build. It may take me some time to get things setup but I will report back once I have everything setup and tested.

    Thanks,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 8:35 PM
  • Thanks.

    Those event handlers are still not called, even after setting AutoPlay to true and removing the Play method call. To be clear, this is a universal application.

    Also, FWIW, XBox music on Windows 10 10074 can play the file.


    Monday, May 18, 2015 8:44 PM
  • Hello Yves,

    How about just setting the URI rather than loading the file first. Does that work?

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 8:57 PM
  • With or without the Play call below, no sound, no call to event handlers:
    var media = new MediaElement() {
        AutoPlay = true,
    };
    media.MediaFailed += Media_MediaFailed;
    media.CurrentStateChanged += Media_CurrentStateChanged;
    media.Source = new Uri("ms-appx:///assets/audio.wav");
    media.Play();

    Monday, May 18, 2015 9:03 PM
  • That is really strange. Does it work with any other audio only formats such as m4a or wma?

    I'm almost done installing an updated version of VS on my newer build. I'll let you know what I find.

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 9:14 PM
  • M4A doesn't work either.
    FWIW, that code was both at the App level (OnLaunched) and in a Page (PageLoaded): same behavior.
    Monday, May 18, 2015 9:23 PM
  • I just took another look at your code. It looks like you are explicitly crating the MediaElement (ME) in code. Are you adding it to the XAML visual tree at any point? The ME is a XAML control and although you are only playing back audio and don't need a visual component the ME still needs to be added to the visual tree to enable it's internal event system. Make sure you add the ME as a child to at least one visual component.

    Something like this should work (where _grdPageContainer is the root grid control of the Page and media is an instantiated MediaElement object):

    _grdPageContainer.Children.Add(media);

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 9:40 PM
  • Are you suggesting something like this:

    private void Page_Loaded(object sender, RoutedEventArgs e) {
        var media = new MediaElement() {
            AutoPlay = true,
        };
        this.MyGrid.Children.Add(media);
        media.MediaFailed += Media_MediaFailed;
        media.CurrentStateChanged += Media_CurrentStateChanged;
        media.Source = new Uri("ms-appx:///assets/Recording.m4a");
        media.Play();
    }
    
    If you do, it's not working. However, this was not my real goal: what I want is to be able to play the sound from a stream coming back from an Oxford TTS REST request. Is the use of the MediaElement, and adding it to the visual tree, the only way to play a sound (e.g. .wav) in an Universal App?

    Monday, May 18, 2015 9:45 PM
  • Hello,

    You need to make sure the MediaElement (ME) is at the page scope and not created in the body of a function. The best way to do this is to create the ME in XAML and set its visibility to "collapsed". Give this a try and let me know if it works for you.

    We have a number of audio playback APIs for Universal apps:

    WASAPI

    XAudio

    AudioGraph

    Using the MediaElement is by far the easiest way to play audio. You can load the audio data from the network, save it in a random access stream and set the stream to the source of the ME. The key to being successful with this scenario is that you must have all of the audio data saved to the random access stream before passing the data to the ME. In other words you cannot continue to add data to the random access stream once you pass it to the ME.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 11:12 PM
  • Thanks James! Yes it works now but I'll still investigate those other APIs as I don't want to have to tie it to a UI just to produce sound.
    Monday, May 18, 2015 11:27 PM
  • Good to hear it is working for you. If you have any questions about those other APIs I recommended feel free to start a new thread. I usually go through the forums in the afternoon.

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, May 18, 2015 11:31 PM