1

I am starting to create an application of which large part relies on streaming Video(few video streams) from a PC to a WP8 mobile phone.

  • I have to choose from one of the following video formats: Motion JPEG,MPEG-4, H.264.

  • The stream should be somehow protected so unauthorized person would have hard time to receive or maybe decode it.

  • Cell phone has connection to the internet by a Wi-Fi. Cell phone is in the different wifi network than PC-server.

The question is: (1.)How to stream video of above named formats from a PC to WP8 phone and (2)how to reasonably secure this transmission?

The PC-server part will be written in C#.

Aydin
  • 15,016
  • 4
  • 32
  • 42
Yoda
  • 17,363
  • 67
  • 204
  • 344

1 Answers1

2

Infrastructure

Since it's a small project you can set up your home PC with IIS and stream the content directly from your own home server.


Media Formats

It's important that you use H.264-encoded videos in MP4 files because it's THE format which is supported on almost every device out there.


Content Delivery

Content will be streamed over HTTP and can be viewed in app or in browser.


Edit

Since it's just a small scale system you will be implementing, you can disregard a lot of the security part and concentrate on getting the video streaming first... You will still need a database concerning what videos you have stored and where they are located on your hard drive, my suggestion would be to store all the videos in one location such as C:\MP4\

Next part would be to setup IIS, you can either use your IP Address, or buy a domain and change its A Records to point to your IP.

You can then create a small database with a table named Videos, have columns labeled VideoID and FilePath and fill the database with your videos.

After the database is done, you can proceed to writing a generic handler which will handle the streaming of the video.

Create a new .ashx file called Watch.ashx, now whichever video you wish to watch, you'll soon be able to do so by passing the videoid parameter to Watch.ashx like this...

http://127.0.0.1/Watch.ashx?v=VIDEOID

I've included the entire class below to get you started.

<%@ WebHandler Language="C#" Class="Watch" %>

using System;
using System.Globalization;
using System.IO;
using System.Web;

public class Watch : IHttpHandler {

    public void ProcessRequest(HttpContext context)
    {
        // Get the VideoID from the requests `v` parameters.
        var videoId = context.Request.QueryString["v"];
        
        /* With the videoId you'll need to retrieve the filepath 
        /  from the database. You'll need to replace the method 
        /  below with your own depending on whichever
        /  DBMS you decide to work with.
        *////////////////////////////////////////////////////////
        var videoPath = DataBase.GetVideoPath(videoId);
        
        // This method will stream the video.
        this.RangeDownload(videoPath, context);
    }

    
    private void RangeDownload(string fullpath, HttpContext context)
    {
        long size;
        long start;
        long theend;
        long length;
        long fp = 0;
        using (StreamReader reader = new StreamReader(fullpath))
        {
            size = reader.BaseStream.Length;
            start = 0;
            theend = size - 1;
            length = size;

            context.Response.AddHeader("Accept-Ranges", "0-" + size);

            if (!string.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
            {
                long anotherStart;
                long anotherEnd = theend;
                string[] arrSplit = context.Request.ServerVariables["HTTP_RANGE"].Split('=');
                string range = arrSplit[1];

                if ((range.IndexOf(",", StringComparison.Ordinal) > -1))
                {
                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + theend + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");
                }

                if ((range.StartsWith("-")))
                {
                    anotherStart = size - Convert.ToInt64(range.Substring(1));
                }
                else
                {
                    arrSplit = range.Split('-');
                    anotherStart = Convert.ToInt64(arrSplit[0]);
                    long temp;
                    if ((arrSplit.Length > 1 && Int64.TryParse(arrSplit[1], out temp)))
                    {
                        anotherEnd = Convert.ToInt64(arrSplit[1]);
                    }
                    else
                    {
                        anotherEnd = size;
                    }
                }

                anotherEnd = (anotherEnd > theend) ? theend : anotherEnd;

                if ((anotherStart > anotherEnd | anotherStart > size - 1 | anotherEnd >= size))
                {
                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + theend + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");
                }

                start = anotherStart;
                theend = anotherEnd;

                length = theend - start + 1;

                fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
                context.Response.StatusCode = 206;
            }
        }

        context.Response.ContentType = "video/mp4";
        context.Response.AddHeader("Content-Range", "bytes " + start + "-" + theend + "/" + size);
        context.Response.AddHeader("Content-Length", length.ToString(CultureInfo.InvariantCulture));

        context.Response.TransmitFile(fullpath, fp, length);
        context.Response.End();
    }
    
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

I adapted the class above from cipto0382's work, the original can be found here:

http://blogs.visigo.com/chriscoulson/easy-handling-of-http-range-requests-in-asp-net/

On parting notes, to save on bandwidth, I highly recommend that you download Media Services from the IIS Appplication Gallery, you can throttle the bitrate that videos are transmitted so that it doesn't eat up your entire bandwidth.

Community
  • 1
  • 1
Aydin
  • 15,016
  • 4
  • 32
  • 42