Scott Hanselman

Streaming Live or On-Demand Video from IIS7 to iOS Devices (iPhone/iPad) and Silverlight Clients

November 9, '10 Comments [20] Posted in IIS | Silverlight
Sponsored By

DSC_0001 Earlier this year I posted on Installing and Setting Up and Encoding for IIS 7 Smooth Streaming and Silverlight. The general idea was to show folks that it's actually pretty easy to setup Smooth Streaming for Silverlight. Of course, not everyone uses Silverlight, and lots of folks (myself included) have iPhones and iPads.

I've long been singing the praises of IIS7. If you're on IIS6, get off it. IIS7 is the #1 reason to get on Windows Server 2008R2, IMHO. Mostly because of the crapload of awesome (CoA) that keeps coming out of the IIS team. Many of these modules aren't on the radar of the average developer. I think that Web Platform Installer helps some, but still, I'd like to get the word about some of this free stuff like the Web Farm Framework, the all new FTP 7.5, Bit Rate Throttling, and my favorite, Application Request Routing (which I use in my robot).

Anyway, last week IIS released IIS Media Services 4.0 that you can download now. It's free if you have IIS on your machine. They also released a number of things this summer like the Transform Manager 1.0 Alpha.

Getting existing Video from IIS7 to iOS devices elegantly

Why do I care? Well, I'm sitting here looking at an IPhone 3G, an iPhone 4 and an iPad on my desk. Many of your customers have these devices. How do you get video to them, cleanly, quickly, easily and from a single source file?

Turns out there's features in IIS7 and Media Services that target iOS directly. Yes, it's true. Cats and dogs, living together, mass hysteria. Get your snowballs out, hell has frozen over and the slopes look sweet.

On-Demand Encoded Video for iOS and Silverlight

First, I've got this file on my hard drive called ScottGuHDTest1. It's a picture in picture (PIP) test that ScottGu and I did a while ago while looking into new ways to deliver educational video content. Consider this my stock video for this example.

Windows Media Player - ScottGuTest Video Frame

If I want to deliver this content to the web over Silverlight Adaptive Smooth Streaming PLUS I want it to look great on an iPhone or iPad regardless of bandwidth, and I want it all done automatically, I'll need these things.

imageFor existing videos or videos you're making on a regular basis, the idea is that you'll just drop them in a folder and a task will automatically kick off. You have total control over everything, to be clear, but for the out of the box example, I'm going to drop my ScottGu WMV into a folder and two things will pop out:

  • A folder with HTML page with a Silverlight media player that supports Smooth Streaming. The ScottGu video will be encoded in various bit rates and be all set for adaptive Smooth Streaming
  • A folder with MPEG-2 TS format files with .m3u8 manifests that conform to the Apple Live Streaming Protocol.

