<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IONCANNON &#187; ffmpeg</title>
	<atom:link href="http://www.ioncannon.net/tag/ffmpeg/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ioncannon.net</link>
	<description>Thoughts on Software Development and Engineering</description>
	<lastBuildDate>Tue, 03 Jan 2012 13:59:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<atom:link rel='hub' href='http://www.ioncannon.net/?pushpress=hub'/>
		<item>
		<title>Compiling WebM into FFMpeg for Windows</title>
		<link>http://www.ioncannon.net/meta/1128/compiling-webm-ffmpeg-windows/</link>
		<comments>http://www.ioncannon.net/meta/1128/compiling-webm-ffmpeg-windows/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 10:30:55 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[vp8]]></category>
		<category><![CDATA[webm]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/?p=1128</guid>
		<description><![CDATA[I have updated this post with a newer version of the VP8 patches to FFMpeg and support for libvorbis instead of the built in vorbis support. Google has released source for the VP8 codec as the WebM project. The WebM project will be an open alternative in the HTML5 video tag codec space and being [...]]]></description>
			<content:encoded><![CDATA[<p>I have updated this post with a newer version of the VP8 patches to FFMpeg and support for libvorbis instead of the built in vorbis support.</p>
<p>Google has released source for the VP8 codec as the <a href="http://www.webmproject.org/">WebM project</a>. The WebM project will be an open alternative in the HTML5 video tag codec space and being backed by Google, who will use it for YouTube, will give it a fighting chance. WebM is starting to be integrated into FFMpeg but there are still some patches that need to be applied. While there are some guides to how to <a href="http://lardbucket.org/blog/archives/2010/05/19/vp8-webm-and-ffmpeg/">build FFMpeg for Linux with VP8 WebM support</a> I wanted to get it compiled for Windows.</p>
<p>First off this won&#039;t be done using a Windows install but instead using <a href="http://www.virtualbox.org/">Virtual Box</a> with a fresh install of <a href="http://releases.ubuntu.com/lucid/">Ubuntu 10.04</a> desktop. It is just faster and easier that way. So go ahead and grab Virtual Box and get Ubuntu installed on it before you continue.</p>
<p><span id="more-1128"></span></p>
<p>I used this <a href="http://www.bluebottle.net.au/blog/2010/cross-compiling-x264-for-win32-on-ubuntu-linux/">cross compiling X264 using Ubuntu</a> as a base for part of my script. The entire script follows but if you want to make sure you get a good copy you can <a href="http://www.ioncannon.net/examples/vp8-webm/vp8webmffmpeg.sh">download it</a>:</p>
<pre class="brush: plain; title: ; notranslate">
mkdir ffmpeg
cd ffmpeg

BASEDIR=`pwd`
MINGBASE=$BASEDIR/win32-webm

sudo apt-get install pkg-config yasm subversion cvs git-core gcc-mingw32

cat &gt; mingw32-setup.sh &lt;&lt; EOF
#!/bin/sh
export CC=i586-mingw32msvc-gcc
export CXX=i586-mingw32msvc-g++
export CPP=i586-mingw32msvc-cpp
export AR=i586-mingw32msvc-ar
export RANLIB=i586-mingw32msvc-ranlib
export ADD2LINE=i586-mingw32msvc-addr2line
export AS=i586-mingw32msvc-as
export LD=i586-mingw32msvc-ld
export NM=i586-mingw32msvc-nm
export STRIP=i586-mingw32msvc-strip

export PATH=&quot;/usr/i586-mingw32msvc/bin:$PATH&quot;
export PKG_CONFIG_PATH=&quot;$MINGBASE/lib/pkgconfig/&quot;
exec &quot;\$@&quot;
EOF
chmod +x mingw32-setup.sh

mkdir $MINGBASE $MINGBASE/src $MINGBASE/lib $MINGBASE/include $MINGBASE/share $MINGBASE/bin

cd $MINGBASE/src

wget -qO - http://downloads.xiph.org/releases/ogg/libogg-1.2.0.tar.gz | tar xzf -
cd libogg-1.2.0
$BASEDIR/mingw32-setup.sh ./configure --enable-static --disable-shared --host=mingw32
make
DESTDIR=$MINGBASE make install prefix=
cd ..

wget -qO - http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.1.tar.gz | tar xzf -
cd libvorbis-1.3.1
LDFLAGS=&quot;-L$MINGBASE/lib&quot; CFLAGS=&quot;-I$MINGBASE/include&quot; $BASEDIR/mingw32-setup.sh ./configure --enable-static --disable-shared --host=mingw32
make
DESTDIR=$MINGBASE make install prefix=
cd ..

wget -qO - ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-8-0-release.tar.gz | tar xzf -
cd pthreads-w32-2-8-0-release
make GC-static CROSS=i586-mingw32msvc-
cp libpthreadGC2.a $MINGBASE/lib
cp *.h $MINGBASE/include
cd ..

wget -qO - http://zlib.net/zlib-1.2.5.tar.gz | tar xzf -
cd zlib-1.2.5/
$BASEDIR/mingw32-setup.sh ./configure
sed -i&quot;&quot; -e 's/-lc//' Makefile
make
DESTDIR=$MINGBASE make install prefix=
cd ..

git clone git://review.webmproject.org/libvpx.git
cd libvpx/
git checkout fd0d7ff4c155b94d3f322addc7b66234b6908cc6
cat &gt; /tmp/libvpx.x.patch &lt;&lt; EOP
diff -rupN libvpx.orig/configure libvpx/configure
--- libvpx.orig/configure	2010-07-11 14:49:18.703230816 -0400
+++ libvpx/configure	2010-07-11 14:50:33.747300030 -0400
@@ -436,9 +436,9 @@ process_detect() {
         }
     fi
     check_header stdio.h || die &quot;Unable to invoke compiler: \${CC} \${CFLAGS}&quot;
-    check_ld &lt;&lt;EOF || die &quot;Toolchain is unable to link executables&quot;
-int main(void) {return 0;}
-EOF
+#    check_ld &lt;&lt;EOF || die &quot;Toolchain is unable to link executables&quot;
+#int main(void) {return 0;}
+#EOF
     # check system headers
     check_header stdint.h
     check_header pthread.h
diff -rupN libvpx.orig/vp8/common/postproc.c libvpx/vp8/common/postproc.c
--- libvpx.orig/vp8/common/postproc.c	2010-07-11 14:49:18.939266476 -0400
+++ libvpx/vp8/common/postproc.c	2010-07-11 14:51:03.855300662 -0400
@@ -481,7 +481,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci,
     }

 #if ARCH_X86||ARCH_X86_64
-    vpx_reset_mmx_state();
+//    vpx_reset_mmx_state();
 #endif

     if (flags &amp; VP8D_DEMACROBLOCK)
diff -rupN libvpx.orig/vp8/common/systemdependent.h libvpx/vp8/common/systemdependent.h
--- libvpx.orig/vp8/common/systemdependent.h	2010-07-11 14:49:18.947263304 -0400
+++ libvpx/vp8/common/systemdependent.h	2010-07-11 14:51:25.019253115 -0400
@@ -10,12 +10,12 @@

 #include &quot;vpx_ports/config.h&quot;
-#if ARCH_X86 || ARCH_X86_64
-void vpx_reset_mmx_state(void);
-#define vp8_clear_system_state() vpx_reset_mmx_state()
-#else
+//#if ARCH_X86 || ARCH_X86_64
+//void vpx_reset_mmx_state(void);
+//#define vp8_clear_system_state() vpx_reset_mmx_state()
+//#else
 #define vp8_clear_system_state()
-#endif
+//#endif

 struct VP8Common;
 void vp8_machine_specific_config(struct VP8Common *);
EOP
patch -p1 &lt; /tmp/libvpx.x.patch
$BASEDIR/mingw32-setup.sh ./configure --disable-examples --disable-mmx --disable-sse --disable-sse2 --disable-sse3 --disable-ssse3
$BASEDIR/mingw32-setup.sh make
DESTDIR=$MINGBASE make install prefix=/
cd ../..
mv usr/local/lib/* lib
mv usr/local/include/vpx/ include/
cd src

wget -qO - http://webm.googlecode.com/files/ffmpeg-0.6_libvpx-0.9.1.diff.gz | zcat - &gt; /tmp/ffmpeg-0.6_libvpx-0.9.1.diff
wget -qO - http://www.ffmpeg.org/releases/ffmpeg-0.6.tar.gz | tar xzf -
cd ffmpeg-0.6
patch -p0 &lt; /tmp/ffmpeg-0.6_libvpx-0.9.1.diff

LDFLAGS=&quot;-L$MINGBASE/lib&quot; CFLAGS=&quot;-I$MINGBASE/include&quot; ./configure --target-os=mingw32 --cross-prefix=i586-mingw32msvc- --arch=x86 --prefix=$MINGBASE --enable-memalign-hack --enable-gpl --enable-avisynth --enable-version3 --enable-postproc --enable-libvpx --enable-runtime-cpudetect --disable-network --disable-devices --disable-encoder=vorbis --enable-libvorbis
make

cp ffmpeg.exe $BASEDIR
</pre>
<p>Just transfer that script to the user you create when you installed Ubuntu and run it. You will need to provide your password once so that the system can install a few tools but after that everything is done automatically. At the end you will have exe files in the directory you ran the script from.</p>
<p>Transfer the exe files that are created to a windows machine and then transcode a video like this:</p>
<div class="codesnip-container" >ffmpeg.exe -i Big_Buck_Bunny_1080p.avi -acodec libvorbis -ac 2 -ab 128k -ar 44100 -s 720&#215;480 Big_Buck_Bunny_1080p.webm</div>
<p>Please note that you need to include the audio codec information above to correctly encode the video. If you don&#039;t include rate values you will get an error telling you the libvorbis can&#039;t be initialized.</p>
<p>When the transcoding is done you will have a WebM video. Grab your closest HTML5 video player like <a href="http://videojs.com/">VideoJS</a> and you are ready to go.</p>
<p>For a demo video encoded using FFMpeg created with the above script check out this <a href="http://www.ioncannon.net/examples/vp8-webm/demo.html">WebM demo video</a>. You will need to use one of the following browsers to view the demo (all of these are as of July 13 2010, support will eventually be added to the main build):</p>
<ul>
<li><a href="http://www.chromium.org/getting-involved/dev-channel">Chromium</a> dev channel build</li>
<li><a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox</a> 4 beta</li>
<li><a href="http://www.opera.com/download/">Opera</a></li>
<li><a href="http://windowsteamblog.com/windows/b/bloggingwindows/archive/2010/05/19/another-follow-up-on-html5-video-in-ie9.aspx">IE 9</a> when the user has the Direct Show DLLs installed</li>
</ul>
<p>I have tested the demo video on each of the above, except for IE9 that doesn&#039;t have WebM support as of yet, and it seems to work pretty well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/meta/1128/compiling-webm-ffmpeg-windows/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>How to Create iPad Formatted Videos Using HandBrake or FFMpeg</title>
		<link>http://www.ioncannon.net/meta/1040/how-to-create-ipad-formatted-videos-using-handbrake-or-ffmpeg/</link>
		<comments>http://www.ioncannon.net/meta/1040/how-to-create-ipad-formatted-videos-using-handbrake-or-ffmpeg/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 10:56:19 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[handbrake]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/?p=1040</guid>
		<description><![CDATA[This is for those who may want to load a video onto their iPad with iTunes that isn&#039;t in the correct format. I needed to do this because I was trying to put an iTunes University video on my iPad a couple days ago and iTunes complained that it wasn&#039;t in the correct format for [...]]]></description>
			<content:encoded><![CDATA[<p>This is for those who may want to load a video onto their iPad with iTunes that isn&#039;t in the correct format. I needed to do this because I was trying to put an iTunes University video on my iPad a couple days ago and iTunes complained that it wasn&#039;t in the correct format for the iPad. I&#039;m not sure exactly how that could be but I decided to take the opportunity to see if I could use <a href="http://handbrake.fr/">HandBrake</a> to easily convert it to an iPad friendly format. There is currently no pre-loaded iPad configuration for HandBrake like there is for the iPhone and iPod Touch so I created a few profiles that can easily be imported into HandBrake to output different sizes for the iPad:</p>
<ul>
<li><a href="http://www.ioncannon.net/projects/ipadhandbrake/iPad-4x3.plist">iPad-4&#215;3.plist</a> &#8211; A 4&#215;3 aspect ratio at 640&#215;480</li>
<li><a href="http://www.ioncannon.net/projects/ipadhandbrake/iPad-16x9.plist">iPad-16&#215;9.plist</a> &#8211; A 16&#215;9 aspect ratio at 640&#215;360</li>
<li><a href="http://www.ioncannon.net/projects/ipadhandbrake/iPad-Full.plist">iPad-Full.plist</a> &#8211; A 4&#215;3 aspect ratio at 1024&#215;576</li>
</ul>
<p>Note that when you import videos using iTunes the iPad puts them in their own Videos app unlike the iPhone where they show up under the iPod app. You will want to find the Videos icon if you don&#039;t already know where it is:</p>
<p><a href="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-iPad-Videos.jpg"><img src="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-iPad-Videos-300x163.jpg" alt="iPad Videos Screenshot" title="iPad Videos Screenshot" width="300" height="163" class="alignnone size-medium wp-image-1043" /></a></p>
<p>After verifying that the above 4&#215;3 version worked for the iTunes University video I went about testing it on a couple other video formats. I tested the <a href="http://www.bigbuckbunny.org/">Big Buck Bunny</a> video that I also used for my post on <a href="http://www.ioncannon.net/programming/1015/ipad-streaming-video-and-more/">iPad video streaming</a> in both 640&#215;360 and 1024&#215;576 output formats. Both resolutions looked great. I also tried converting a DVD. If you decide to convert a DVD you will probably want to turn on de-interlacing in HandBrake. You do that by first selecting the &#034;Picture Settings&#034; option:</p>
<p><a href="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-HandBrake-PictureSettings.png"><img src="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-HandBrake-PictureSettings-300x81.png" alt="HandBrake Picture Settings Screenshot" title="HandBrake Picture Settings Screenshot" width="300" height="81" class="alignnone size-medium wp-image-1042" /></a></p>
<p>Then the filters tab and then select the type of de-interlace you want (fast, slow, slowest):</p>
<p><a href="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-HandBrake-DeInterlaceSettings.png"><img src="http://www.ioncannon.net/wp-content/uploads/2010/04/Screenshot-HandBrake-DeInterlaceSettings-300x103.png" alt="HandBrake DeInterlace Settings Screenshot" title="HandBrake DeInterlace Settings Screenshot" width="300" height="103" class="alignnone size-medium wp-image-1041" /></a></p>
<p>If you want to use FFMpeg to do all this you can. The following is a slightly modified version of the streaming command I&#039;m using that will output a high bitrate version of the input video:</p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">ffmpeg</span> <span class="re5">-y</span> <span class="re5">-i</span> input.avi <span class="re5">-acodec</span> aac <span class="re5">-ar</span> 48000 <span class="re5">-ab</span> 128k <span class="re5">-ac</span> 2 <span class="re5">-s</span> 1024&#215;768 <span class="re5">-vcodec</span> libx264 <span class="re5">-b</span> 1200k <span class="re5">-flags</span> +loop+mv4 <span class="re5">-cmp</span> 256 <span class="re5">-partitions</span> +parti4x4+partp8x8+partb8x8 <span class="re5">-subq</span> 7 <span class="re5">-trellis</span> 1 <span class="re5">-refs</span> 5 <span class="re5">-coder</span> 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 <span class="re5">-bt</span> 1200k <span class="re5">-maxrate</span> 1200k <span class="re5">-bufsize</span> 1200k -rc_eq <span class="st_h">&#039;blurCplx^(1-qComp)&#039;</span> <span class="re5">-qcomp</span> 0.6 <span class="re5">-qmin</span> 10 <span class="re5">-qmax</span> 51 <span class="re5">-qdiff</span> 4 <span class="re5">-level</span> 30 <span class="re5">-aspect</span> 16:9 <span class="re5">-r</span> 30 <span class="re5">-g</span> 90 <span class="re5">-async</span> <span class="nu0">2</span> output.mp4</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/meta/1040/how-to-create-ipad-formatted-videos-using-handbrake-or-ffmpeg/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>iPhone HTTP Streaming with FFMpeg and an Open Source Segmenter</title>
		<link>http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/</link>
		<comments>http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 23:43:45 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/?p=452</guid>
		<description><![CDATA[With the release of the iPhone OS 3 update came the ability to do live streaming. There are a few types of streaming and each requires a certain encoding and segmentation. I&#039;ve put together a cheat sheet on how I went about building a static stream using FFMpeg and an example segmenter that someone has [...]]]></description>
			<content:encoded><![CDATA[<p>With the release of the iPhone OS 3 update came the ability to do live streaming. There are a few types of streaming and each requires a certain encoding and segmentation. I&#039;ve put together a cheat sheet on how I went about building a static stream using FFMpeg and an example segmenter that someone has posted. I&#039;m not covering windowed streams in this post but if you are thinking about implementing a windowed stream the following will help you make a step in that direction.</p>
<p>Before getting started it is best to read over the Apple documentation on HTTP live streaming. Start out with the <a href="http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/iPhoneStreamingMediaOverview/iPhoneStreamingMediaOverview.html#//apple_ref/doc/uid/TP40008332-CH100-SW4">iPhone streaming media overview</a>. This document covers the basics of how the streaming works and has some nice diagrams.</p>
<p>If you want even more information after reading the overview you can take a look at the <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-01">HTTP Live streaming draft proposal</a> that was submitted to the IETF by Apple. It covers the streaming protocol in complete detail and has examples of the stream file format for reference.</p>
<p>Once you are ready to start grab a decent quality video clip to use. If you don&#039;t have one handy I found a nice list of downloadable <a href="http://www.highdefforum.com/high-definition-movies-video-clips/6537-official-hd-video-clip-list.html">HD clips</a> in various formats for testing.</p>
<p><span id="more-452"></span></p>
<h3>Step 1: Grab the latest version of FFMpeg</h3>
<p>You may be able to get away with anything after FFMpeg 0.5 but you might as well pull down a more recent version. The FFMpeg <a href="http://ffmpeg.org/download.html">download page</a> has instructions on getting the latest version. I pulled the version I used out of git.</p>
<p>I used the following command to configure FFMpeg:</p>
<pre>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">configure --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libx264</div>
</div>
</pre>
<p>One of the main things to note is the &#45;-enable-libx264 flag.</p>
<h3>Step 2: Encode your video for the iPhone</h3>
<p>Once you have a working version of FFMpeg it is time to create an X264 encoded stream that will work with the iPhone. There are a few things to note before diving in:</p>
<ol>
<li>The supported bitrates for streaming are: 100 Kbps to 1.6 Mbps</li>
<li>The suggested bitrates for streaming are*:
<ul>
<li>Low &#8211; 96 Kbps video, 64 Kbps audio</li>
<li>Medium &#8211; 256 Kbps video, 64 Kbps audio</li>
<li>High &#8211; 800 Kbps video, 64 Kbps audio</li>
</ul>
</li>
<li>The iPhone screen size is: 480&#215;320</li>
</ol>
<p>* See step 7 for more information on what I think are better bitrates.</p>
<p>Taking all that into account someone on the iPhone developer forums suggested the following and it works well for me:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">ffmpeg -i &lt;in file&gt; -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 320&#215;240 -vcodec libx264 -b 96k -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate 96k -bufsize 96k -rc_eq &#039;blurCplx^(1-qComp)&#039; -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 &lt;output file&gt;</div>
</div>
<p>If you want some more detail on some of these commands check out the <a href="http://rob.opendot.cl/index.php/useful-stuff/ffmpeg-x264-encoding-guide/">X264 encoding guide</a> and in general the <a href="http://ffmpeg.org/ffmpeg-doc.html">FFMpeg documentation</a> to see what all the flags mean.</p>
<p>Note that I have the bitrate set to 96k in the above example. That can be changed to fit your needs. Use the script that I have created later in the post or just make sure you change the -b, -maxrate, and -bufsize values.</p>
<h3>Step 3: Download and build the segmenter</h3>
<p>Now you have a complete video but you don&#039;t want to toss the entire thing up or you wouldn&#039;t be reading about HTTP streaming. What you need is a way to segment the video stream into smaller chunks. You can download Apple&#039;s segmenter (see the overview above for more information on where to find it) or you can download one created by the forum user <a href="https://devforums.apple.com/people/corp186">corp186</a>. </p>
<p>There is an SVN repository set up for the <a href="http://svn.assembla.com/svn/legend/segmenter/">segmenter source</a>. It is only a couple files and it is easy to build. The trouble you may run into is that the Makefile that it comes with won&#039;t build the binary correctly. Don&#039;t worry it just takes some extra link flags to make it work. The following is what I needed in the Makefile to get it to build on my system:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">all:<br />
&nbsp; &nbsp; &nbsp; &nbsp; gcc -Wall -g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad</p>
<p>clean:<br />
&nbsp; &nbsp; &nbsp; &nbsp; rm segmenter</div>
</div>
<p>After compiling the segmenter you are ready to create your first HTTP streaming content. </p>
<p>The format of the segmenter command is:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">segmenter &lt;input MPEG-TS file&gt; &lt;segment duration in seconds&gt; &lt;output MPEG-TS file prefix&gt; &lt;output m3u8 index file&gt; &lt;http prefix&gt;</div>
</div>
<p>Following is an example used to create a stream from a video file created with the above FFMpeg command split into 10 second intervals:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">segmenter sample_low.ts 10 sample_low stream_low.m3u8 http://www.ioncannon.net/</div>
</div>
<h3>Step 4: Prepare the HTTP server</h3>
<p>At this point you should have a set of files that represent the stream and a stream definition file. Those files can be uploaded to a web server at this point but there is another important step to take that ensures they will be download correctly and that is setting up mime types. There are two mime types that are important for the streaming content:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">.m3u8 application/x-mpegURL<br />
.ts video/MP2T</div>
</div>
<p>If you are using Apache you would want to add the following to your httpd.conf file:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">AddType application/x-mpegURL .m3u8<br />
AddType video/MP2T .ts</div>
</div>
<p>If you are using lighttpd you would want to put this in your configuration file (if you have other mime types defined make sure you just add these and don&#039;t set them):</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">mimetype.assign = ( &quot;.m3u8&quot; =&gt; &quot;application/x-mpegURL&quot;, &quot;.ts&quot; =&gt; &quot;video/MP2T&quot; )</div>
</div>
<h3>Step 5: Test the stream</h3>
<p>The video is encoded for the iPhone, segmented for streaming, and the server is configured. The only thing left to do is test the stream and the fastest way to do that is to use the new HTML5 video tag. Here is an example of how to set it up:</p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span><br />
&nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/title.html"><span class="kw2">title</span></a>&gt;</span>Video Test<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/title.html"><span class="kw2">title</span></a>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/meta.html"><span class="kw2">meta</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;viewport&quot;</span> <span class="kw3">content</span><span class="sy0">=</span><span class="st0">&quot;width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span><br />
&nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;background-color:#FFFFFF; &quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/center.html"><span class="kw2">center</span></a>&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span class="sc2">&lt;video <span class="kw3">width</span><span class="sy0">=</span><span class="st0">&#039;150&#039;</span> <span class="kw3">height</span><span class="sy0">=</span><span class="st0">&#039;150&#039;</span> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;stream-128k.m3u8&quot;</span> <span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/center.html"><span class="kw2">center</span></a>&gt;</span><br />
&nbsp; <span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span></div>
</div>
<p> If everything has been done correctly you should see the video.</p>
<p>If you want to test the stream out in an application then <a href="http://developer.apple.com/iphone/library/samplecode/MoviePlayer_iPhone/index.html">download the MoviePlayer iPhone demo application</a> from the iPhone developer site. Build and run it in the simulator or put it on an actual phone and then type the URL in for the server you uploaded your stream to.</p>
<p>That is all there is to building a single static HTTP stream. A good number of steps but if you have some experience using FFMpeg it isn&#039;t too hard to set up. The only pitfalls I ran into revolve around trying to segment the stream without the segmeter code. I don&#039;t know enough about how the segmentation works to know why this is so difficult to do but I believe it could have something to do with synchronization points in the stream. Of course when you stray from the path the stream just doesn&#039;t work and you get a generic error message so that is just my best guess. I&#039;ll also guess that Apple may tighten up the player over time and make it work better with miss-formatted streams.</p>
<h3>Step 6: Automating the stream encoding and segmentation</h3>
<p>Here is a little script I put together that first encodes an input file and then segments it into 10 second chunks:</p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="co0">#!/bin/sh</span></p>
<p><span class="re2">BR</span>=800k</p>
<p><span class="kw2">ffmpeg</span> <span class="re5">-i</span> $1 <span class="re5">-f</span> mpegts <span class="re5">-acodec</span> libmp3lame <span class="re5">-ar</span> 48000 <span class="re5">-ab</span> 64k <span class="re5">-s</span> 320&#215;240 <span class="re5">-vcodec</span> libx264 <span class="re5">-b</span> <span class="re1">$BR</span> <span class="re5">-flags</span> +loop <span class="re5">-cmp</span> +chroma <span class="re5">-partitions</span> +parti4x4+partp8x8+partb8x8 <span class="re5">-subq</span> 5 <span class="re5">-trellis</span> 1 <span class="re5">-refs</span> 1 <span class="re5">-coder</span> 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 <span class="re5">-bt</span> 200k <span class="re5">-maxrate</span> <span class="re1">$BR</span> <span class="re5">-bufsize</span> <span class="re1">$BR</span> -rc_eq <span class="st_h">&#039;blurCplx^(1-qComp)&#039;</span> <span class="re5">-qcomp</span> 0.6 <span class="re5">-qmin</span> 10 <span class="re5">-qmax</span> 51 <span class="re5">-qdiff</span> 4 <span class="re5">-level</span> 30 <span class="re5">-aspect</span> 320:240 <span class="re5">-g</span> 30 <span class="re5">-async</span> 2 sample_<span class="re1">$BR_pre</span>.ts</p>
<p>segmenter sample_<span class="re1">$BR_pre</span>.ts 10 sample_<span class="re1">$BR</span> stream-<span class="re1">$BR</span>.m3u8 http:<span class="sy0">//</span>www.ioncannon.net<span class="sy0">/</span></p>
<p><span class="kw2">rm</span> <span class="re5">-f</span> sample_<span class="re1">$BR_pre</span>.ts</div>
</div>
<p>The script could use some work but it does a good enough job for testing.</p>
<h3>Step 7: Create a variable rate HTTP stream</h3>
<p>Once you have creating a single stream down you need to try out creating a variable bitrate stream. There isn&#039;t much to it, just create different bitrate encoded streams and link to their stream definition files in a separate stream definition file. Here is an example:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">#EXTM3U<br />
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=96000<br />
http://192.168.132.15/ipv/stream-96k.m3u8<br />
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000<br />
http://192.168.132.15/ipv/stream-256k.m3u8<br />
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000</p>
<p>http://192.168.132.15/ipv/stream-800k.m3u8</p></div>
</div>
<p>I gave the above a try using both the iPhone&#039;s 3G connection and a WIFI connection. The following log shows the two different attempts (first 3G then WIFI):</p>
<pre>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">6.x.x.x ioncannon.net - [20:49:13] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 304 0 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:14] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 206 288 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:15] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 200 288 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:16] &quot;GET /stream-96k.m3u8 HTTP/1.1&quot; 200 719 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:18] &quot;GET /s_96k-00001.ts HTTP/1.1&quot; 200 334828 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:21] &quot;GET /s_96k-00002.ts HTTP/1.1&quot; 200 377880 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:30] &quot;GET /s_96k-00003.ts HTTP/1.1&quot; 200 383520 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:32] &quot;GET /stream-256k.m3u8 HTTP/1.1&quot; 200 730 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:39] &quot;GET /s_256k-00003.ts HTTP/1.1&quot; 200 716844 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:49] &quot;GET /s_256k-00004.ts HTTP/1.1&quot; 200 705564 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:57] &quot;GET /stream-96k.m3u8 HTTP/1.1&quot; 200 719 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:49:59] &quot;GET /s_96k-00004.ts HTTP/1.1&quot; 200 368668 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:03] &quot;GET /s_96k-00005.ts HTTP/1.1&quot; 200 371300 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:13] &quot;GET /s_96k-00006.ts HTTP/1.1&quot; 200 398936 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:16] &quot;GET /stream-256k.m3u8 HTTP/1.1&quot; 200 730 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:22] &quot;GET /s_256k-00006.ts HTTP/1.1&quot; 200 758016 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:36] &quot;GET /s_256k-00007.ts HTTP/1.1&quot; 200 737524 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:40] &quot;GET /s_256k-00008.ts HTTP/1.1&quot; 200 773244 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:46] &quot;GET /s_256k-00009.ts HTTP/1.1&quot; 200 717032 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:50:57] &quot;GET /s_256k-00010.ts HTTP/1.1&quot; 200 768920 &quot;-&quot; &quot;...&quot;
6.x.x.x ioncannon.net - [20:51:06] &quot;GET /s_256k-00011.ts HTTP/1.1&quot; 200 611000 &quot;-&quot; &quot;...&quot;

1.x.x.x ioncannon.net - [20:52:23] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 304 0 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:24] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 206 288 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:25] &quot;GET /varpl.m3u8 HTTP/1.1&quot; 200 288 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:25] &quot;GET /stream-96k.m3u8 HTTP/1.1&quot; 200 719 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:26] &quot;GET /s_96k-00001.ts HTTP/1.1&quot; 200 334828 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:27] &quot;GET /s_96k-00002.ts HTTP/1.1&quot; 200 377880 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:28] &quot;GET /stream-800k.m3u8 HTTP/1.1&quot; 200 730 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:31] &quot;GET /s_800k-00002.ts HTTP/1.1&quot; 200 1774156 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:34] &quot;GET /s_800k-00003.ts HTTP/1.1&quot; 200 1916096 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:38] &quot;GET /s_800k-00004.ts HTTP/1.1&quot; 200 1831872 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:41] &quot;GET /s_800k-00005.ts HTTP/1.1&quot; 200 1831496 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:46] &quot;GET /s_800k-00006.ts HTTP/1.1&quot; 200 1967608 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:50] &quot;GET /s_800k-00007.ts HTTP/1.1&quot; 200 1676208 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:54] &quot;GET /s_800k-00008.ts HTTP/1.1&quot; 200 2094132 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:52:58] &quot;GET /s_800k-00009.ts HTTP/1.1&quot; 200 1860260 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:53:08] &quot;GET /s_800k-00010.ts HTTP/1.1&quot; 200 2008404 &quot;-&quot; &quot;...&quot;
1.x.x.x ioncannon.net - [20:53:19] &quot;GET /s_800k-00011.ts HTTP/1.1&quot; 200 1400224 &quot;-&quot; &quot;...&quot;</div>
</div>
</pre>
<p>Notice that there is a decent bit of indecisiveness on the part of what stream to pick when using 3G. For my test it actually caused the player to pause while it switched from the 256k stream back to the 96k stream. The stream on the WIFI connection starts out low but then jumps right to the highest quality and stays there. Overall it seems like the variable rate streaming works decently and again Apple may be able to tweak it down the road to get even better results.</p>
<p>The bitrate jump between 96k and 256k is probably too large even though that is what Apple seems to recommend. I believe with some testing a better set of bitrates could be found. The video quality of the 256k bitrate looks pretty good so I would say that 96k, 128k and 384k would potentially be a better choice.</p>
<p><i>Some parting notes</i></p>
<p>If you are interested in how the segmenter works you can find out more on how to use libavformat at the following resources: <a href="http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html">an older libavformat tutorial</a>, <a href="http://www.cryptosystem.org/archives/2006/03/libavcodec-libavformat-sample-code/">some sample libavformat code</a>, <a href="http://www.dranger.com/ffmpeg/">How to Write a Video Player in Less Than 1000 Lines</a>, and <a href="http://web.me.com/dhoerl/Home/Tech_Blog/Entries/2009/1/22_Revised_avcodec_sample.c.html">more sample libavformat code</a>.</p>
<p>The next step for this is to do a windowed live stream. I&#039;ve done a little experimenting so far and with a modified segmeter I can generate a live stream. I will need to heavily modify the segmeter to get a live windowed stream so it may take a little while to get it done. My intent of course will be to combine the modifications with something fun like S3 and cloudfront since I believe that would be a sweat combination.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/feed/</wfw:commentRss>
		<slash:comments>195</slash:comments>
		</item>
	</channel>
</rss>

