iPhone HTTP Streaming with FFMpeg and an Open Source Segmenter

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'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'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 and read about the Ethernet broadband benefits data so that it's received in real-time.
Many professional broadcasters use live streaming software in addition to their online video platforms. Video streaming software typically provides tools for encoding, transcoding, adding on-screen effects, and more.

If you are looking for a no-frills, lightweight tool for broadcast live stream production and other video tasks, FFmpeg may be the software for you. You can use FFmpeg to create rtmp streams.

This feature-rich tool is primarily designed for advanced broadcasters. To help lower the learning curve, we’ve put together this guide to break down some of the code and functions available on FFmpeg. This FFmpeg tutorial will help you understand how it works.

In this post, we’ll cover how to set up FFmpeg on Linux, Mac, and Windows, and how to use FFmpeg to broadcast live streams.

Before getting started it is best to read over the Apple documentation on HTTP live streaming. Start out with the iPhone streaming media overview. This document covers the basics of how the streaming works and has some nice diagrams.

If you want even more information after reading the overview you can take a look at the HTTP Live streaming draft proposal 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.

Once you are ready to start grab a decent quality video clip to use. If you don't have one handy I found a nice list of downloadable HD clips in various formats for testing.

Step 1: Grab the latest version of FFMpeg

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 download page has instructions on getting the latest version. I pulled the version I used out of git.

I used the following command to configure FFMpeg:

configure --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libx264

One of the main things to note is the –enable-libx264 flag.

Step 2: Encode your video for the iPhone

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:

  1. The supported bitrates for streaming are: 100 Kbps to 1.6 Mbps
  2. The suggested bitrates for streaming are*:
    • Low – 96 Kbps video, 64 Kbps audio
    • Medium – 256 Kbps video, 64 Kbps audio
    • High – 800 Kbps video, 64 Kbps audio
  3. The iPhone screen size is: 480×320

* See step 7 for more information on what I think are better bitrates.

Taking all that into account someone on the iPhone developer forums suggested the following and it works well for me:

ffmpeg -i <in file=""> -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 320x240 -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 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 <output file="">

If you want some more detail on some of these commands check out the X264 encoding guide and in general the FFMpeg documentation to see what all the flags mean.

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.

Step 3: Download and build the segmenter

Now you have a complete video but you don't want to toss the entire thing up or you wouldn't be reading about HTTP streaming. What you need is a way to segment the video stream into smaller chunks. You can download Apple's segmenter (see the overview above for more information on where to find it) or you can download one created by the forum user corp186.

There is an SVN repository set up for the segmenter source. 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't build the binary correctly. Don'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:

all:
gcc -Wall -g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad

clean:
rm segmenter

After compiling the segmenter you are ready to create your first HTTP streaming content.

The format of the segmenter command is:

segmenter <input mpeg-ts="" file=""> <segment duration="" in="" seconds=""> <output mpeg-ts="" file="" prefix=""> <output m3u8="" index="" file=""> <http prefix="">

Following is an example used to create a stream from a video file created with the above FFMpeg command split into 10 second intervals:

segmenter sample_low.ts 10 sample_low stream_low.m3u8 http://www.ioncannon.net/

Step 4: Prepare the HTTP server

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:

.m3u8 application/x-mpegURL
.ts video/MP2T

If you are using Apache you would want to add the following to your httpd.conf file:

AddType application/x-mpegURL .m3u8
AddType video/MP2T .ts

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't set them):

mimetype.assign = ( ".m3u8" =&gt; "application/x-mpegURL", ".ts" =&gt; "video/MP2T" )

Step 5: Test the stream

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:


<title>Video Test</title>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">

<center>
<video width="150" height="150" src="stream-128k.m3u8">
</video></center>

If everything has been done correctly you should see the video.

If you want to test the stream out in an application then download the MoviePlayer iPhone demo application 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.

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'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'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't work and you get a generic error message so that is just my best guess. I'll also guess that Apple may tighten up the player over time and make it work better with miss-formatted streams.

