A lot of people think that ASP.NET Web API is basically a fancy framework for building APIs – which couldn’t be further from the truth. Web API is mainly about the new .NET HTTP programming model it brings to the table – embracing HTTP to perform a whole magnitude of web related tasks; and APIs are just a small portion of that. Hopefully if you follow this blog, you have seen examples of that already, as we often wander in the unkown areas of ASP.NET Web API, beyond building “traditional” APIs.

Today, let’s go back to the HTTP programming model and use Web API to asynchronously stream videos.

More after the jump.

The concept of asynchronous streaming

To perform the async streaming task, we will revert to the class we already previously used on this blog – and that is PushStreamContent. It allows the developer to progressively push packets of data down to the receiving client. Previously, we used PushStreamContent and JavaScript’s Server Sent Events to create an HTML5 chat.

In our new scenario, we will read the video stream from the file on the server’s hard drive, and flush it down to the client (using PushStreamContent) in the packets of 65 536 bytes. The streaming video playback could then start immediately (client doesn’t have to wait for the entire video to be flushed down), without causing unnecessary load on our server, especially as the process of writing to the client happens asynchronously. Once the client disconnects, the writing stops.

This class is obviously little simplified, for the sake of demo purposes, but hopefully you get the idea. We allow the consumer of the class to give as information about the file (for which we arbitrarily look in a specific location, the Downloads folder in this case). In the WriteToStream method, we proceed to read the file progressively and flush these bits to the output stream.

Notice that the signature of this method matches the Action expected by PushStreamContent and as a result can be used by it.

Now let’s move to the controller action, which, by now, will be very simple (all the heavy lifting happens in the above VideoStream class).

In this case, I will be requesting this video: C:UsersFilipDownloadsCkY96QuiteBitterBeings.webm.

If we run this in the browser that supports WebM, we could see that the video (especially if you open the network inspection console) is streamed rather than loaded at once. To better illustrate this, I have recorded a short video which shows the application in action. I’ve put a breakpoint inside WriteToStream method, to show that subsequent packets of video get sent down *after* the playback has already started; the client can commence the playback already after the first 64kB packet. Also, as soon as the breakpoint hits, nothing more gets sent to the client, yet the browser still continues the playback of what it has already received.

Video below (choose 480p when playing for better quality):

Summary

While there are arguably many better solution for video streaming (media protocols, media servers and so on), in my opinion, this type of functionality is a pretty nifty example of how flexible Web API can be in terms of working with HTTP programming – and how many different things it can do.

On a side, PushStreamContent itself is a very interesting class, and if used correctly, can be a very powerful weapon in the arsenal of Web API developer. A very interesting article about a similar topic (async with PushStreamContent) can be found here, by Andrés Vettor. Really worth a read!

Filip, this is a very awesome post. I’d be interested to see usage scenarios other than video streaming where we could take advantage of streaming content. Would you say it would be wise to use it for streaming stock tickers and other realtime-data or should we then use SignalR instead?

http://www.timacheson.com/ Tim Acheson

Cool! Would it be more accurate to describe this as progressive download, rather than streaming?

http://www.strathweb.com/ Filip W

yes you are right, in the strict technical terms, since we deal with HTTP and no streaming server is involved, that would be progressive download. With that said, that wouldn’t make such catchy post title

Suppose I have a video that is 2 hours long. I use this method on it, and a user drags the video tag control slider all the way to 1 hour and 59 minutes. Can this method cope with that? Can the video-tag api also cope with it?

Rahul Behal

Hi Fillip

Thanks for the post!

However, I am facing one issue – Video stops playing after some time – let us say plays for 9 sec out of 4 minutes 20 sec.

I used the same code above, debugged it and found that stream reading/writing has

finished after 9 sec.

Can you please suggest the way ahead. I am using chrome 24.0.1312.57 m

Thanks a lot,
Rahul

Nahaz Nizam

pls send me a sample project for this .or how to achieve this synchronous video streaming in normal asp.net web application

‘System.IO.Stream’ does not contain a definition for ‘WriteAsync’ and no extension method ‘WriteAsync’ accepting a first argument of type ‘System.IO.Stream’ could be found (are you missing a using directive or an assembly reference?)

The error occurs right at:
await outputStream.WriteAsync(buffer, 0, bytesRead);
which is in the VideoStream class.

Here are my using statements above the class.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;

Am I missing something?

http://www.strathweb.com/ Filip W

is it .net 45?

Jeremy

You can achieve this by targeting .NET 4 also. In NuGet search for Microsoft.Bcl.Async. Install it. It installs the async extensions for .NET 4/Silverlight 4 and 5.

Goshen Monzon Jimenez

Hi, im getting an error which reads :

‘System.IO.Stream’ does not contain a definition for ‘WriteAsync’ and no extension method ‘WriteAsync’ accepting a first argument of type ‘System.IO.Stream’ could be found (are you missing a using directive or an assembly reference?)

