Wednesday, July 7, 2010

Silverlight Video Streaming

Recently I was on as project , that involved playing the media files from the storage server in the browser. Silverlight was chosen to play the media files. Plan was to have a datagrid that shows media files filtered on the basis of date. After the user chooses the file , the file is fetched from the storage and played in the media element . Starting was the creation of the project structure , a silverlight application with asp.net project to host the silverlight application. In the silverlight application, a usercontrol with media element embedded is created.





















<mediaelement name="media" mediafailed="MediaElement_MediaFailed" autoplay="True">

Media Element has the property source and a method SetSource that set's the media file to be played in the media element. Source property takes the Uri of the media file and the SetSource method takes stream to be played in the media element. Setting the Source property was not a choice as the media files resided on the other server . Silverlight media element Source proerty do not support file:// or UNC path to set media files , files have to be on the webserver hosting the web app. So the solution to get the media files from the storage server and stream them to the silverlight client was to use WCF media streaming. At the silverlight client we use SetSource method of media element to provide the media stream.
WCF service will be hosted along side the web project on IIS . WCF service for silverlight application are little bit different from the normal WCF applications. WCF service has to be silverlight enabled. To create the silverlight enabled service goto :- Add New Item --> Silverlight --> Silverlight enabled WCF service , this will create a svc service file with default structure . We will start with creating a service contract interface IVideoService , having a method GetVideoFile that takes a string as parameter and returns the stream object. Method is decorated with the OperationContract and WebGet attribute.
.

[ServiceContract]
public interface IVideoService
{
[OperationContract]
[WebGet(UriTemplate = "media/{name}")]
Stream GetVideo(String name);
}


.
Now we create the implementation of the service contract by creating a class VideoService that implements the service contract . In silverlight enabled WCF service , we have attribute AspNetCompatibilityRequirements
on the service class. Service class implements the GetVideoFile method that takes as parameter the path of video (UNC or File://) and returns the filestream .


[AspNetCompatibilityRequirements
(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class VideoService : IVideoService
{
public Stream GetVideo(String name)
{
if(File.Exists(name))
{
return File.OpenRead(name);
}
return null;
}
}


.
Now our service class is in place, we create the WCF configuration for wcf streaming.We use basicHttpBinding with transferMode set to streamed , we also increase the maxReceivedMessageSize .With the service hosted on web app the endpoint address is always relative to the web address (Example : http://localhost:2310/Default.aspx --> http://localhost:2310/myservice.svc).






















At the silverlight client we add service reference to our WCF service and use proxy to get the media file and play it with media element.

VideoStreaming.VideoServiceClient client = new VideoStreaming.VideoServiceClient();
client.GetVideoCompleted += new EventHandler(client_GetVideoCompleted);
client.GetVideoAsync(@"\\Storage-pc\Files1\Encoded\myvideo.asf");


















We also have to create a clientaccesspolicy file and place it with service (.svc) file for making service available across appdomain boundries.











Now we are all set to stream the media file.

Network Security Access Restrictions in Silverlight
Making a Service Available Across Domain Boundaries
WCF Streaming Message Transfer

2 comments:

  1. How can I assign the e.Result to the media object?

    ReplyDelete
  2. how to use web service for video streaming

    ReplyDelete