平台选择
目前流行的流媒体服务协议主要有:RTSP/RTMP/MMS/HLS,现在还有Adobe推的HDS和微软推的SmoothStreaming。
由于HLS是苹果提出的,目前各大视频网站都提供此格式的支持。
RTSP(Real Time Streaming Protocol)
rtsp 是android native支持的。
RTMP(Real Time Messaging Protocol)
实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议。
MMS(Microsoft Media Server Protocol)
“微软媒体服务器协议”,用来访问并流式接收 Windows Media 服务器中 .asf 文件的一种协议。MMS 协议用于访问 Windows Media 发布点上的单播内容。MMS 是连接 Windows Media 单播服务的默认方法。若观众在 Windows Media Player 中键入一个 URL 以连接内容,而不是通过超级链接访问内容,则他们必须使用MMS 协议引用该流。MMS的预设埠(端口)是1755
HLS(HTTP Live Streaming)
苹果公司实现的基于HTTP的流媒体传输协议,可实现流媒体的直播和点播。Android4.0以上已开始原生支持HLS。
HLS相比使用 RTSP 协议的好处在于,一旦切分完成,之后的分发过程完全不需要额外使用任何专门软件,普通的网络服务器即可,大大降低了 CDN 边缘服务器的配置要求,可以使用任何现成的 CDN。分发使用的协议是最常见 HTTP,代理服务器对这个协议的缓存优化相当成熟,而很少有代理服务器对 RTSP 的进行缓存优化。这对播放(软)实时视频有相当大的优势,因为这样分发后,对源服务器的负载压力小得多。
对于非实时视频,同样的好处也是存在的:如果你要在一段长达一小时的视频中跳转,如果使用单个 MP4 格式的视频文件,并且也是用 HTTP 协议,那么需要代理服务器支持 HTTP range request 以获取大文件中的一部分。不是所有的代理服务器都对此有良好的支持。而 HTTP Live Streaming 则只需要根据列表文件中的时间轴找出对应的 TS 片段下载即可,不需要 range request,对代理服务器的要求小很多。所有代理服务器都支持小文件的高效缓存。
此外,HTTP Live Streaming 还有一个巨大优势:自适应码率流播(adaptive streaming)。效果就是客户端会根据网络状况自动选择不同码率的视频流,条件允许的情况下使用高码率,网络繁忙的时候使用低码率,并且自动在二者间随意切换。这对移动设备网络状况不稳定的情况下保障流畅播放非常有帮助。实现方法是服务器端提供多码率视频流,并且在列表文件中注明,播放器根据播放进度和下载速度自动调整。
总上我们选择了HLS平台作为流媒体服务平台。
HLS平台概述
一个典型的HTTP Live Streaming流媒体系统由内容准备(流媒体服务)、内容分发(分发服务器)和客户端软件三部分组成.
内容准备服务
内容准备服务(流媒体服务器)负责将输入的音视频媒体内容转换成为适合于内容分发服务进行传输的格式。对于视频源获取的或者上传的视利用视频编码器转化为MPEG-2系统层标准的传输流(TS)格式进行输出。流分割器负责将编码器输出的MPEG-2 TS流分割为一系列连续的、长度均等的小TS文件(后缀名为.ts),并依次发送至内容分发组件中的Web服务器进行存储。与此同时,流分割器还需创建一个含有指向这些小TS文件指针的索引文件(后缀为m3u8),同样放置于Web服务器之中进行存储。流分割器还可以对其生成的每个小TS文件进行加密,并生成相应的密钥文件。
之所以采用MPEG-2 TS格式来对编码后的媒体流进行统一封装,是因为它能够将音视频媒体流严格按时序进行交织复用,任意截取和分段后,每一个分段都可能不依赖于之前的分段而独立进行解码和播放
内容分发服务
内容分发服务(分发服务器)用于通过HTTP协议将分割后的小媒体文件及其索引文件递送至客户端播放器,可以采用一个普通的Web服务器(nginx,Apache)来实现。
客户端
对于苹果设备均支持m3u8文件的播放(iphone,ipad, mac os)。
对于支持flash的设备均支持StrobeMediaPlayback播放(pc)。
对于浏览器支持html5的浏览器均支持html5方式的播放(苹果设备,pc, android)。
HLS平台搭建
技术选型
编码器采用ffmpeg,最新的ffmpeg已经支持流切片,貌似可以省去segmenter了;)。
流切片采用Segmenter,
web服务器采用nginx-rtmp-module
安装ffmpeg
下载FFmpeg和libx264的包 ffmpeg-2.4.1.tar.bz2 last_x264.tar.bz2 libx264需要yasm,所以先安装yasm apt-get install yasm 然后安装libx264 aptitude install libx264-dev 也可以手动安装libx264(原先libx264在ubuntu的软件源里是没有的只能手动安装,现在有了就可以不用手动安装了) 解压缩libx264 tar -xjvf last_x264.tar.bz2 安装libx264 ./configure --enable-shared --enable-pic make make install 然后安装ffmpeg,ffmpeg有许多依赖包,需要一个一个先安装 1. libfaac aptitude install libfaac-dev 2. libmp3lame aptitude install libmp3lame-dev 3. libtheora aptitude install libtheora-dev 4. libvorbis aptitude install libvorbis-dev 5. libxvid aptitude install libxvidcore-dev 6. libxext aptitude install libxext-dev 7. libxfixes aptitude install libxfixes-dev 依赖包安装完后,安装ffmpeg 先解压缩ffmpeg tar -xjvf ffmpeg-2.4.1.tar.bz2 然后编译安装 ./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-pthreads --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab --enable-libvorbis make make install 生成hls分片: ffmpeg -i <媒体文件> -c:v libx264 -c:a aac -strict -2 -f hls 20140701111639.m3u8
安装nginx
1.下载http://nginx.org/<br> nginx默认需要的是pcre和zlib和openssl,分别去这两个官方网站下载最新的版本<br> 执行 ./configure --prefix=/usr/local/nginx --with-pcre=/home/user/pcre/pcre-8.32 --with-zlib=/home/user/zlib/zlib-1.2.8 --with-openssl=/home/user/openssl/openssl-1.0.1i --add-module=/home/user/nginx-rtmp-module 然后就是执行make和make install,如果没有报错的话nginx就安装完成了。
nginx常用命令
启动: nginx -c表示configuration,指定配置文件。 -t检查配置文件 -h帮助 重启: nginx -s reload service nginx reload -s都是采用向 Nginx 发送信号的方式。 退出: nginx -s stop或者nginx -s quit nginx停止命令stop与quit参数的区别在于stop是快速停止nginx,可能并不保存相关信息,quit是完整有序的停止nginx,并保存相关信息。
配置nginx
rtmp { server { listen 1935; chunk_size 4000; #HLS # For HLS to work please create a directory in tmpfs (/tmp/app here) # for the fragments. The directory contents is served via HTTP (see # http{} section in config) # # Incoming stream must be in H264/AAC. For iPhones use baseline H264 # profile (see ffmpeg example). # This example creates RTMP stream from movie ready for HLS: # # ffmpeg -loglevel verbose -re -i movie.avi -vcodec libx264 # -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 # -f flv rtmp://localhost:1935/hls/movie # # If you need to transcode live stream use 'exec' feature. # application hls { live on; hls on; hls_path /tmp/app; hls_fragment 5s; } } } http { server { listen 80; location /hls { # Serve HLS fragments types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /tmp/app; expires -1; } } }
配置nginx自启动
http://my.oschina.net/yearnfar/blog/284862
update-rc.d命令,是用来自动的升级System V类型初始化脚本,简单的讲就是,哪些东西是你想要系统在引导初始化的时候运行的,哪些是希望在关机或重启时停止的,可以用它来帮你设置。 首先 我们需要在 /etc/init.d/目录下创建一个nginx的脚本文件,命令 vi nginx 输入以下内容 #! /bin/sh # Author: rui ding # Modified: Geoffrey Grosenbach http://www.linuxidc.com # Modified: Clement NEDELCU # Reproduced with express authorization from its contributors set -e PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DESC="nginx daemon" NAME=nginx DAEMON=/usr/local/nginx/sbin/$NAME SCRIPTNAME=/etc/init.d/$NAME # If the daemon file is not found, terminate the script. test -x $DAEMON || exit 0 d_start() { $DAEMON || echo -n " already running" } d_stop() { $DAEMON –s quit || echo -n " not running" } d_reload() { $DAEMON –s reload || echo -n " could not reload" } case "$1" in start) echo -n "Starting $DESC: $NAME" d_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" d_stop echo "." ;; reload) echo -n "Reloading $DESC configuration..." d_reload echo "reloaded." ;; restart) echo -n "Restarting $DESC: $NAME" d_stop # Sleep for two seconds before starting again, this should give the # Nginx daemon some time to perform a graceful stop. sleep 2 d_start echo "." ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2 exit 3 ;; esac exit 0 然后输入 以下命令 [root@example.com ~]# update-rc.d –f nginx defaults 好了 从新启动看看NGINX启动了没 如果要取消开机启动可以这样 update-rc.d -f nginx remove 补充资料: /etc/init.d/里存放了所有的启动脚本,我们平时可以通过/etc/init.d/脚本名 启动模式 来启动某个应用。 例如输入命令“/etc/init.d/smb start”来启动smb服务。 如果是在RedHat系统下,还可以通过service smb start来启动某个服务。 尽管/etc/init.d目录中的脚本可以启动和停止各个服务,但在系统引导时,init并不是直接在/etc/init.d目录下找各个服务的启动脚本,而是在/etc/rc.d/目录下查找,该目录包含rc0.d、rc1.d等分别代表不同的init启动级别的子目录。 你可以用Runlevel命令查看当前你的系统是在那个运行级 #Runlevel N 2 注:我当前的系统是2级 接着来看看这些rcx.d的目录下所包含的内容,内容全是一些符号链接,链接到上一级init目录中的脚本上。 这些符号链接名称都以S或K开头,后面跟一个数字以及该脚本所控制的服务名,例如S10network。 当init从低的运行级向高的运行级过渡时,它按照数字递增的顺序运行所有以S开头的脚本,S=start,即启动脚本对应的服务;K=kill,即杀死脚本对应服务。 前面介绍到rcx.d目录下指向启动脚本的符号链接是由K或S+数字+服务名 所组成,中间这个数字十分重要,系统启动时按照这个数字递增执行所有S开头的脚本,系统关闭时按照这个数字递减执行所有K开头的脚本。 如何自定义符号链接? 启动脚本: 因为我刚才的运行级是2级 所以在/etc/rc.d/rc2.d 目录下运行 #ln -s /etc/init.d/nginx S99nginx //重新定义nginx服务的脚本启动顺序
安装php
下载编译
./configure --prefix=/usr/local/php \ --with-mysql=/usr/local/mysql \#设置mysql的安装路径 --enable-fastcgi \ #开启fastcgi支持 --enable-debug #支持调试 make make install
修改配置
利用ffmpeg生成缩略图命令:
exec("ffmpeg -i 2.wmv -ss 3 -vframes 1 -r 1 -ac 1 -ab 2 -s 160*120 -f image2 2.jpg");
安装mysql
编译
1.安装 cmake sudo apt-get install build-essential sudo apt-get install libncurses5-dev sudo apt-get install sysv-rc-conf sudo apt-get install cmake 2.创建mysql用户 sudo groupadd mysql sudo useradd -r -g mysql mysql 3.编译 cmake . \ -DCMAKE_INSTALL_PREFIX=/usr/mysql \ -DMYSQL_DATADIR=/usr/mysql/data \ -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci \ -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \ -DWITH_DEBUG=0 \ -DWITH_INNOBASE_STORAGE_ENGINE=1 $ make -j 8 //8核并行编译 $ make install sudo chown -R mysql . chgrp -R mysql . sudo bin/scripts/mysql_install_db \ --user=mysql \ --basedir=/usr/mysql \ --datadir=/usr/mysql/data \ --no-defaults 4.配置 sudo cp /usr/mysql/support-files/my-medium.cnf /etc/mysql/my.cnf /*这步骤可以省略、默认会存在一个*/ # chown -R mysql:mysql /etc/my.cnf 5.修改配置文件、配置数据文件、日志文件的路径 # su - mysql $ cd mysql $ mkdir run log tmp $ vim /etc/my.cnf **新增内容如下-- basedir = /home/mysql/mysql datadir = /home/mysql/mysql/data socket = /home/mysql/mysql/run/mysql.sock /*Server和client的socket配置都要相同*/ log-error = /home/mysql/mysql/log/alert.log log_slow_queries = /home/mysql/mysql/log/slow.log 注意可能为: slow_query_log_file = /home/mysql/mysql/log/slow.log slow_query_log = 1 6.初始化 MySQL 配置表 $ ./scripts/mysql_install_db --basedir=/home/mysql/mysql --datadir=/home/mysql/mysql/data --user=mysql --force 7.启动 ./bin/mysqld_safe & / 通常我们是通过脚本传入适当的参数启动mysqld。因此在/etc/mysql/my.cnf中加入如下的内容: 引用: [mysqld] basedir=/usr/mysql datadir=/usr/mysql/data user=mysql pid-file = /usr/mysql/mysql.pid
如果是后安装的mysql需要配置php添加mysql扩展。
添加扩展的基本步骤:
1、进入php源代码目录:# cd /usr/ChenShao/php-5.3.1/ 2、再进入要添加的mysql扩展源码目录:# cd ext/mysql/ 2、调用已经编译好的php里面的phpize:# /usr/local/php5/bin/phpize 3、然后configure:# ./configure --with-php-config=/usr/local/php5/bin/php-config --with-mysql=/usr/local/mysql (/usr/local/mysql 为mysql的安装目录) 4、make && make install 5、编译之后,自动把mysql.so放到了默认的php扩展目录下(phpinfo可查看,我的为 /usr/local/php5/lib/php/extensions/no-debug-zts-20090626),再修改php.ini,去掉;extension=php_mysql.so前面的分号。 不过有一点需要注意的是,生成的模块名叫mysql.so,跟php.ini里面的php_mysql.so名字不一致,必须把mysql.so改名为php_mysql.so,切记切记~!
配置mysqli
据说mysqli插件比mysql插件效率更高。 因为mysqli的长连接。
在linux中解决办法稍加复杂一点,因为都是命令模式了 代码如下 复制代码 cd php-5.2.8 //在这下面有个ext文件夹里有mysqli cd ext/mysqli linux下将源码文件编译应该都有configure吧,可这里没有,在我们已经安装php后,php5这个文件夹里的命令目录bin里有一个文件叫phpize,用它就可以生成configure文件啦,继续 代码如下 复制代码 /usr/local/php5/bin/phpize //这里回车运行,执行完后就出了configure文件, ./configure –prefix=/usr/local/mysqli –with-php-config=/usr/local/php5/bin/php-config –with-mysqli=/usr/local/mysql/bin/mysql_config 直接回车,不出问题就继续。。 代码如下 复制代码 make make test make install //(不出错就会显示Installing shared extensions: /usr/local/php5/lib/php/extensions/no-debug-non-zts-20041030/) 现在mysqli.so文件就出来啦。。 直接在php.ini里把这个文件加载就OK啦。。 代码如下 复制代码 extension_dir=”/usr/local/php5/ext” extension=mysqli.so 把上面第一行找到修改成这个,然后再把第二行加入。。wq保存退出。 把mysqli.so这个文件cp到/usr/local/php5/ext下
web前端开发
http://www.51zxw.net/list.aspx?cid=393
参考资料
https://github.com/johnf/m3u8-segmenter
https://developer.apple.com/streaming/
Nginx RTMP 功能研究:
http://blog.youkuaiyun.com/cccallen/article/details/8440191/
nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器:
http://redstarofsleep.iteye.com/blog/2123752
https://github.com/arut/nginx-rtmp-module.git