Nginx: HLS Video on Demand
Sumber: http://razvantudorica.com/12/hls-video-on-demand-streaming/
First of all, let’s explain shortly what HLS is.
HTTP Live Streaming (also known as HLS) is an HTTP-based media streaming communications protocol implemented by Apple. Since it requires only standard HTTP transactions, HTTP Live Streaming is capable of traversing any firewall or proxy server that lets through standard HTTP traffic, unlike UDP-based protocols such as RTP. This also allows content to be delivered over widely available CDNs. In a few words, HLS works by breaking the overall stream into a sequence of small HTTP-based file downloads. At the start of the streaming session, the client downloads an extended M3U (m3u8) playlist containing the metadata for the various sub-streams (called TS files) which are available. You can read more about HLS Architecture on Apple Developer website.
Currently, there are two main solutions for streaming Adobe RTMP streaming, that we covered in the previous blog post and Apple HLS streaming. However, both technologies allow you to play your video as you record it, automatically adjust video quality to available bandwidth, and seek to different parts of a video. The major differences between the two technologies are, that while Adobe RTMP works only in Flash and requires you to have a dedicated RTMP server installed, Apple HLS works with both Flash and HTML5 and can be used with an ordinary web server. Furthermore, when Apple decided to drop Flash support for iOS (the affected devices are iPhones, iPads, laptops, etc) the developers had to think to a solution for the users of these devices.
The first step in our tutorial it is to compile nginx web server with rtmp modules. We described the necessary steps also in our previous post , but we will mention them again here.
cd ~ mkdir nginx cd nginx # for compiler and git apt-get install git gcc make #for the HTTP rewrite module which requires the PCRE library apt-get install libpcre3-dev # for SSL modules apt-get install libssl-dev git clone https://github.com/arut/nginx-rtmp-module wget http://nginx.org/download/nginx-1.4.3.tar.gz tar zxpvf nginx-1.4.3.tar.gz cd nginx-1.4.3 ./configure --add-module=/root/nginx/nginx-rtmp-module/ --with-http_ssl_module --prefix=/usr/local/nginx-streaming/ make make install
We have to change the default nginx configuration file:
cd /usr/local/nginx-streaming/conf mv nginx.conf nginx.conf.bkp nano nginx.conf
worker_processes 1; events { worker_connections 1024; } http { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { # in case we have another web server on port 80 listen 8080; location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } #where the m3u8 and ts files are alias /var/www/hls; } location / { # here we can put our website root /var/www/html; index index.html index.htm; } } }
We compiled ffmpeg according to this guide. After we finished to compile ffmpeg, we created an executable also for qt-faststart (we will explain later the use of this tool)
cd ~/ffmpeg_sources/ffmpeg/tools make qt-faststart cp qt-faststart $HOME/bin
cd ~/ffmpeg_sources/ffmpeg/tools make qt-faststart cp qt-faststart $HOME/bin
Now, we have all the necessary tools to start streaming… but, we don’t have the files. We are going to use the well known movie of Big Buck Bunny (right click and save the file in /var/www/hls folder on your webserver).
In order to prepare the ts files (media segments) and m3u8 playlist we are going to use ffmpeg. We compiled according with the guide recommended above, and we have ffmpeg executable in $HOME/bin/ffmpeg. You can define in FFMPEG variable the path to your own ffmpeg executable.
cd /var/www/hls FFMPEG=$HOME/bin/ffmpeg #pay attention FILENAME=bbb $FFMPEG -i $FILENAME.mp4 -codec copy -map 0 -f segment -vbsf h264_mp4toannexb -flags -global_header -segment_format mpegts -segment_list $FILENAME.m3u8 -segment_time 10 $FILENAME-%03d.ts
cd /var/www/hls FFMPEG=$HOME/bin/ffmpeg #pay attention FILENAME=bbb $FFMPEG -i $FILENAME.mp4 -codec copy -map 0 -f segment -vbsf h264_mp4toannexb -flags -global_header -segment_format mpegts -segment_list $FILENAME.m3u8 -segment_time 10 $FILENAME-%03d.ts
Unfortunately, the streaming doesn’t work all the time, and we need to re-order the MP4 “atoms”. These atoms are the meta-information about the movie (like the timescale, duration, other characteristics). For fast delivering over the network these meta information should be at the beginning of the file, not at the end. You can read more about atoms in the following article Understanding the MPEG-4 movie atom. To move the atoms at the beginning of the file, we will use qt-faststart tool in this way.
FASTSTART=$HOME/bin/qt-faststart mv bbb.mp4 bbb_original.mp4 input=bbb_original.mp4 $FFMPEG -i $input -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=854:480 -threads 0 -acodec aac -ac 2 -strict experimental -b:a 128k bbb_tmp.mp4 $FASTSTART bbb_tmp.mp4 bbb.mp4
FASTSTART=$HOME/bin/qt-faststart mv bbb.mp4 bbb_original.mp4 input=bbb_original.mp4 $FFMPEG -i $input -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=854:480 -threads 0 -acodec aac -ac 2 -strict experimental -b:a 128k bbb_tmp.mp4 $FASTSTART bbb_tmp.mp4 bbb.mp4
and now let’s execute again the previous command:
$FFMPEG -i bbb.mp4 -codec copy -map 0 -f segment -vbsf h264_mp4toannexb -flags -global_header -segment_format mpegts -segment_list bbb.m3u8 -segment_time 10 bbb-%03d.ts
1
$FFMPEG -i bbb.mp4 -codec copy -map 0 -f segment -vbsf h264_mp4toannexb -flags -global_header -segment_format mpegts -segment_list bbb.m3u8 -segment_time 10 bbb-%03d.ts
Anyway, sometimes (if the video file is broken or not standard), qt-faststart can fail with some side effects (high CPU load). Fortunately, there is a python script that can handle better the move of the atoms.
We can see the result of our work, using a m3u8 player (eg: VLC) and opening the stream from Media->Open Network Stream and in URL field pasting: http://mydomain.com:8080/hls/bbb.m3u8 (replace mydomain.com with your domain name or IP).
Hit the Play button and… the video will start to be played.
If you want to play the movie in the browser, you can read the post about How to play HLS with JW Player.