Step 6: Automating the stream encoding and segmentation

Here is a little script I put together that first encodes an input file and then segments it into 10 second chunks:

#!/bin/sh

BR=800k

ffmpeg -i $1 -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 320x240 -vcodec libx264 -b $BR -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 $BR -bufsize $BR -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 sample_$BR_pre.ts

segmenter sample_$BR_pre.ts 10 sample_$BR stream-$BR.m3u8 http://www.ioncannon.net/

rm -f sample_$BR_pre.ts

The script could use some work but it does a good enough job for testing.

Step 7: Create a variable rate HTTP stream

Once you have creating a single stream down you need to try out creating a variable bitrate stream. There isn'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:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=96000
http://192.168.132.15/ipv/stream-96k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000
http://192.168.132.15/ipv/stream-256k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000
http://192.168.132.15/ipv/stream-800k.m3u8

I gave the above a try using both the iPhone's 3G connection and a WIFI connection. The following log shows the two different attempts (first 3G then WIFI):

6.x.x.x ioncannon.net - [20:49:13] "GET /varpl.m3u8 HTTP/1.1" 304 0 "-" "..."
6.x.x.x ioncannon.net - [20:49:14] "GET /varpl.m3u8 HTTP/1.1" 206 288 "-" "..."
6.x.x.x ioncannon.net - [20:49:15] "GET /varpl.m3u8 HTTP/1.1" 200 288 "-" "..."
6.x.x.x ioncannon.net - [20:49:16] "GET /stream-96k.m3u8 HTTP/1.1" 200 719 "-" "..."
6.x.x.x ioncannon.net - [20:49:18] "GET /s_96k-00001.ts HTTP/1.1" 200 334828 "-" "..."
6.x.x.x ioncannon.net - [20:49:21] "GET /s_96k-00002.ts HTTP/1.1" 200 377880 "-" "..."
6.x.x.x ioncannon.net - [20:49:30] "GET /s_96k-00003.ts HTTP/1.1" 200 383520 "-" "..."
6.x.x.x ioncannon.net - [20:49:32] "GET /stream-256k.m3u8 HTTP/1.1" 200 730 "-" "..."
6.x.x.x ioncannon.net - [20:49:39] "GET /s_256k-00003.ts HTTP/1.1" 200 716844 "-" "..."
6.x.x.x ioncannon.net - [20:49:49] "GET /s_256k-00004.ts HTTP/1.1" 200 705564 "-" "..."
6.x.x.x ioncannon.net - [20:49:57] "GET /stream-96k.m3u8 HTTP/1.1" 200 719 "-" "..."
6.x.x.x ioncannon.net - [20:49:59] "GET /s_96k-00004.ts HTTP/1.1" 200 368668 "-" "..."
6.x.x.x ioncannon.net - [20:50:03] "GET /s_96k-00005.ts HTTP/1.1" 200 371300 "-" "..."
6.x.x.x ioncannon.net - [20:50:13] "GET /s_96k-00006.ts HTTP/1.1" 200 398936 "-" "..."
6.x.x.x ioncannon.net - [20:50:16] "GET /stream-256k.m3u8 HTTP/1.1" 200 730 "-" "..."
6.x.x.x ioncannon.net - [20:50:22] "GET /s_256k-00006.ts HTTP/1.1" 200 758016 "-" "..."
6.x.x.x ioncannon.net - [20:50:36] "GET /s_256k-00007.ts HTTP/1.1" 200 737524 "-" "..."
6.x.x.x ioncannon.net - [20:50:40] "GET /s_256k-00008.ts HTTP/1.1" 200 773244 "-" "..."
6.x.x.x ioncannon.net - [20:50:46] "GET /s_256k-00009.ts HTTP/1.1" 200 717032 "-" "..."
6.x.x.x ioncannon.net - [20:50:57] "GET /s_256k-00010.ts HTTP/1.1" 200 768920 "-" "..."
6.x.x.x ioncannon.net - [20:51:06] "GET /s_256k-00011.ts HTTP/1.1" 200 611000 "-" "..."

