Monday, August 17, 2009

Confessions of an iPhone HTTP Live Streaming Video Geek

I did it!!!! I finally got HTTP live streaming working on the iPhone version of my company's web site. I hope to pass on a few tips for those who are just starting out and also maybe those of you who've been trying for a while but are still having trouble.

Note: I could not have done any of this without the fabulous instructions posted by Carson on

http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/

I also want to thank Corp186 on the Apple Developer Forums for writing and releasing his open source segmenter, which this script depends on in order to work.


If you'd like to see streaming in action and have an iPhone with OS version 3.0 or later, you can try going to my company's web site at http://www.endlesspools.com/ and you should see an iPhone specific web site that will play streaming video. It works great. The only issues that remain for me is that the videos always appear grainy for the first couple of seconds since it seems to first start at the lowest available bit-rate even on Wifi, and the current ffmpeg version doesn't seem to encode transport streams as cleanly as it could, so there is some skipping during playback which is somewhat distracting.

In my case, the hardest part of this project was dealing with the large number of videos I would have to convert. I had 8 different video files I needed to iphone-enable on our web site. Now, let's think about that process for a minute.

  • 8 video files need to be converted to at least 3 different transport streams (at 3 different bit rates)
  • So our 8 files turns into at least 24
  • Then those 24 files need to be segmented into say, 10 second segments, and since each of my videos are up to 10 minutes long, we are talking about hundreds of segmented transport streams.
  • Then for each group of segmented files at a given bit rate, I have to create an m3u8 playlist to connect them all together.
  • Finally, I need to make a master playlist, which contains a list of all of the bit-rate specific playlists I created above.

Sounds complicated? It might at first, but actually after you work with it for a bit it is actually quite logical and very straightforward, but even so, we are talking about creating a LOT of files

This might be doable if you have one video, but even so, if you make one mistake, you have to start all over.

And I wanted to be able to try different scenarios. Trying different bit rates. Trying different segment lengths. Doing that manually and consistently with that many videos would be mind boggling

So I took some time and cobbled together a php script that will help automate the entire process.

I had big plans. First I was going to write an app in RealBasic and run it as a stand-alone app with a nice professional GUI. Realizing I had already worked 70 hours this week, I came to my senses and thought about making a nice command line php utility. And I did just that, except I skipped the process of adding the ability to add parameters via the command line. To get the script done, and to get back to my real work, I am attaching below a simple php script, and in order to change the arguments, you currently need to edit the script (which is pretty easy). OK, it's not as elegant as it could be, but it's 10 times easier than doing it manually.

So, here is a link to download a zipped copy of the script

http://web.me.com/zacware/file_library/iphone_stream_batch_processor.php.zip

The code is actually well commented, so it's easiest just to download the file and open it in your favorite text editor, but for a quick summary....

You need to indicate the location of your raw, pristine m4v files, and also where you would like the final product to go. You also need to tell the program where your segmenter is (not everyone who reads this will understand how to Set Path, so I'm trying to keep it simple). You then indicate the URL where the streams are going to wind up, the name of the master play list for each video (the master playlist is what you'll put in the source parameter of your HTML video tag). There is an array where you can change the bit rates that will be used, the audio sampling frequency, the width and height of the resulting video (also applies to aspect ratio), and finally the length of each segment in seconds.

$mySourceFilesDirectoryPath="/Users/steve/desktop/source_videos/";
$myWebFilesDirectoryPath="/Library/WebServer/Documents/streams/";

$myFullSegmenterPath="/Users/steve/codefolder/segmenter/segmenter";

$myURLSeed="http://10.0.1.192/streams/";

$myMasterPlayListName="MasterPlayList";

$myVideoBitRateArray=array(96,256,800);

$myAudioSamplingFrequency="44100";

$myCurrentWidth=480;
$myCurrentHeight=320;

$mySegmentLength=10;

For me, this is great. I could try different settings, run the script, and while all 8 videos are encoded and segmented, I could go and do other things (if you have a lot of videos, this takes a lot of time)

For those of you who want to do live streaming but are intimidated by command line stuff, it's really not that hard to do.

Carson's article does a great job explaning what to do, and the hardest part if you are new to this would be the compiling ffmpeg from source code.

Before you try anything, make sure you have the latest version of Apple's Developer Tools installed on your machine. Then it's just a matter of downloading the ffmpeg source and compiling it.

Compiling apps from source is beyond the scope of this post, but basically, you download the source code to a folder. Make VERY VERY sure your current directory location is the one where the actual code files you just downloaded are contained in and then enter "./configure", then "make", and finally "sudo make install".

In the case of ffmpeg, Carson points out a bunch of parameters you will have to add to the config command in order to set it up properly. And if you are starting from scratch, ffmpeg will give you compile errors unless you download some stuff first. In my case, on a standard Leopard install, I first had to download and compile "faac", "faad2", "lame", "x264", and "yasm" (and after that, you'll also need to download and compile Corp186's segmenter). In Carson's tutorial, he points out that you need to modify the make file in order to get the segmenter to compile, so don't forget that little step.

Also, for anyone new to working from the command prompt, be careful when you just copy and paste stuff out of a browser window, as you may actually be pasting special characters into the command line that will look like spaces to you but in reality are something else entirely. You'll go crazy trying to figure out why things aren't working. In going through Carson's tutorial, I had to find/replace on something that looked like an "x" but actually wasn't and replace it with a normal x. The same thing can happen with spaces. When doing stuff like this, BBEdit (which is the best editor in the world), or it's little brother Text-Wrangler, both have a wonderful Zap Gremlins feature to find and fix these special characters.

OK, that it for now. I have to get back to doing my real work to pay the mortgage. I hope the script is of use to you

Once again, if you have an iPhone with OS 3.0 or later on it, you can check the videos out on the iPhone enabled version of my company's web site...... http://www.endlesspools.com/

Remember, the above link will only work correctly for iPhone users running 3.0 or greater.


Saturday, August 15, 2009

I'm now a Multi-Hundredaire!!!

My 4th iPhone app, 3D Photo Toy, which was easily the most complicated app I've done for the iPhone, has fizzled before it could ever sizzle. Last year, my first few apps earned me at least a few hundred dollars for my efforts (hence, my status as a multi-hundredaire), but sadly, 3D Photo Toy, which was my first attempt at working with 3D graphics, something I've been wanting to do for years, hasn't even covered the cost of my annual developer renewal. I never expected to get rich off of apps like this, but with the millions of iphone users out there, I was expecting at least a few hundred dollars. Amazingly, I think I made more money back when I wrote software for the Newton!