Streaming Live or On-Demand Video from IIS7 to iOS Devices (iPhone/iPad) and Silverlight Clients
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.
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.
- IIS7 - If you Windows 7 or Windows Server 2008 you already have this.
- You may need to check a box under Programs and Features. Easiest way is to install all this stuff with the Web Platform Installer and it'll enable IIS for you.
- IIS Media Services 4
- IIS Transform Manager 1.0 Alpha
- Expression Encoder 4 - You can use the Trial version for VC-1 content, but you'll need the Pro version for H.264. I think it's $199.
For 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.
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.
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.
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...
...and one for the Apple format:
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...
...and here it is in Silverlight. Note the chart showing the smooth streaming bandwidth adjusting.
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.
Make sure to select "Enable Output to Apple Mobile Digital Devices" and also Enable iOS 3.0 Compatibility for older phones.
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.
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"
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.
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. ;)
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.
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
- Getting Started with IIS Live Smooth Streaming
- Apple HTTP Live Streaming with IIS Media Services
- Creating and Managing Live Smooth Streaming Publishing Points
- Syndicating Live Smooth Streams between Servers
- Live Smooth Streaming Deployment
- IIS Media Services 4 released
- Microsoft Silverlight Media Framework 2.2
- All about Media Services
- Encode and Deliver On-Demand Smooth Streams with IIS Transform Manager and IIS Media Services 4
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Thanks!!!
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?
Jeff - I'll ask abotu a CDN or hoster that does this.
Asif - Good question. I'll ask the team!
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
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?
http://emea.microsoftstore.com/UK/en-GB/Microsoft/Expression-Encoder-4-Pro gives a nice 404.
:'(
<!-- 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.
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.
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!
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.
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
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
Instead of having 2 separate urls "1 for Iphone/Ipad and other for silverlight" we would like to have a single url.. Recommendations?
Comments are closed.
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?