1.x.x.x ioncannon.net - [20:52:23] "GET /varpl.m3u8 HTTP/1.1" 304 0 "-" "..."
1.x.x.x ioncannon.net - [20:52:24] "GET /varpl.m3u8 HTTP/1.1" 206 288 "-" "..."
1.x.x.x ioncannon.net - [20:52:25] "GET /varpl.m3u8 HTTP/1.1" 200 288 "-" "..."
1.x.x.x ioncannon.net - [20:52:25] "GET /stream-96k.m3u8 HTTP/1.1" 200 719 "-" "..."
1.x.x.x ioncannon.net - [20:52:26] "GET /s_96k-00001.ts HTTP/1.1" 200 334828 "-" "..."
1.x.x.x ioncannon.net - [20:52:27] "GET /s_96k-00002.ts HTTP/1.1" 200 377880 "-" "..."
1.x.x.x ioncannon.net - [20:52:28] "GET /stream-800k.m3u8 HTTP/1.1" 200 730 "-" "..."
1.x.x.x ioncannon.net - [20:52:31] "GET /s_800k-00002.ts HTTP/1.1" 200 1774156 "-" "..."
1.x.x.x ioncannon.net - [20:52:34] "GET /s_800k-00003.ts HTTP/1.1" 200 1916096 "-" "..."
1.x.x.x ioncannon.net - [20:52:38] "GET /s_800k-00004.ts HTTP/1.1" 200 1831872 "-" "..."
1.x.x.x ioncannon.net - [20:52:41] "GET /s_800k-00005.ts HTTP/1.1" 200 1831496 "-" "..."
1.x.x.x ioncannon.net - [20:52:46] "GET /s_800k-00006.ts HTTP/1.1" 200 1967608 "-" "..."
1.x.x.x ioncannon.net - [20:52:50] "GET /s_800k-00007.ts HTTP/1.1" 200 1676208 "-" "..."
1.x.x.x ioncannon.net - [20:52:54] "GET /s_800k-00008.ts HTTP/1.1" 200 2094132 "-" "..."
1.x.x.x ioncannon.net - [20:52:58] "GET /s_800k-00009.ts HTTP/1.1" 200 1860260 "-" "..."
1.x.x.x ioncannon.net - [20:53:08] "GET /s_800k-00010.ts HTTP/1.1" 200 2008404 "-" "..."
1.x.x.x ioncannon.net - [20:53:19] "GET /s_800k-00011.ts HTTP/1.1" 200 1400224 "-" "..."

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.

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.

Some parting notes

If you are interested in how the segmenter works you can find out more on how to use libavformat at the following resources: an older libavformat tutorial, some sample libavformat code, How to Write a Video Player in Less Than 1000 Lines, and more sample libavformat code.

The next step for this is to do a windowed live stream. I'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.

