After some more work I have enhanced the HTTP segmenter and uploading script from my iPhone streaming using AWS S3 and Cloudfront post. I added a number of features and tried to pull together some of the ideas from the comments. I’ll go over some of the features here and there is a full list of configuration options on the HTTP Live Video Streaming server project page and the source is available at the github repo.
So the major changes I have added are:
- Yaml based configuration file. See the project page for a complete list of options.
- Ability to transfer segments via copy, ftp, scp and s3.
- Added the ability to do variable bitrate streams.
- Added re-streaming support.
- Added logging to a file and better debug output.
The variable bitrate streams where done by using pipes. I have done a large amount of testing via ITT Systems and it seems to work fairly well. I am able to stream a live HD video source into 3 different bitrates on a fairly old PC. Here are a couple clips I created to show the progressive enhancement in action, you probably want to switch to the HD version of the video and watch it full screen to get the bet view:
The configuration file will allow for any number of encoding options or transfer options and they can be put together in a number of different ways. Here are a couple examples of both, see the example configuration files for more.
An encoder example:
[code lang=”text”]
ep_128k:
ffmpeg_command: "ffmpeg -er 4 -y -i %s -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 320×240 -vcodec libx264 -b 128k -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 128k -maxrate 128k -bufsize 128k -rc_eq ‘blurCplx^(1-qComp)’ -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 – | %s %s %s %s %s"
bandwidth: 128000
[/code]
Transfer configuration example:
[code lang=”text”]
ftp_dev:
transfer_type: ‘ftp’
remote_host: ‘192.168.1.1’
user_name: ‘user’
password: ‘pass’
directory: ‘html/streamingvideo’
[/code]
As a final note on changes, you are no longer able to use the segmenter without the script now really. If you want to do that you should use the original version of the segmenter source.
Please note that there is still some work to be done on the script to be complete. If I have time my next enhancement will be to add encryption and I will probably try to test builds on other distributions (maybe attempt to create segmenter binaries).
Wow great stuff! After a few late nights i managed to compile live_streamer (my library paths seemed to be out of wack, cleaning up macports helped). Anyway it works great. It could be nice to merge this into the old iSquint (now punyVid [1]) to make some sort of live transcoder with gui and playlist support, but I do not have the Cocoa-skills (yet) ;). Thanks for sharing this!
[1] http://transcoderredux.svn.sourceforge.net/viewvc/transcoderredux/PunyVid/
Very interesting project ! I managed to get everything working, but i have one problem : when playing the video, i realized that it contains some “clicks” in audio streams, and also some freezes in video stream. I’ve tried to tweek my encoding settings, but finally found the problem somewhere else : if i remove the pipe between ffmpeg encode and the segmenter, and replace it by, for example, a temporary file (thus making ffmpeg and segmenter running in sequence instead of parallel if i’m right),… it works perfectly ! I still don’t understand why.
Any ideas on that ?
Thanks again for the great work !
Hi again,
Don’t know if i am the only one having such problem… maybe because i’m using a tweaked version of ffmpeg for embedded. Anyway, i identified the reason for that: ffmpeg seems to create corrupted TS streams when the input protocol does not support “seek” function. Which means : in case of file protocol, no problem (that’s why using a temporary file solved my problem). But, using pipe protocol, seek functionality is not provided and ffmpeg output contains clicks, like desynchronization between audio and video.
Hope this helps! (maybe an interesting idea would be to add some kind of ffmpeg protocol registering to the segmenter, in order to support “seek”, even if restricted : i still have to check why seek is needed, and it would be sufficient).
folks,
the very last segment always misses a second or 2 (the time bar stops at –0:01) and the quicktime logo is shown.
has anyone had a fix for this? thx.
Is there any documentation on how to use this? Or do I need to know how to integrate the ruby into apache? I managed to get it to compile, but then when I go to http://my-server/html/streamingvideo/stream_multi.m3u8 on my iphone4, I get 20 seconds of choppy video and it exits.
ubuntu lucid lynx: https://gist.github.com/762299
how do I use it with a live stream from a pipe? is that possible?
Hi,
Very interesting.
I was wondering about the 64k bitrate fallback that seems to miss to the yaml file (required by Apple)
Any tips on howto do integrate this ?
Many thanks
@bn The required 64k bitrate fallback is indeed missing. I haven’t had time to add it yet and doing so will require some work because the audio tracks aren’t currently separated from the video before being segmented. They need to be separated so that the 64k fallback will sync correctly.
Hello Carson
Thank you for the inspiration to follow through and make this work. I have written a Howto for the setup of a live broadcast. the url is http://www.onvos.com/http-live-streaming-howto.html
Thanks again.
B
Do you have the separate audio track commando already contemplated?
Hello Carson
I have segmented Zeitgeist Moving forward, a 2 hour 41 min movie and get the m3u8 multi stream to play it in 2:19.
http://www.onvos.com/zmf.html
I am still trying to find the error in ffmpeg, but no additional parameter helps.
When I use the -vn trying to create an audio only stream, the length is correctly 2:41
Do you have any idea where the missing 22 minutes went?
Take the time and have a nice evening viewing the video.
Saludos
Bernhard
@bernhard no audio track support yet, it is something I haven’t had time to really get started on.
Hi Bastien – Can you let us have the version of the script where you’ve taken out the pipe … might work for me!
Thanks, Tony
I am getting the following error while compiling the live_segmenter.c file. Please help.
Thanks in advance.
Amit
=====ERROR=====
gcc -Wall -g live_segmenter.c -o live_segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad -lpthread
live_segmenter.c: In function ‘add_output_stream’:
live_segmenter.c:70: error: ‘CODEC_TYPE_AUDIO’ undeclared (first use in this function)
live_segmenter.c:70: error: (Each undeclared identifier is reported only once
live_segmenter.c:70: error: for each function it appears in.)
live_segmenter.c:84: error: ‘CODEC_TYPE_VIDEO’ undeclared (first use in this function)
live_segmenter.c: In function ‘main’:
live_segmenter.c:165: warning: implicit declaration of function ‘guess_format’
live_segmenter.c:165: warning: initialization makes pointer from integer without a cast
live_segmenter.c:192: e
Hello, Amit. I had the same problem and I have already solved it.
The reason is in new libavformat which has constants with different names.
Try replace CODEC_TYPE_AUDIO with AVMEDIA_TYPE_AUDIO, CODEC_TYPE_VIDEO with AVMEDIA_TYPE_VIDEO and PKT_FLAG_KEY with AV_PKT_FLAG_KEY in your live_segmenter.c source. It helps me to compile live_segmenter.