locked
Setting the source of MediaElement to InMemoryRandomAccessStream not working

    Question

  • Hi,

    I have a buffer of type unsigned char * (videoBuf) that contains mp4 video. I want to play this video using MediaElement. My code as follow:

    auto videoIMS = ref new Windows::Storage::Streams::InMemoryRandomAccessStream();
    auto dw = ref new Windows::Storage::Streams::DataWriter(videoIMS);
    Array<unsigned char>^ data = ref new Array<unsigned char>(videoBuf, videoBufSize);
    dw->WriteBytes(data);
    task<unsigned int>(dw->StoreAsync()).then([dw, videoIMS, this](task<unsigned int> t){
    	return dw->FlushAsync();
    }).then([videoIMS, dw, this](task<bool> t){
    	if(t.get()){
    		SwitchToUIContext(Dispatcher, [videoIMS, this ]()
    		{
    			videoIMS->Seek(0);
    			myMediaElement->SetSource(videoIMS,L"video/mp4");
    			myMediaElement->Play();
    		});
    	}
    });

    When I run the above code the video is not playing. If I save the video buffer to a file and then read that file and set the stream to MediaElement it works.

    What is wrong in my code? and how I can make MediaElement play video from InMemoryRandomAccessStream?

    Thanks

    Tuesday, March 12, 2013 5:37 PM

All replies

  • Hello,

    I don't see anything obviously wrong in your code. It is not completely clear to me exactly how you are marshaling back to the UI thread but I assume you know what you are doing. Are you getting an error from the MediaElement? Handle the "OnError" event and relay the HRESULT. Hopefully this will give us an idea of what is going on.

    -James


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

    Tuesday, March 12, 2013 11:24 PM
    Moderator
  • Hello James,

    I handled MediaFailed event and I got MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0xC00D36C4 .

    As I mentioned in my post, when I saved the same buffer to file and then read it and set the stream to MediaElement it works. Also I checked the saved file and it is a valid mp4 video that I can play in external player. 

    The code that I used to save the buffer to file:

    create_task(KnownFolders::DocumentsLibrary->CreateFolderAsync("MyMedia", CreationCollisionOption::OpenIfExists))
    .then([this, videoBuf, videoBufSize](StorageFolder^ libraryFolder)
    {
    	return libraryFolder->CreateFileAsync ("test.mp4", CreationCollisionOption::ReplaceExisting);
    }).then([this, videoBuf, videoBufSize](StorageFile^ file){
    	return file->OpenAsync(FileAccessMode::ReadWrite);
    }).then([this, videoBuf, videoBufSize](Windows::Storage::Streams::IRandomAccessStream^ stream){
    	auto w = ref new Windows::Storage::Streams::DataWriter(stream);
    	Array<unsigned char>^ data = ref new Array<unsigned char>(videoBuf, videoBufSize);
    	w->WriteBytes(data);
    	return w->StoreAsync();
    });

    So what do you think the problem?

    Thanks

    Haider

    Wednesday, March 13, 2013 3:32 AM
  • Hello Microsoft Developers

    I am still waiting for a solution for the problem, is there anyone will help me in this.


    Monday, March 18, 2013 6:43 PM
  • I am also faced with this problem.  It works from a FileRandomAccessStream, but bit for bit the same stream from an InMemoryRandomAccessStream fails with the indicated error.  Here is the test I use:

    StorageFile fileToTest = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Test.mp4"));
                ras = new InMemoryRandomAccessStream();
                using (var stream = await fileToTest.OpenAsync(FileAccessMode.Read)) {
                    await RandomAccessStream.CopyAsync(stream, ras);
                }
                
                TestMedia.SetSource(ras, "video/mp4");
                TestMedia.MediaFailed += TestMedia_MediaFailed;
                TestMedia.CurrentStateChanged += TestMedia_CurrentStateChanged;
    As an edit, you might wonder why I want to do this.  I am trying to support encrypted video files (small size) which will be decrypted into an in-memory stream for playback.  I could write the file back to the disk first but that would be even slower and prone to easy attack.




    • Edited by Jim Borden Tuesday, April 30, 2013 7:34 AM
    Tuesday, April 30, 2013 7:31 AM
  • Hello Jim,

    I think either Microsoft team do not know the answer or they are do not care to answer.

    I think the only solution for this is writing the data to file and read it again and that what I did.

    Thursday, May 16, 2013 5:21 PM