http://blog.csdn.net/cjsafty/article/details/7922849
简介:HTTP Live Streaming(缩写是 HLS)是一个由苹果公司提出的基于HTTP的流媒体 网络传输协议。
是苹果公司QuickTime X和iPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP
的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速
率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包
含元数据的extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。
HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防
火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。
此协议详细内容请参考apple官方网站:https://developer.apple.com/resources/http-streaming/
有两种方式搭建HLSserver,
一种是利用apple SDK,
一种是利用adobe 的fms,4.5版本支持hls,参考,
adobe的fms现在很强大,但是商用需要licence。有兴趣的可以研究下。
一种是利用opensouce.我比较喜欢这一种。
方法:
opensource的方法主要是使用m3u8-segmenter+ffmpeg对ts文件进行分片。
因此思路就是:
1,用编译好的ffmpeg制作所需要的ts文件,
2,安装libavformat-dev版本,
3,编译m3u8-segmenter,
4,部署到nginx
5,高级功能,流切换
6,页面
过程
1,本来想下载ffmpeg源码编译,但是因为要涉及到faac,x264,lame库。有时候ffmpeg版本对这些库的版本又有最低版本要求,在编译
faac时候遇到以下问题
- 安装支持库
- apt-get install automake autoconf m4 libtool
- -bash: ./bootstrap: /bin/sh^M: bad interpreter: No such file or directory
- 转换字符:
- dos2unix bootstrap
- make
- 错误:mpeg4ip.h:126:58: error: new declaration ‘char* strcasestr(const char*, const char*)’
- 解决方法:Remove line 126 containing strcasecmp from mpeg4ip.h as a temporary workaround
- make install时遇到
- usr/local/share/man/man1文件夹无法创建问题。
最后一个问题无法解决,好像是Linux(ubuntu)下同一个目录下,如果已经有一个文件了,则不能创建同名文件夹,遂放弃编译,
直接从ffmpeg网站:http://ffmpeg.org/download.html ,的linux下载页面下载编译好ffmpeg静态文件。这个静态文件的主要目的是
为了把各种文件转换成apple所规定的文件。所以需要AAC,mp3,x264库支持。
或者干脆按照2的方法。apt-get install ffmpeg.这样会得到ffmpeg可行性文件。
2,安装ffmpeg支持库,主要用于编译m3u8-segmenter,这里的ffmpeg支持库,其目的是给segmenter提供libavformat支持。不涉及编解码。
apt-get install libavformat-dev.
- Reading package lists... Done
- Building dependency tree
- Reading state information... Done
- The following extra packages will be installed:
- libavcodec-dev libavcodec53 libavformat53 libavutil-dev libavutil51 libgsm1 libogg0 liborc-0.4-0
- libschroedinger-1.0-0 libspeex1 libtheora0 libva1 libvorbis0a libvorbisenc2 libvpx1
- Suggested packages:
- libfaad-dev libgsm1-dev libogg-dev libschroedinger-dev libspeex-dev libtheora-dev libvorbis-dev libx11-dev
- libxext-dev libraw1394-dev libdc1394-22-dev speex
- The following NEW packages will be installed:
- libavcodec-dev libavcodec53 libavformat-dev libavformat53 libavutil-dev libavutil51 libgsm1 libogg0 liborc-0.4-0
- libschroedinger-1.0-0 libspeex1 libtheora0 libva1 libvorbis0a libvorbisenc2 libvpx1
这样会自动安装ffmepg几个相关库。
3,从https://github.com/johnf/m3u8-segmenter 下载m3u8-segmenter
下载后不要用它的反复编译,直接取m3u8-segmenter.c文件,
- gcc -Wall -g segmenter.c -o segmenter -lavformat
从源码来看,因为只用到了avformat库,所以只链接这一个即可。生成segmenter文件,用help命令,可以看到已经成功。
- HTTP Live Streaming - Segments TS file and creates M3U8 index.
- -i, --input FILE TS file to segment (Use - for stdin)
- -d, --duration SECONDS Duration of each segment (default: 10 seconds)
- -p, --output-prefix PREFIX Prefix for the TS segments, will be appended
- with -1.ts, -2.ts etc
- -m, --m3u8-file FILE M3U8 output filename
- -u, --url-prefix PREFIX Prefix for web address of segments, e.g. http://example.org/video/
- -n, --num-segment NUMBER Number of segments to keep on disk
- -h, --help This help
从上图来看,语法很简单,这里贴一个我用的。
- ./segmenter -i test.ts -n 30 -p sample_test -m stream-test.m3u8 -u http://192.168.1.10:8080/hls/
i表示输入文件,n表示切割30个,p表示切割文件的前缀。m表示生成的m3u8文件名,u表示这些切割后的文件处于web server的哪个目录下,这个一定要和web目录匹配
4,部署到nginx。
nginx的相关部署我在前两个博客中已经详细说明,这里在jwplayer博客的基础上部署hls。
1)目录问题:
在html/jwplayer目录下,建立hls文件夹,将m3u8文件和切割后的全部ts文件拷贝到此目录下,
在VLC PLAYER或者ipad safie浏览器或者在ffplayer(我用的是0.11版本的windows编译版本)
上的访问路径应该是http://192.168.1.10:8080/hls/stream-test.m3u8
2)文件类型问题:编辑 /usr/local/nginx/conf/mime.types 文件,添加如下类型
- application/x-mpegURL m3u8;
- video/MP2T ts;
输入上述路径,你应该就看到视频了。
5,高级功能,流切换
上述m3u8文件,只有一个流,不具备流切换功能。在优酷上,如果是ipad客户端,可以看到有标清,高清,超清的按钮,其实那个是对应着不同标准
的(单个)m3u8文件,来实现流切换的,不知道apple是不是这样做的,apple好像是要求“智能”流切换。即不要求用户去选择,而是根据网络状况自适应的。
apple给的sample的流切换是把各个流的m3u8写在一个m3u8文件里实现的。
类似于这样,其实原理是一样的。
- #EXTM3U
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=100000
- video1/index1.m3u8
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000
- video2/index2.m3u8
6,页面,
如果再继续搭建一个页面,把上述地址嵌在页面里面,这样配合CSS就比较美观了。页面可以在这个基础上,用webpy去做。
页面参考:
苹果开发网:https://developer.apple.com/resources/http-streaming/
博客:http://www.nginxs.com/linux/459.html
ffmpeg开发网:http://ffmpeg.org/download.html
segmenter源码:https://github.com/johnf/m3u8-segmenter
2014.02备注:
文中所描述的切片软件可能有问题,可选择这个
https://code.google.com/p/httpsegmenter/downloads/list
说明:在写这篇文章时不知道查了多少资料不是资料不完整就是根本不能安装,网上许多资料都是转载。写这篇文章时我亲自做了测试,安装完全通过,如果有什么不对的地方欢迎拍砖
一、安装ffmpeg
操作系统:centos 5.6
(一)安装编译环境
#yum install -y automake autoconf libtool gcc gcc-c++
(二)安装所需程序库的RPM包到 centos(因为centos自带的库中没有ffmpeg包,这里相当于是扩展)
view plaincopy to clipboardprint?
#rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
如果上面的代码执行失败,你可以在本站下载,然后安装这个rpm包。
(三)安装 Install ffmpeg 等模块
yum -y install ffmpeg ffmpeg-devel
CentOS yum方式安装ffmpeg
系统为CentOS 6.4,自己编译ffmpeg和众多解码器太痛苦了,yum方式安装ffmpeg的解码器很全,先用用看。
1、安装所需软件
yum install -y automake autoconf libtool gcc gcc-c++
2、安装第三方更新源
rpm -ivh http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/rpmforge-release-0.5.3-1.el6.rf.i686.rpm
3、安装ffmpeg
yum install ffmpeg ffmpeg-devel
会自动安装众多解码器,ffmpeg版本为0.6.5-1.el6.rf。看了下yum安装的解码器版本还不是很旧,但是ffmpeg版本较老。
4、测试一下
将一个.avi视屏转为.flv格式
ffmpeg -i Destination.avi -y -ab 56 -ar 22050 -r 15 -sameq test2.flv
转换前后两个文件的格式比较:
Destination.avi
General
Complete name : E:\PV\Destination.avi
Format : AVI
Format/Info : Audio Video Interleave
Format/Family : RIFF
File size : 79.5 MiB
PlayTime : 4mn 1s
Bit rate : 2754 Kbps
StreamSize : 469 KiB
Subject : doobie (2007)
Writing application : VirtualDubMod 1.5.10.2 (build 2540/release)
Writing library : VirtualDubMod build 2540/release
Video #0
Codec : XviD
Codec/Family : MPEG-4
Codec/Info : XviD project
Codec profile : Streaming Video Profile/Level 1
Codec settings/PacketBitStream : Yes
Codec settings/BVOP : Yes
Codec settings/QPel : No
Codec settings/GMC : 0
Codec settings/Matrix : Default
PlayTime : 4mn 1s
Bit rate : 2556 Kbps
Width : 640 pixels
Height : 480 pixels
Display Aspect ratio : 4/3
Frame rate : 29.976 fps
Resolution : 8 bits
Chroma : 4:2:0
Interlacement : Progressive
Bits/(Pixel*Frame) : 0.277
StreamSize : 73.5 MiB
Audio #1
Codec : MPEG-1 Audio layer 3
Codec profile : Joint stereo
PlayTime : 4mn 1s
Bit rate : 190 Kbps
Bit rate mode : CBR
Channel(s) : 2 channels
Sampling rate : 48 KHz
Resolution : 16 bits
StreamSize : 5.47 MiB
Writing library : Gogo (after 3.0)
转换后
test2.flv
General
Complete name : E:\PV\test2.flv
Format : Flash Video
File size : 45.0 MiB
PlayTime : 4mn 1s
Bit rate : 1564 Kbps
Video
Codec : Sorenson H263
PlayTime : 4mn 1s
Bit rate : 195 Kbps
Width : 640 pixels
Height : 480 pixels
Display Aspect ratio : 4/3
Frame rate : 15.000 fps
Bits/(Pixel*Frame) : 0.042
Audio
Codec : MPEG-1 Audio Layer 3
Bit rate : 55 bps
Channel(s) : 2 channels
Sampling rate : 22 KHz
Resolution : 16 bits
参考资料:
http://www.rosoo.net/a/201205/16001.html
-
CentOS编译安装ffmpeg以及相关编码解码器
CentOS编译安装ffmpeg是一件很痛苦的过程,因为各种编码器、解码器什么的很繁杂,而且相互依赖关系更复杂。
编译了一天终于把它搞定并基本测试无问题,以下是步骤。
安装yasm
安装frei0r(先安装新版autoconf,这会覆盖掉系统中的旧版本哦)
安装gnutls
参考:http://blog.creke.net/800.html
安装mp3lame
安装opencore-amr
安装opus
安装rtmpdump
安装schroedinger(先安装好orc库)
安装soxr(注:新版libsoxr貌似与当前ffmpeg不兼容,用旧版)
安装speex(先安装libogg库)
安装theora(先安装好libvorbis库和libsdl库)
安装twolame
安装VisualOn AAC(注:github的tag和master版均无法autoconf,用zeranoe版代替)
安装VisualOn AMR-WB(注:github的tag和master版均无法autoconf,用zeranoe版代替)
安装libvpx(注:新版libvpx貌似与当前ffmpeg不兼容,用旧版)
安装x264
安装xvid
最重要的一步——编译安装ffmpeg!
注1:
我在编译安装时参考Windows Build:http://ffmpeg.zeranoe.com/builds/。
注2:
与Windows Build相比,以下没有选项开启:
http://www.cnblogs.com/mystory/archive/2013/04/07/3006200.html
linux下搭建生成HLS所需的.ts和.m3u8文件
要想利用HLS来实现视频的在线播放,就得需要将一个完整的视频文件切割成多个ts视频流,然后利用m3u8的索引文件来播放。
在Mac下,苹果提供了streamingTools的工具,里面有mediafilesegmenter和mediastreamsegmenter来分别实现文件和直播流的切割,一行命令直接就可以将输入的原始视频文件导出成几个ts和索引文件,直接就可以用了。但是一般服务器都是基于linux的,要想在linux下实现同样的切割,着实费了一番功夫。
网上也找了好多相关的资料,基本是利用开源的ffmpeg和segmenter工具来实现,但是这搭建这个环境的过程是曲折的,编译这些工具的时候会出现好多错误,难以解决,好多文章的步骤介绍的也很复杂,又要安装各种包,又要修改源代码,经过几天的各种反复尝试,才知道在不是直接将源文件切割,而是先要转换一下,再切割,最终终于痛苦的摸索到了一个成功的路子,特此记录下来以防忘记。
1、首先获得ffmpeg
apt-get install ffmpeg
2、安装ffmpeg支持库,为m3u8-segmenter准备
apt-get install libavformat-dev
3、获得m3u8-segmenter
https://github.com/johnf/m3u8-segmenter
4、编译并安装m3u8-segmenter
aclocal
automake -ac
./configure
make
sudo make install
4、编译其中的文件m3u8-segmenter
gcc -Wall -g m3u8-segmenter.c -o segmenter -lavformat
5、利用ffmpeg将已有的视频文件转换成ts文件
ffmpeg -y -i <in file> -vcodec copy -acodec copy -vbsf h264_mp4toannexb <output file>
其中in file为待转换的视频文件,比如input.mov,output file为转换后的文件,要命名为output.ts
6、利用segmenter将转换好的ts文件切割成多个ts片,并生成.m3u8的索引文件
./segmenter -i out.ts -n 10 -p segmenter_test -m test.m3u8 -u
i表示输入文件,n表示切割10秒,p表示切割文件的前缀。m表示生成的m3u8文件名,u表示这些切割后的文件处于web server的哪个目录下
PS:实践过程中发现一个问题,就是切片之后,最后一段ts不管是不是10s,同样会按10s去切,导致切好后的视频最后一段会加上去几秒的黑段来补足10s,原因是segmenter.c中的程序写的还有缺陷,修正方法如下:
https://github.com/johnf/m3u8-segmenter/pull/10/files
参考:
http://blog.chinaunix.net/uid-25530360-id-3483535.html
http://shappy1978.iteye.com/blog/1071815
http://hi.baidu.com/lphack/item/83865611c5f82c8988a956df
http://blog.cnrainbird.com/index.php/2012/03/25/ping_guo_http_shi_pin_dian_bo_ji_shu/
最近研究hls,发现需要使用m3u8_segmenter这个程序,搞了半天才编译通过,特此记录一下。
使用正常的./configure等编译老是出错误
gcc -Wall -g m3u8-segmenter.c -o segmenter -lavformat -lavcodec -lavutilm3u8-segmenter.c: In function ‘add_output_stream’:
m3u8-segmenter.c:58: warning: implicit declaration of function ‘avformat_new_stream’
m3u8-segmenter.c:58: warning: assignment makes pointer from integer without a cast
m3u8-segmenter.c: In function ‘main’:
m3u8-segmenter.c:343: warning: implicit declaration of function ‘avformat_find_stream_info’
m3u8-segmenter.c:380: error: ‘AVFMT_FLAG_IGNDTS’ undeclared (first use in this function)
m3u8-segmenter.c:380: error: (Each undeclared identifier is reported only once
m3u8-segmenter.c:380: error: for each function it appears in.)
m3u8-segmenter.c:390: warning: implicit declaration of function ‘avcodec_open2’
m3u8-segmenter.c:397: error: ‘AVIO_FLAG_WRITE’ undeclared (first use in this function)
在网上查资料,特别是参考xjd_1985的文章,m3u8-segmenter工程编译和使用
./configure FFMPEG_CFLAGS=-I../ffmpeg-2.1.1 FFMPEG_LIBS='-L ../ffmpeg-2.1.1/libavformat -L../ffmpeg-2.1.1/libavcodec -L../ffmpeg-2.1.1/libavutil -pthread -lavformat -lavcodec -lavutil -lm -lz'
ffmpeg-2.1.1是我使用ffmpeg的版本和目录
然后再make就通过了。