198 thoughts on “iPhone HTTP Streaming with FFMpeg and an Open Source Segmenter

  1. Robert Swain

    I noticed you're using the old method of explicitly specifying all options rather than using the preset files. It's highly recommended that you use the preset files for specifying options as per the guide. It makes your life easier and the command lines more readable. :)

  2. carson Post author

    Robert, thanks for the tip. I think if I follow the way that works someone could create a file named libx264-mobile.ffpreset and stick this in it:

    flags=+loop
    cmp=+chroma
    partitions=+parti4×4+partp8×8+partb8×8
    subq=5
    trellis=1
    refs=1
    coder=0
    me_range=16
    keyint_min=25
    sc_threshold=40
    i_qfactor=0.71
    qcomp=0.6
    qmin=10
    qmax=51
    qdiff=4
    g=30

    Then the command line would change to:

    ffmpeg -i <in file> -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -vcodec libx264 -s 320×240 -b 96k -bt 200k -maxrate 96k -bufsize 96k -rc_eq 'blurCplx^(1-qComp)' -level 30 -aspect 320:240 -async 2 -vpre mobile <output file>

  3. vz

    I am trying to compile the segmenter, but I allways have the following error, does anyone have the same problem?

    segmenter.c: In function ‘add_output_stream’:
    segmenter.c:44: error: ‘AVCodecContext’ has no member named ‘ticks_per_frame’
    segmenter.c:46: error: ‘AVCodecContext’ has no member named ‘ticks_per_frame’
    segmenter.c:54: error: ‘AVCodecContext’ has no member named ‘channel_layout’
    segmenter.c:54: error: ‘AVCodecContext’ has no member named ‘channel_layout’
    segmenter.c: In function ‘main’:
    segmenter.c:219: warning: implicit declaration of function ‘avformat_alloc_context’
    segmenter.c:219: warning: assignment makes pointer from integer without a cast
    make: *** [all] Error 1

  4. chris

    I got a segmentation fault running the ffmpeg command. Which libx264 version you are using?

  5. carson Post author

    @vz It may be picking up an older version of libavformat so you might want to specify where the version you want it to use lives with -L and -I flags.

  6. carson Post author

    @chris I'm using the version from Fedora 11: x264-devel-0.0.0-0.24.20090319gitc109c8.fc11.i586 if that helps. I am also using the git repo version as of June 24th of ffmpeg.

  7. ian

    Very interested in how you get the live stream going – what are you using to encode the live transport stream- VLC?

  8. carson Post author

    @ian I'm going to try to get another post ready in a few days detailing. I will say that you can do everything with just FFMpeg depending on the location of your input. I'm going to involve VLC just to get the video stream from my camera on a laptop to a server where the encoding happens.

  9. Mike

    Great work,
    \here is what I am trying to accomplish and I am not quite sure yet how.
    Perhaps you could help.

    I want to have a continous live stream for an event so say a camera setup to stream a live event or even a non stop webcam to the iphone. I think the flow should be something like

    Camera–>VLC—>SEGMENTER—>WEB_SERVER

    If you could provide some further explanation on this I would be very greatful, \

    Thanks,

  10. carson Post author

    It is necessary unless you want to have just one big stream.

    FFMpeg by itself has two limitations as far as I can see with working this on its own:

    1) It can't encode the segments correctly on its own. I did a good bit of experimenting because I felt like it should be able to do the same thing the segmenter does even though I've read the reasons why it can't. One of those reasons is that it is said to not produce timestamps but there is actually a way to do that so you can offset the timestamps in the resulting stream so they match the offset. The other reason has to do with key frames at certain locations and I think you could solve that by just adding key frames with every frame. I've got this feeling that the true issue has to do with timestamps not actually being correctly added to the streams even though they are seemingly reported to be correct by mplayer.

    2) Now assuming you could chunk the source with FFMpeg using the current command line you still would be out of luck for windowed streaming.

    So there is actually a real reason to use the segmenter.

  11. Sylvain

    Nice howto, but I'm stuck at segmenting part

    When using the preset I always get:
    Unable to parse option value "parti4X4+partp8X8+partb8X8": undefined constant or missing (
    Invalid value '+parti4X4+partp8X8+partb8X8' for option 'partitions'

    I remove that line and this is OK but then, when I use segmenter, I always get
    [mpegts @ 0xed1110]dts < pcr, TS is invalid
    Last message repeated 17090 times
    [NULL @ 0xecf190]missing picture in access unit

    No matter which MPEG file I use as input.

  12. Graeme

    What a fantastic tutorial. I'm having trouble encoding and getting an audio error relating to mpegts [mpegts @ 0x1009400]dts < pcr, TS is invalid which ends up corrupting the clip.
    Wondering if you encountered this issue? Am using latest snapshots of everything.

  13. anonymouscoward

    i was testing this out of curiosity and i got it working from the first try on 550kbps bitrate even though segmenter spit some warnings

    # ./segmenter sample_550k_pre.ts 10 sample_550k stream-550k.m3u8 http://www.mytesting.tld
    Output #0, mpegts, to 'sample_550k':
    Stream #0.0: Video: libx264, yuv420p, 320×240, q=2-31, 90k tbn, 59.96 tbc
    Stream #0.1: Audio: libmp3lame, 48000 Hz, stereo, s16, 64 kb/s
    [mpegts @ 0x81108b0]dts < pcr, TS is invalid
    Last message repeated 36163 times
    [NULL @ 0x805f560]missing picture in access unit
    [mpegts @ 0x81108b0]dts = 63000
    Could not write frame of stream

    Any clues?

  14. anonymouscoward

    What the… my previous comment is not as complete as i wrote it :|

    Let's try again (please delete the previous one):

    So the following encode/segment is working even though i get some warnings but playback is a bit jerky and sometimes stops for 2-4 seconds

    # ./segmenter sample_550k_pre.ts 10 sample_550k stream-550k.m3u8 http://www.mytesting.tld
    Output #0, mpegts, to 'sample_550k':
    Stream #0.0: Video: libx264, yuv420p, 320×240, q=2-31, 90k tbn, 59.96 tbc
    Stream #0.1: Audio: libmp3lame, 48000 Hz, stereo, s16, 64 kb/s
    [mpegts @ 0x81108b0]dts < pcr, TS is invalid
    Last message repeated 36163 times
    [NULL @ 0x805f560]missing picture in access unit
    [mpegts @ 0x81108b0]dts = 63000
    Could not write frame of stream

    And got no output.
    Googled a bit for a solution but not much luck.

  15. Sylvain

    Ok, despite errors, streaming is OK… as long as we don't use NPVR controls and adaptive rates (video playback is not at normal speed when switching higher bitrate)…

    NPVR issue: 30s back goes to start, and forward doesn't work

    Any similar experience ?

  16. Vikas Jain

    As per HTTP Live Streaming requirement, each segmented .ts file should contain PAT and PMT tables.
    Is it Segmenter's responsibility to ensure that while segmenting it puts those?
    If not then how does FFMPEG ensures it?

  17. Leon Chen

    Hi I am having problem in configuring ffmpeg with the configuration option "–enable-libfaad" as it says faad.h file is missing. Can you advise how I could find the consistent faad.h file with that?

    thanks.

  18. Chris J.

    I cant get the Media Stream Segmenter from the apple ADC site and im a IPhone Developer with paid provisioning. from what I hear a lot of people are having the same issue with sht site not giving rights to validated Developers. Question is does anybody else know where to get the Apple Media Stream Segmenter! Thanks! Chris J.

  19. Frank Lowney

    At WWDC '07, Apple detailed byte-range serving in QuickTime, a fairly straightforward method and one that many are familiar with. So why do all of this awkward segmenting of multiple versions of a video when byte-range serving might have been the more elegant way to go about this. Latency?

    Apple also uses an MPEG-2 stream containing H.264/AAC. What's the rationale for doing that? Encryption?

  20. randall

    does anyone have a 32-bit x86 ubuntu binary of 'segmenter'? i get compilation errors – trying to build it from the ffmpeg directory as that's where libavformat/avformat.h is but it still has troubles with file paths.

  21. David

    This looks great, but the issue I am having appears to be with the ffmpeg command itself. I have a camera that is sending out H.264 with AAC audio wrapped up in mpeg4. What I reall y need, I think, is to just rewrap it in mpeg2. Any ideas on how to accomplish that? Your ffmpeg doesn't work for me at all as it stands.

    Thanks.

  22. Stephen

    Hi, I encoded my ts stream using gstreamer. It plays fine on VLC and other player but when i run it thru the segmenter. I get the follow error (lots of them):

    [mpegts @ 0x9047160]invalid dts/pts combination
    [h264 @ 0x9052800]error, non monotone timestamps 25566400 >= -9223372036854775808
    Warning: Could not write frame of stream
    [mpegts @ 0x908d460]dts < pcr, TS is invalid

    Anyone can shed some lights on whats going on?
    Many thanks.

  23. damhack

    Great work!

    It would be really really useful if someone could supply a download link to a static compile of ffmpeg and the segmenter for Mac OSX 10.5.7 or 10.5.8 Intel.

    It's a lot of hit and miss work getting everything to compile properly on OSX if you have your compiler environment set up for other types of project.

    Thanks,

    DH

  24. finney

    I am trying to compile the segmenter, but I allways have the following error, does anyone have the same problem?

    /usr/local/lib/libavcodec.a(pthread.o): In function `avcodec_thread_free':
    /home/finney/ffmpeg/libavcodec/pthread.c:95: undefined reference to `pthread_join'
    /usr/local/lib/libavcodec.a(pthread.o): In function `avcodec_thread_init':
    /home/finney/ffmpeg/libavcodec/pthread.c:159: undefined reference to `pthread_create'
    /usr/local/lib/libx264.a(encoder.o): In function `x264_encoder_close':
    encoder.c:(.text+0x23ee): undefined reference to `pthread_join'
    /usr/local/lib/libx264.a(encoder.o): In function `x264_encoder_frame_end':
    encoder.c:(.text+0x34ec): undefined reference to `pthread_join'
    /usr/local/lib/libx264.a(encoder.o): In function `x264_encoder_encode':
    encoder.c:(.text+0x7053): undefined reference to `pthread_create'
    collect2: ld Return 1

  25. Stanley

    I have succeeded to make on-demand stream for iPhone with this guide.
    But how can I avtivate seek-bar like the YouTube player?

  26. David

    I would love to see that, too. From what I've seen, the player interface supports only 30 second skip backwards or skip to live. It doesn't appear to have a random seek capability. While annoying, it does fit in with the "live streaming" Apple is going for. I really wish you could skip forward 30 seconds the same as skip backwards.

  27. Phil

    I am getting this error, not sure why. Any help is appreciated. Thanks.

    phil@ubuntu:~/ffmpeg$ ffmpeg -i /home/phil/Desktop/test1.mpeg -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 480×320 -vcodec libx264 -b 96k -flags +loop -cmp +chroma -partitions +parti4×4+partp8×8+partb8×8 -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 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 480:320 -g 30 -async 2 /home/phil/Desktop/output.mp4

    FFmpeg version SVN-r19633, Copyright (c) 2000-2009 Fabrice Bellard, et al.
    configuration: –enable-gpl –enable-nonfree –enable-pthreads –enable-libfaac –enable-libfaad –enable-libmp3lame –enable-libtheora –enable-libx264 –enable-libxvid –enable-x11grab
    libavutil 50. 3. 0 / 50. 3. 0
    libavcodec 52.32. 0 / 52.32. 0
    libavformat 52.37. 0 / 52.37. 0
    libavdevice 52. 2. 0 / 52. 2. 0
    libswscale 0. 7. 1 / 0. 7. 1
    built on Aug 12 2009 15:34:06, gcc: 4.1.3 20080623 (prerelease) (Ubuntu 4.1.2-24ubuntu1)
    [wmv3 @ 0x9349970]Extra data: 8 bits left, value: 0

    Seems stream 1 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 30.00 (30/1)
    Input #0, asf, from '/home/phil/Desktop/test1.mpeg':
    Duration: 00:00:28.71, start: 3.000000, bitrate: 3324 kb/s
    Stream #0.0(eng): Audio: wmav2, 44100 Hz, 2 channels, s16, 96 kb/s
    Stream #0.1(eng): Video: wmv3, yuv420p, 640×480, 3049 kb/s, 30 tbr, 1k tbn, 1k tbc
    Metadata
    SfOriginalFPS : 300000
    WMFSDKVersion : 11.0.6002.18005
    WMFSDKNeeded : 0.0.0.0000
    IsVBR : 0
    [NULL @ 0x9332020]Unable to parse option value "parti4×4+partp8×8+partb8×8": undefined constant or missing (
    Invalid value '+parti4×4+partp8×8+partb8×8' for option 'partitions'

  28. Pingback: Encodage de video pour l’iPhone | Digital adventures

  29. Nathan Ziarek

    No answers to the segmenter issue, huh? I installed FFMpeg using MacPorts. The header files for libavformat are in /opt/local/include/. I've included that in my $PATH, but still "make"ing the segmenter errors out.

    segmenter.c:21:34: error: libavformat/avformat.h: No such file or directory
    segmenter.c:23: error: syntax error before ‘*’ token
    segmenter.c:23: error: syntax error before ‘*’ token
    ….

    I assume this means it still can't find the header files, but I'm at a complete loss on how to instruct it. Any advice is appreciated.

  30. hEMANT

    Hi Carson,
    I referred all the istruction from your above blog, except I use the Apple's Media Segmenter.
    First, I used ffmpeg to get mpeg2 ts file.
    Then, I provided this to Apples media segmenter and it creates .m3u8 and other .ts files in o/p folder.
    Then, I publish these files on web server, and created a page with Video tag in it as descrribed by you.
    And, now I am trying to access the page on iPhone 3.0, but I can't see any video.
    When I supplied this page in the Apple's Video Demo exaample, then it says "Media Format not supported".
    aNY IDEA what may be going wrong here?

    Thanks,
    Hemant

  31. Nathan Ziarek

    Not sure if this will help, but …

    1) Download and install MacPorts
    2) Install FFMpeg using "sudo port install ffmpeg +gpl +lame +x264 +xvid"
    3) Download the three files for the segmenter app (Makefile, segmenter.c and COPYING) from the link above.
    4) Edit the Makefile file to read:

    all:
    gcc -I/opt/local/include -L/opt/local/lib -Wall -g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad
    clean:
    rm segmenter

    5) CD to the directory with Makefile and segmenter.c and run make.

    It worked on 10.5.8 after much trial and error.

  32. Shine

    Could you please tell me, what versions of libraries, FFMpeg, YASM, NASM and GCC did you use, if you succeeded to make the live stream for iphone with this guide under linux?
    I follow the steps of this guide on Suse with
    GCC 4.3.1, YASM-0.8.0, libfaad2.2.7, libmp3lame-398-2, libfaac-1.28,libx264 from git repository:git://git.videolan.org/x264.git, FFMpeg-0.5.

  33. Shine

    There were no problem, I think, during building them with shared libraries and installing the FFMpeg with the following configuration:

    ./configure --prefix=/home/shine/iphone/shared/ --extra-cflags=-I/home/shine/iphone/shared/include/ --extra-ldflags=-L/home/shine/iphone/shared/lib/ --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libx264

    And it works fine for converting the media. But I got the error message, when I used the segmenter with:

    ./segmenter ../test.ts 10 ../ts/test ../ts/stream.m3u8 /home/shine/iphone/ts/
    Output #0, mpegts, to '../ts/test':
    Stream #0.0: Video: libx264, yuv420p, 640x480, q=2-31, 90k tbn, 25 tbc
    Stream #0.1: Audio: libfaac, 24000 Hz, stereo, s16, 77 kb/s
    [h264 @ 0x815af90]error, non monotone timestamps 63000 >= 63000
    Warning: Could not write frame of stream
    [mpegts @ 0x815a000]dts < pcr, TS is invalid
    Last message repeated 2291 times
    [NULL @ 0x805f5a0]missing picture in access unit
    [mpegts @ 0x815a000]dts < pcr, TS is invalid

    MPlayer can play the separat transport stream, though. But VLC not.

    Any idea? What players or tools, which works like iphone, can play m3u8 and the streaming?
    Thanks a lot!

    @Phil: rewrite 'x' of '+parti4×4+partp8×8+partb8×8' .

  34. Pingback: Inside Mac OS X Snow Leopard: QuickTime X — RoughlyDrafted Magazine

  35. Jason Schmidt

    I answered my own question.

    My test files do stream successfully on iPhone, but stream files do not play on the Web, at least not for me, using the HTML 5 video tag viewing on Mac 10.5.7 Safari 4. HTML 5 video tag works only when calling standard .mp4 files, not .m3u8 -> .ts files.

    So, HTTP stream tests need to be conducted via Safari on the iPhone. Unless, someone knows another way…

  36. Pingback: Long-term Memory » Blog Archive » Video encoding for iPhone

  37. Rick Stevens

    If you're having problems building the segmenter, I've built it successfully on Fedora 11. You must have the ffmpeg-devel RPM (V0.5-2 or later) and the ffmpeg-libs RPM (V0.5-2 or later) installed.

    NOTE: Earlier versions of these RPMs do NOT include the "ticks_per_frame" or "channel_layout" members in the various structures and you'll get compile errors.

    You must also modify segmenter's "Makefile" by inserting

    -I/usr/include/ffmpeg

    on the "gcc" line so the compiler knows where to find the header files:

    [root@bigdog work]# cat Makefile
    all:
    gcc -Wall -I/usr/include/ffmpeg -g segmenter.c -o segmenter -lavformat -lavcodec -lavutil

    clean:
    rm segmenter

    install: segmenter
    cp segmenter /usr/local/bin/

    uninstall:
    rm /usr/local/bin/segmenter

    Hope that helps.

  38. ColletJb

    Hi,

    Thank you for this very interesting tuto.

    I'm trying to use FFMpeg to encode my video (step 2), but an error occurs and I don't understand how to fix it ? Does anyone has an idea ?

    Thank ;)

    FFmpeg version SVN-r19948, Copyright (c) 2000-2009 Fabrice Bellard, et al.
      configuration: 
      libavutil     50. 3. 0 / 50. 3. 0
      libavcodec    52.35. 0 / 52.35. 0
      libavformat   52.38. 0 / 52.38. 0
      libavdevice   52. 2. 0 / 52. 2. 0
      libswscale     0. 7. 1 /  0. 7. 1
      built on Sep 21 2009 14:08:13, gcc: 4.3.3
    
    Seems stream 0 codec frame rate differs from container frame rate: 47.95 (5000000/104271) -> 23.98 (24000/1001)
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'demo.mp4':
      Duration: 00:02:09.23, start: 0.000000, bitrate: 5843 kb/s
        Stream #0.0(und): Video: h264, yuv420p, 1280x544, 23.98 tbr, 24k tbn, 47.95 tbc
        Stream #0.1(und): Audio: aac, 48000 Hz, 2 channels, s16
      Metadata
        author          : 20th Century Fox
        title           : Fantastic Four: Rise of the Silver Surfer - Theatrical Trailer
        year            : 2007
    Incorrect frame size
    
  39. shnee

    Hi, I'm also getting this when I try to build the segmenter

    In function `add_output_stream':
    segmenter.c:28: undefined reference to `av_new_stream'
    In function `main':
    segmenter.c:177: undefined reference to `av_register_all'
    segmenter.c:225: undefined reference to `av_find_input_format'
    segmenter.c:231: undefined reference to `av_open_input_file'
    segmenter.c:237: undefined reference to `av_find_stream_info'
    segmenter.c:242: undefined reference to `guess_format'
    segmenter.c:248: undefined reference to `avformat_alloc_context'
    ...

    my makefile has

    gcc -I//ffmpeg/ -Wall -g segmenter.c -o segmenter -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad

    and my libavformat thats with ffmpeg is 52.39.0

    any help would be greatly appecriated

Leave a Reply

Your email address will not be published. Required fields are marked *