9

Is it possible to use the WPF MediaElement to play streaming video from a System.IO.Stream object? The Stream object is being retrieved from a WCF service that stores the media files.

rafale
  • 1,704
  • 6
  • 29
  • 43

5 Answers5

17

Before anyone wastes hours finding this out for themselves: it is impossible to host the Silverlight MediaElement in a WPF application. The reason for this is that it is one of a number of types that appear in PresentationFramework.dll (unavoidable for WPF) and System.Windows.dll (Silverlight versions) that have the same names and the same namespaces, but are different types. (Someone should explain why we have namespaces to microsoft!)

Robert
  • 171
  • 1
  • 3
  • 1
    This is true. Unfortunately I had to find this out the hard way. :( – rafale Nov 11 '11 at 03:42
  • 4
    I know this is a year-old answer, but aren't "multiple distinct types with the same name in the same namespace" the reason that reference aliases exist? – Damien_The_Unbeliever Nov 05 '12 at 09:19
  • 1
    It is always possible to make Silverlight Website and use MediaElement there and in WPF applicatione add WebBrowser control with source to that Silverlight website and it is done. – NoWar Feb 06 '13 at 11:50
  • yes @Damien_The_Unbeliever my thought at first - but it depends on how it plays out and I've seen situations where similar tricks aren't possible. Though I'd say this still 'might' be possible, with some hacking. Haven't tried though, looks like trouble – NSGaga-mostly-inactive Apr 12 '14 at 19:54
14

It might be too late, hopefully this might help if you're still looking for an answer.

Yes you can play video from Memory stream using WPF media element.

I have used a third party component called boxed app, A million thanks to BoxedApp - http://www.boxedapp.com/boxedappsdk/

I have to update the code a tiny bit to make it work for byte[]. Copy the below constructor to CustomFileStream class from BoxedApp

public CustomFileStream(byte[] data)
{
    _Stream = new MemoryStream(data);
    _Length = _Stream.Length;
    _data = data;
    _Offset = 0;
}

Create a wpf application and add a media element and a button and copy the below code

public MainWindow()
{
    BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

    InitializeComponent();
}

private void button2_Click(object sender, RoutedEventArgs e)
{
    var MyFileStream = new CustomFileStream(File.ReadAllBytes(@"wildlife.wmv"));

    IntPtr ptr = BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFileBasedOnIStream(
            @"1.wmv",
            BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
            BoxedAppSDK.NativeMethods.EFileShare.Read,
            IntPtr.Zero,
            BoxedAppSDK.NativeMethods.ECreationDisposition.New,
            BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
            IntPtr.Zero,
            MyFileStream);

    using (new SafeFileHandle(ptr, true))
    {
        mediaElement1.Source = new Uri(Path.GetFullPath("1.wmv"));
        mediaElement1.LoadedBehavior = MediaState.Manual;
        mediaElement1.Play();
    }
}
  • for boxed app please follow the samples and that's it.. you're in a happy world...

It's the same thing for QT Player as well.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
user1108125
  • 141
  • 1
  • 4
7

IF you can make the WCF deliver the Media Object via a http-URL (GET) then you can just assign that URL to the MediaElement.Source property - see http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.source.aspx.

For cases where such URL is not available/possible:

Assigning a Stream is currently not possible - although there are some hacks to make that happen, for a DirectShow-based example see http://social.msdn.microsoft.com/forums/en-US/wpf/thread/6191ef1a-0010-4294-a5b4-451bbadca33a/ and http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/15/WPF-Hackery-Part-I.aspx .

Another option would be to somehow host the Silverlight MediaElement and use the SetSource method which can take a stream and play it... see http://silverlightviewport.codeplex.com/SourceControl/list/changesets and http://msdn.microsoft.com/en-us/library/cc190669%28v=vs.95%29.aspx

Yahia
  • 69,653
  • 9
  • 115
  • 144
5

I know this isn't what you asked for but you can host a VLC ActiveX component inside a window in WPF and then use that VLC control to connect to the stream and display the stream. This is how I got streaming working through WPF.

Edit: this page has an example of how to host an ActiveX control inside WPF

Travis
  • 1,044
  • 1
  • 17
  • 36
stuartmclark
  • 1,203
  • 13
  • 22
  • 3
    Can I see an example of a WPF application running VLC as an ActiveX component? I'd like to see what it looks like and what's involved in getting it running before I actually go for it. – rafale Aug 20 '11 at 06:02
  • 1
    Hi Stuart, could you post your example using VLC somewhere so that I can have a look. Thanks. – Toan Nguyen Jan 29 '15 at 06:06
0

As WPF mediaelement internally uses windows media player. If you alter the buffer settings of media player from default buffer setting to custom. Open windows media player  Tools  Options  Performance.

When you choose “Buffer” option and set “Seconds of content” to 2. The following registry values will be added under media player. HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Preferences UseDefaultBufferTime=0 CustomBufferTime=2000

You can use dotnet registry class to make changes. Refer this link: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1b4b8fb9-ff8f-4861-8e99-4a7a4fc75596/setting-windows-media-player-properties-in-wpf?forum=wpf#ac879a7f-37bc-4ccc-854d-ab6e047086e5

somu
  • 51
  • 1
  • 6