The error occurs right at:
await outputStream.WriteAsync(buffer, 0, bytesRead);
which is in the VideoStream class.

Here are my using statements above the class.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;

Am I missing something?

dekic

Has someone gotten this project to work, it’s explained really well, but for me it only loads for 3 seconds and then stops. Any help would be rather helpful

Love the post, great ideas for handling it with WebAPI for streaming. BUt I’m running into a slight problem, hoping you can help with. Using .net 4.5 I am getting an error reading (call is ambiguoius between system.func and system.action). I did some more research and when I try to cast it to an Action, as you mentioned above, I get the error “No Overload of WriteToStream matches delegate System.Action”. Any thoughts?

Scratch my previous question. I got that working by moving the code from the Video stream class into the VideosController. My bigger question is that I verified my mp4 file works but wwhen run through the web API it says unsupported file type? thoughts?

Hi, It’s working fine as expected but if stream small size of file working properly. For large file asynchronous streaming not happening… Player loading videos after while loop complete.(WriteToStream Method). Is anything needs to be configured for that?

David Levy

having same issue, not streaming,

David

I’m trying to create this exact project to see for myself, but I keep getting errors. Instead of listing all of my errors could you send me a sample project of this? It would be much appreciated.
thank you

Neha Tekchandani

Will this code work for .net 3.5 if yes can i get a Sample code

vijay sundrapandiyan

Filip W Pls Post Sample Project……in mVC 4..

Ron Killaars

Dear Andrés Vettor, Thanks for the great article!. Would it be possible to send me the sample project? I am trying to get it done but is seems I missing something. Could you send it to rkillaars@hotmail.com Thanks.

Great post.
Only one question ?
Is there any way to set the duration of the video in order to make the video progressbar shows the user the duration of the video ?

ArunJayapal

Can someone share the fundamentals of video streaming. I am just completely in the blank about that…

Park-ChangSung

it is not mp4 video play on ipad and iphone…

Nihad Ahmetovic

Has anyone idea how to play video streamed on this way in android aplication. I was try to access with api url and videoView….

Lucas Kolb

Hey Filip!
This sounds great and seems to be exactly what I need!
But I’m not getting through with it :-/
Could you provide me the code? That would be great!
Thank you so much!

Chris Luposli

Hi Filip,
Could you please send me the code as well as I am not getting thru it.
my email is assumea@gmail.com
Thanks,
Chris Luposli.

captain

i am getting error at 1st line of this tutorial: public PushStreamContent(Action onStreamAvailable);
error is method must have return type.
please give me solution.

captain

i am getting error at first line of tutorial :public PushStreamContent(Action onStreamAvailable);
error is Method must have return type.
i have tried in both framework 4.0 and 4.5
please give me solution.

Ajit

Will you please send the project with code. Thanks alot for writing such a nice article.

Avinash

Great post,
can you create a sample project on how to use twitter streaming API in webpage such as this -> http://tweetmapr2.azurewebsites.net/
It will be of great help for many of us.
looking forward for your new post.

Guys, can you give me some ideas how can I stream one video to multiple clients simultaniosly?

Adam

Hi, thank you for the awesome code. It works perfect. But how can i send a string value along with this video stream to the client website?
So i can set the src of the tag in code behind(c#) and set the string value to string variable for other filteration purpose. Please advice….. thanks in advance

Naresh

Hi I am new to Web API and .net MVC. Con you please share the code to read video file asynchronously from Web API using MVC.
Thanks.

Simplevolk lightvolk

Hm..Is it possible to stream to Unity with this code?

thiago adriano

hi, How can I change quality ?

CradleToGraveLazy

I wonder if you had updated this for VS2013. Apparently the signature for PushStreamContent has changed and this implementation throws an error. I appreciate the blog.

Vijendra Patil

Love the post, very great article!!! Any alternate solution if I have to read very large video file through External URL such as “http://somesite/videos/video1.mp4″ through HttpWebRequest.Create()? Just wondering how would the method “public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) ” will look like. At present the file path is a physical file path and not a web path in above example.

Pavithra Krishnakumar

hey this solution worked well … Good Post for video streaming… But I am facing a problem when executed with the chrome. Its working fine with the IE and in chrome its not working… Could you please help with this issue..

Stress

In VideoStream.WriteToStream, why do you eat any HttpExceptions? Also, why do you close the output stream? Shouldn’t the caller do that?

Sean S

This post was excellent, thank you! I used it to pipe a live video stream through an Action (read one infinite stream and write to another). One issue I can’t figure out, while one stream is being written to, all other requests to the controller are blocked. Should the Controller’s Action be “async”? Should I be using AsyncController instead of ApiController?

LALIT BHANGALE

It is really very good for streaming video. Is it Possible with asp.net 2.0? How?
Please can you send me the sample code. Thanking You