Here's what you do. Once you've installed the Transform Manager, it'll show up in your IIS Manager as a node. You'll setup account credentials (an account with some power, as it'll need to run stuff and copy files into IIS folders. I used my own. Naughty.)

Now, go to Job Templates and notice there are a bunch of built-in templates. You can create whatever you want to encode video in whatever way makes you happy.

I double-clicked on them and checked all the paths and stuff. You'll need to change the templatePath property to decide on your input and output directories.

 Edit Job Template

I have my input folder here, in c:\inetpub\media\Transform Manager, and there's sub-folders beneath that as seen in this screenshot. Notice that tasks can do multiple things, so mine takes an input file and "fans out" into multiple tasks.

 Transform Manager

If I drop my ScottGu file in, a task immediately starts up (it's watching the folder) and I can see the progress from the IIS manager. Here it is in the middle of encoding.

Internet Information Services (IIS) Manager

The Transforms Manager has lots of interesting parameters that you can set, basically using simple template expansion. It'll make a folder with the Date and Time and a Unique Number, but again, you control all this.

Now I have two folders, one for the Silverlight format...

20101108231223_22BCFBBAA9864545A8864DEDC41E6A87

...and one for the Apple format:

 TS

I'll add a HTML page for an iOS device to hit. NOTE: You'll be pointing the iPhone/iPad to this m3u8.ism file and it'll decide what streams to watch:

<html>
<head>
<title>iPhone page</title>
</head>
<body>
<h1>Encoded stream</h1>
<video width="640"
height="480"
src="ScottGu720pTest1-m3u8-aapl.ism/manifest(format=m3u8-aapl).m3u8"
poster="ScottGuSplashPage.png"
autoplay="true"
controls="true" >Live</video>
</body>
</html>

I've also added splashscreen "poster" that's just a PNG frame from the video. Here's a photograph of my iPhone 3G, iPad and iPhone 4 with the video...

DSC_0001

...and here it is in Silverlight. Note the chart showing the smooth streaming bandwidth adjusting.

ScottGu720pTest1 - Windows Internet Explorer

Cool, that was easy. How about LIVE video streaming to both iPhone/iPad clients and Web Browsers?

Live Streaming Video from IIS7 to iOS devices and Silverlight

Doing LIVE Streaming video is pretty easy also. You start with IIS Media Services 4 and Expression Encoder 4 Pro. The encoder will dynamically transcode the incoming video into the right format for outputting to Apple Devices as well as Silverlight clients. It'll also archive the video for later.

Start by selecting Live Smooth Streaming, and create a Publishing Point.

image

Make sure to select "Enable Output to Apple Mobile Digital Devices" and also Enable iOS 3.0 Compatibility for older phones.

 Add Publishing Point

In the Encoder I can also add multiple live sources (multiple cameras, USB, Firewire, whatever) as well as recorded sources (we'll be right back, advertisements, whatever) and then cue them up appropriately.

Fire up Encoder 4 and select Live Broadcasting Project.

Load a new project

Add a Live Source (I used my Webcam, although Firewire and other video sources work great), then select the H.264 Encoding you want. I chose "H.264 IIS Smooth Streaming iPad Wifi"

image

Under Output, enter in your Publishing Point. This is a file on your IIS server. Mine was http://hexpower7/livestreaming/magicalgoodness.isml because that's the folder I started the Publishing Point in.

Click Cue and cue your live source, then Start the broadcasting.

Create an HTML page like before, this time using the ISML file.

<html>
<head>
<title>iPhone Live Baby!</title>
</head>
<body>
<h1>Live Stream</h1>

<video width="640"
height="360"
src="magicalGoodness.isml/manifest(format=m3u8-aapl).m3u8"
autoplay="true"
controls="true" >Live</video>
</body>
</html>

That's it! Here's a shot of me Encoding while streaming to an iPhone 4.

Me streaming LIVE locally to myself on my iPhone

Plus, just for fun (and to make a point) I can take the Silverlight Player from the first step at the beginning of the blog post (or make my own with the Silverlight Media Framework 2.2) and just point its source to my live streaming endpoint: "<MediaSource>MagicalGoodness.isml%5CManifest</MediaSource>" and I'm using the same live video feed to serve video to my Silverlight client, my iPhone and iPad. Also, the new Silverlight Media Framework 2.2 supports Windows Phone 7 as well. ;)

 ScottGu720pTest1 - Windows Internet Explorer (2)

And, it's not just a LIVE stream, but it's a live stream with DVR support, so folks can pause, back up, etc and it's all being archived to my server.

image

All this about a half an hour of setup. I was pretty impressed at how easy it was and with a little planning, I think I could this up for a local User Group with multiple lives streams and broad client support with some hardware a few hours. You might think about trying it for your local event as a practice, Dear Reader.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Tuesday, November 09, 2010 2:50:22 AM UTC
Aargh! Stop! I can't keep up! I literally just finished building my blog from your "Unnamed Package of Web Love" PDC presentation!

Seriously though, you guys are really churning out the awesome right now. I saw a very similar presentation to yours at DevConnections last week (I wonder who stole from who?) and I can't wait to get going with NuGet, MVC3, Razor, and all the other goodness. When do we get syntax highlighting for Razor?
Tuesday, November 09, 2010 7:30:44 AM UTC
Wow, I recall this stuff (the smooth streaming to a browser, let alone a mobile device) being realy, realy, realy complicated only a few years ago. Great work by the IIS team here.
Tuesday, November 09, 2010 8:57:30 AM UTC
Wow, this is so cool! Your explanation is very easy. Im going to try it right now!
Thanks!!!
Alfredo Temprano
Tuesday, November 09, 2010 12:50:46 PM UTC
Scott, can you point us to a CDN that uses this technology for those of us who don't want to own the servers?
Tuesday, November 09, 2010 1:31:42 PM UTC
What about Windows Phone 7? Where's the love?

dm3281
Tuesday, November 09, 2010 4:18:50 PM UTC
Great post Scott.
We wanted to use this solution but having trouble as this wont work for flash players which needs the rtmp protocol.

Any work around for that?
Tuesday, November 09, 2010 5:35:04 PM UTC
dm3281 - I'll do Windows Phone soon, but I just wanted to do iOS for now so it could sit as its own post.

Jeff - I'll ask abotu a CDN or hoster that does this.

Asif - Good question. I'll ask the team!
Wednesday, November 10, 2010 2:04:45 PM UTC
Hi Scott,

Any idea if or when we can expect Silverlight support on iOS for iPhone / iPad? Is it realistic to wait for Silverlight support on iOS, or is it just wishful thinking?

Thanks in advance for answering, keep up the great work!

Arne
Thursday, November 11, 2010 11:47:44 AM UTC
Nice article
Thursday, November 11, 2010 1:32:39 PM UTC
Useful article, thank you very much!
Thursday, November 11, 2010 8:02:32 PM UTC
Fantastic article!

The company that I work for has an extensive list of video presentations that we want to make available on the iPhone and this has really helped a lot. However I can't seem to get it to work from within a video player embedded in an iPhone application. Is there something special that IIS is doing with because this is coming through a web page? It is just an HTML file so I don't see how that could make any difference at all.

Using the web page just like you have it things are working great but trying to send the same "xxx.ism/manifest(format=m3u8-aapl).m3u8" url to a video player inside the application doesn't work at all. Any suggestions?
Wednesday, December 01, 2010 11:34:47 AM UTC
So frustrating - it doesn't appear to be possible to purchase the "with codecs" version of Expression Encoder 4 Pro from within the UK. Grr.

http://emea.microsoftstore.com/UK/en-GB/Microsoft/Expression-Encoder-4-Pro gives a nice 404.

:'(
Wednesday, December 08, 2010 3:10:00 PM UTC
I took the bunny smooth stream movie and used the transform stuff to convert to apple format. The conversion works. But, I can't get the movie to load. If I hit the url that I placed in the video tag directly I get a bad request error. Here are some details from my trace log...

<!-- saved from url=(0014)about:internet -->
<failedRequest url="http://is13:81/appleoutput/bigbuckbunny-m3u8-aapl.ism?manifest(format=m3u8-aapl).m3u8"
siteId="2"
appPoolId="DefaultAppPool"
processId="8912"
verb="GET"
remoteUserName=""
userName=""
tokenUserName="NT AUTHORITY\IUSR"
authenticationType="anonymous"
activityId="{00000000-0000-0000-2001-0080000000FF}"
failureReason="STATUS_CODE"
statusCode="400"
triggerStatusCode="400"
timeTaken="0"
xmlns:freb="http://schemas.microsoft.com/win/2006/06/iis/freb"
>


<EventData>
<Data Name="ContextId">{00000000-0000-0000-2001-0080000000FF}</Data>
<Data Name="ModuleName">SmoothHandler</Data>
<Data Name="Notification">128</Data>
<Data Name="HttpStatus">400</Data>
<Data Name="HttpReason">Bad Request</Data>
<Data Name="HttpSubStatus">0</Data>
<Data Name="ErrorCode">2156396546</Data>
<Data Name="ConfigExceptionInfo"></Data>
</EventData>

Any Ideas? When I use the video tag all I see is the video poster. It will not play.
Wednesday, December 08, 2010 9:25:57 PM UTC
For ppl that are trying to use this in their iOS app there are couple problems:

1. Audio bitrate is incorrectly reported - look at the last picture in Scott's post - it says 1.4 Mbps (which is obviously not true as audio encoder is required to be set to 64Kbsp in order for all this to work). Because this incorrect value is further forwarded, sometimes your Apple device will suddenly switch to audio-only stream without any apparent reason (it detects that it can stream "better quality" and then switches to "1.4Mbps stream" which is in fact 64Kbps audio stream).

I would love if anyone from MS team could give answer to this as it effectively makes IIS Media Services unusable for any real-world project. Concrete question: can we influence *.isml/manifest(format=m3u8-aapl).m3u8 format so that 64Kbsp audio stream comes first (and remove that incorrect value)? This is actually requirement in order to get your app approved in AppStore! http://www.wowzamedia.com/forums/showthread.php?8971-We-have-be-Rejected-again-because-quot-64-kbps-is-not-set-as-the-baseline-feed-quot

2. Apple's official primer on how to stream videos is broken - it'll work if you build using older SDK but for > iOS 3.2 it won't work as they changed MPMoviePlayerController in iOS 3.2 to support non-fullscreen video playback. Obviously I can't paste all needed code changes here, but the main thing is changing initAndPlayMovie function from their primer in order to make things work:

-(void)initAndPlayMovie:(NSURL *)movieURL
{
if ([MPMoviePlayerController instancesRespondToSelector:@selector(view)]) {
// Running on 3.2+
MPMoviePlayerViewController *mp2 = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
if (mp2) {
self.moviePlayer2 = mp2;
[mp2 release];
// Assuming self is a UIViewController
[self.tabBarController presentMoviePlayerViewControllerAnimated:self.moviePlayer2];

self.moviePlayer = self.moviePlayer2.moviePlayer;
}
} else {
// Initialize a movie player object with the specified URL
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if (mp)
{
// save the movie player object
self.moviePlayer = mp;
[mp release];

// Removed user specified settings to the movie player object
}
}

// Play the movie!
[self.moviePlayer play];
}

To start streaming all you need to do is forward that manifest URL (the same one you are using in HTML 5)

3. Publishing points on IIS 7 need to be Shutdown and then Started whenever you start new encoding session from Expression Encoder. You'll see how obnoxious this is when you try to setup your streaming... for production you'll probably want to do this programatically - http://blogs.southworks.net/ejadib/2009/04/16/live-smooth-streaming-how-to-start-stop-shutdown-a-publishing-point-programmatically/

I tried posting whole class that implements this functionality as a comment like 5 times there... but never succeeded; if somebody needs it, let me know and I'll try to post it here or somewhere else.
Friday, December 10, 2010 7:11:16 AM UTC
Robin - I'll ask the Microsoft Store Guys now!

OpenID guy - For the first one – that is a known bug in Expression Encoder 4 that was fixed in SP1. The workaround is to create an HTTP module or an .aspx page that would request our manifest first and then “fix-up” the bad audio bitrate that is coming in from EE4. This is resolved when EE4 SP1 ships in January. Soon, sorry.

For the second issue – that is also a known workflow issue that we hope to fix in a future release of Expression Encoder. Right now the only way to do this is to use the RSCA API that Southworks discusses on their blog post.

The streaming guys are aware of both and working on them!
Thursday, December 16, 2010 11:23:08 PM UTC
@Asif

I know this reply is coming late (it's hard to fully keep up to date when you get more than 80 new feeds per day heh), and the original poster may not even see this, but just in case...

I haven't tested the method shown in this blog post, but you don't need RMTP or RTMFP support in order to play internet videos, it's been some time since Flash has supported HTTP streaming, take a look at the OSMF project as it will surely be of your interest.
Friday, February 25, 2011 2:01:50 AM UTC
Hi Scott!

Thanks fot this awesome article.

I have one question...

Is there any way to use this same smooth stream technology on latest release of Windows Azure getting the video/media from a Blob Storage account???

Thanks!!!

Best regards...

Gutemberg
Tuesday, July 19, 2011 10:29:19 AM UTC
Hi

Any way to get streaming of other formats, compatible with other platforms, not only with Silverlight and Apple? (e. g. Is it possible to get stream from http://<address>/LiveSmoothStream.isml/manifest(format=XXX).XXX?

With best regards, Boris
Thursday, July 28, 2011 9:49:15 PM UTC
This is slick. We were able to get this up and running within a day.
Instead of having 2 separate urls "1 for Iphone/Ipad and other for silverlight" we would like to have a single url.. Recommendations?
3c
Tuesday, August 02, 2011 10:44:40 PM UTC
I would do some server-side user agent detection and write out the correct markup based on the client.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.