2

I'm developing WPF application that stores some sound files as array of bytes in database. I want play these files via MediaElement control. MediaElement has Source property but its type is Uri. Does anyone know if it is possible to convert array of bytes to Uri?

Thanks

user2250152
  • 14,658
  • 4
  • 33
  • 57

1 Answers1

2

Here is a workaround using a self hosted media server

let's start

MainWindow.xaml

<MediaElement x:Name="media" />

MainWindow.cs

public MainWindow()
{
    InitializeComponent();

    //host a media server on some port
    MediaServer ws = new MediaServer(RenderVideo, "http://localhost:8080/");
    ws.Run();

    //set the media server's url as the source of media element
    media.Source = new Uri("http://localhost:8080/");
}

private byte[] RenderVideo(HttpListenerRequest r)
{
    //get the video bytes from the server etc. and return the same
    return File.ReadAllBytes("e:\\vids\\Wildlife.wmv");
}

MediaServer class

class MediaServer
{

    private readonly HttpListener _listener = new HttpListener();
    private readonly Func<HttpListenerRequest, byte[]> _responderMethod;

    public MediaServer(Func<HttpListenerRequest, byte[]> method, string prefix)
    {
        if (!HttpListener.IsSupported)
            throw new NotSupportedException(
                "Needs Windows XP SP2, Server 2003 or later.");

        if (prefix == null)
            throw new ArgumentException("prefix");


        if (method == null)
            throw new ArgumentException("method");

        _listener.Prefixes.Add(prefix);

        _responderMethod = method;
        _listener.Start();
    }


    public void Run()
    {
        ThreadPool.QueueUserWorkItem((o) =>
        {
            try
            {
                while (_listener.IsListening)
                {
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        var ctx = c as HttpListenerContext;
                        try
                        {
                            byte[] buf = _responderMethod(ctx.Request);
                            ctx.Response.ContentLength64 = buf.Length;
                            ctx.Response.ContentType = "application/octet-stream";
                            ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                        }
                        catch { }
                        finally
                        {
                            ctx.Response.OutputStream.Close();
                        }
                    }, _listener.GetContext());
                }
            }
            catch { }
        });
    }

    public void Stop()
    {
        _listener.Stop();
        _listener.Close();
    }
}

give it a try, I am successful able to play the video, I hope same for you too

For the MediaServer I have used Simple C# Web Server with some modifications.

above could be made shorter using Reactive Extensions. I'll give a try on the same if this works for you.

Also we can make the media server generic to pass the id of the video in url and in return it will stream back the desired video from the DB

pushpraj
  • 13,458
  • 3
  • 33
  • 50
  • I had high hopes for this. I copy+pasted the code, but my MediaElement shows nothing. No exception gets thrown, so I'm not sure why the video won't load. Did you ever encounter this? – eriyg Nov 07 '22 at 03:05
  • @eriyg, I had tested that code snippet at the time of creating that post. it is almost 8 years old. a lot have changed since then in terms of framework/architecture/security etc. try debugging the code line by line and see if you can spot something. – pushpraj Nov 08 '22 at 01:07