How to stream video in asp.net using WCF rest service

In this post I will show you how to stream video in asp.net using WCF rest service.The techniques used here is as we don't know the exact content lenght of the data so we used Content-Encoding transfer encoding allows a server to maintain an HTTP persistent connection for dynamically generated content. In this case the HTTP Content-Length header cannot be used to delimit the content and the next HTTP request/response, as the content size is as yet unknown. Chunked encoding has the benefit that it is not necessary to generate the full content before writing the header, as it allows streaming of content as chunks and explicitly signaling the end of the content, making the connection available for the next HTTP request/response..
  • Open visual studio and create a simple wcf service.
  • Add a new class and add following code into it
public class ContentTypeMessageFormatter : IDispatchMessageFormatter
{
    private IDispatchMessageFormatter formatter;
    private String contentType;
    public ContentTypeMessageFormatter(IDispatchMessageFormatter formatter, String contentType)
    {
        this.formatter = formatter;
        this.contentType = contentType;
    }

    public void DeserializeRequest(Message message, object[] parameters)
    {
        formatter.DeserializeRequest(message, parameters);
    }

    public Message SerializeReply(MessageVersion messageVersion, Object[] parameters, Object result)
    {
        if (!String.IsNullOrEmpty(contentType))
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
        }
        return formatter.SerializeReply(messageVersion, parameters, result);
    }
}
  • Create another class and add following code
public class ContentTypeAttribute : Attribute, IOperationBehavior
{
    public ContentTypeAttribute(String contentType)
    {
        this.ContentType = contentType;
    }

    public String ContentType
    {
        get;
        set;
    }

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
    {
    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Formatter = new ContentTypeMessageFormatter(dispatchOperation.Formatter, ContentType);
    }

    public void Validate(OperationDescription operationDescription)
    {
    }
}
  • Add a new Interface named IMediaService and add following code into it
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

[ServiceContract]
public interface IMediaService
{
    [OperationContract]
    [ContentType("audio/x-ms-wmv")]
    [WebGet(UriTemplate = "media/{name}")]
    Stream GetMedia(String name);
}
  • Implement the service as below
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using System.Web;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior]
public class MediaService : IMediaService
{
    [OperationBehavior]
    public Stream GetMedia(String name)
    {
        var dir = HttpContext.Current.Server.MapPath("~"); 
        var file = String.Format("{0}.mp4", "x");
        var filePath = Path.Combine(dir, file);
        return File.OpenRead(filePath);
    }
}
  • Configure the service.
<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
      <service behaviorConfiguration="serviceBehav" name="MediaService">
        <endpoint behaviorConfiguration="RestBehaviorConfig" binding="webHttpBinding"
          bindingConfiguration="HttpStreaming" contract="IMediaService" />
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding name="HttpStreaming" maxReceivedMessageSize="67108864" transferMode="Streamed"/>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RestBehaviorConfig">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="serviceBehav">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>
Now our streaming service is ready.Let's test it.Create a html5 web page in visual studio and add following tag in the page.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <video src="http://localhost/MediaWCF/Service.svc/media/x" autoplay="autoplay"></video>
    </div>
    </form>
</body>
</html>

2 comments:

  1. Hi Santosh,

    Can you please send me the code ?
    arnoyoung@gmail.com

    Thanks!

    ReplyDelete
  2. @Arno: Sure give me some time and I will upload the code int github and let you know

    ReplyDelete