Useful script for multi-rate HLS output from ffmpeg

#!/bin/bash
VIDSOURCE=”$1RESOLUTION=”854x480”
BITRATE1=”800000BITRATE2=”600000BITRATE3=”400000”
 
AUDIO_OPTS=”-c:a libfaac -b:a 160000 -ac 2VIDEO_OPTS1=”-s $RESOLUTION -c:v libx264 -b:v $BITRATE1 -vprofilebaseline -preset medium -x264opts level=41VIDEO_OPTS2=”-s $RESOLUTION -c:v libx264 -b:v $BITRATE2 -vprofile
baseline -preset medium -x264opts level=41VIDEO_OPTS3=”-s $RESOLUTION -c:v libx264 -b:v $BITRATE3 -vprofile
baseline -preset medium -x264opts level=41OUTPUT_HLS=”-hls_time 3 -hls_list_size 10 -hls_wrap 30 -start_number 1ffmpeg -i$VIDSOURCE-y -threads 4
              $AUDIO_OPTS $VIDEO_OPTS1 $OUTPUT_HLS stream_hi.m3u8
              $AUDIO_OPTS $VIDEO_OPTS2 $OUTPUT_HLS stream_med.m3u8
              $AUDIO_OPTS $VIDEO_OPTS3 $OUTPUT_HLS stream_low.m3u8

Credit to: jeisom@gmail.com

Encoding HLS with ffmpeg

For starters here is the command to create a stream that is GOP aligned, that is has keyframes at regular intervals that can be nicely segmented. It is recommended to pull down and compile the latest version of ffmpeg for this as some of the distros can be a bit out of date.

ffmpeg -y -i %(filename)s -pix_fmt yuv420p -vcodec libx264 -acodec libfaac -r %(fps)s -profile:v baseline -b:v %(bitrate)sk -maxrate %(bitrate)sk  -force_key_frames %(keyframe_str)s -s %(width)sx%(height)s %(target_dir)s%(newFile)s

The s%(filename) are in Python format where the %s(var) bit gets replaced with your value.

For example:

ffmpeg -y -i infile.mp4 -pix_fmt yuv420p -vcodec libx264 -acodec libfaac -r 25 -profile:v baseline -b:v 2000k -maxrate 2500k  -force_key_frames 50s -s 640×360 /tmp/newfile.ts

I like to do segmenting as a second step just to keep the whole process a bit cleaner, especially if you want to produce multiple formats off the same initial encode:

ffmpeg -y -i %(target_dir)s%(filename)s -codec copy -map 0 -f segment -segment_list %(target_dir)sindex_%(bitrate)s.m3u8 -segment_time %(segment_size)s  -segment_list_type m3u8 %(filenameNoExt)s_%(count)s.ts

Or you could wrap it all into one command e.g.

ffmpeg -y -i %(filename)s -pix_fmt yuv420p -vcodec libx264 -acodec libfaac -r %(fps)s -profile:v baseline -b:v %(bitrate)sk -maxrate %(bitrate)sk  -force_key_frames %(keyframe_str)s -s %(width)sx%(height)s %-f segment -segment_list %(target_dir)sindex_%(bitrate)s.m3u8 -segment_time %(segment_size)s  -segment_list_type m3u8 %(filenameNoExt)s_%(count)s.ts

Working example:

ffmpeg -y -i infile.mp4 -pix_fmt yuv420p -vcodec libx264 -acodec libfaac -r 25 -profile:v baseline -b:v 1500k -maxrate 2000k -force_key_frames 50 -s 640×360 -map 0 -flags -global_header -f segment -segment_list /tmp/index_1500.m3u8 -segment_time 10 -segment_format mpeg_ts -segment_list_type m3u8 /tmp/segment%05d.ts

Here is an example of capturing from the desktop Linux and streaming straight to a local web server configured for low latency:

ffmpeg -f x11grab -s `xdpyinfo | grep ‘dimensions:’|awk ‘{print $2}’` -r 25 -i :0.0 -pix_fmt yuv420p -vcodec libx264 -acodec libfaac -r 25 -profile:v baseline -b:v 1500k -x264opts keyint=25 -s 640×360 -map 0 -flags -global_header -f segment -segment_list index_1500.m3u8 -segment_time 1 -segment_format mpeg_ts -segment_list_type m3u8 -segment_list_flags +live -segment_list_size 2 segment%05d.ts

Tested with:

ffmpeg version N-51554-g1c0d8f2 Copyright (c) 2000-2013 the FFmpeg developers

  built on Apr  7 2013 18:35:14 with llvm-gcc 4.2.1 (LLVM build 2336.11.00)

  configuration: —enable-libx264 —enable-libfaac —enable-nonfree —enable-gpl

  libavutil      52. 24.100 / 52. 24.100

  libavcodec     55.  2.100 / 55.  2.100

  libavformat    55.  1.100 / 55.  1.100

  libavdevice    55.  0.100 / 55.  0.100

  libavfilter     3. 49.100 /  3. 49.100

  libswscale      2.  2.100 /  2.  2.100

  libswresample   0. 17.102 /  0. 17.102

  libpostproc    52.  2.100 / 52.  2.100

Hyper fast Audio and Video encoder

Video Players for Android

Android suffers from not having a good across the board player, especially for HLS. There appear to be a few approaches:

  1. Chance it with the native player
  2. Link through to a VLC variant using Android NDK/JNI
  3. Link through to a ffmpeg variant using Android NDK/JNI
  4. Run a HLS proxy that converts the HLS to RTSP and then sends RTSP to the native player (SOL HLS does this)

NuPlayer

Is this the builtin player for Androidn 4.?

NXP Cinexplayer

http://cinexplayer.com/

Sol HLS Player

Looked promising as it is supposed to just pickup the mime-type and then control the playback but had trouble getting it to pick up the stream.

Note that if you want to like to a live HLS stream use the intent httplive:// works very well and even with a token protected Akamai stream.

After more testing am less convinced on this one as it takes the stream and then does a live transmux from HLS to RTSP and pipes that to the local player. The end result can be quite a lot of pixelisation.

Ooyala Hook

Only works with the Ooyala backend and appears to be based on the VisualOn player. Overall this works quite well and is really easy to integrate if you are on the Ooyala platform.

VisualOn

The VisualOn player has an impressive pedigree with clients such as Netflix on the books. The player will support HLS and MS Smooth Streaming with the Smooth variant also supporting PlayReady DRM (as used by Netflix).

The player is not free however and expect to pay upfront and per device costs for this.

NXPlayer

amffmpeg / amplayer from XBMC Android port

AppTelic

http://www.apptelic.com/

ffmpeg/libav variant

To do this you will need a Linux environment

https://github.com/appunite/AndroidFFmpeg

MoboPlayer

Nexstreaming

Vitamio

Hoperun

http://www.hoperun.com/hoperun/

ffmpeg/libav

DIY Ffmpeg!