Linux下使用FFmpeg将RTMP流转换为HLS
Posted 你知道989
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下使用FFmpeg将RTMP流转换为HLS相关的知识,希望对你有一定的参考价值。
Linux下使用FFmpeg将RTMP流转换为HLS
所需资料
- nginx
下载地址 : http://nginx.org/ - nginx-http-flv-module
下载地址 :https://github.com/winshining/nginx-http-flv-module - ffmpeg
- vlc视频播放器(windows安装方便测试)
安装FFmpeg
由于CentOS没有官方FFmpeg rpm软件包。但是,我们可以使用第三方YUM源(Nux Dextop)完成此工作。
sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
安装FFmpeg 和 FFmpeg开发包
sudo yum install ffmpeg ffmpeg-devel -y
测试FFmpeg
ffmpeg -h
配置安装nginx并添加nginx-http-flv-module到nginx中
依次安装系统相关依赖项
yum -y install unzip
yum -y install gcc-c++
yum -y install pcre pcre-devel
yum -y install zlib zlib-devel
yum -y install openssl openssl-devel
将nginx-http-flv-module和nginx上传并解压到/usr/local/nginx中
cd /usr/local/nginx
tar -zxvf nginx-1.8.1.tar.gz
unzip nginx-http-flv-module-1.2.6.zip
进入nginx目录下编译安装nginx
cd nginx-1.8.1
./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx/nginx-http-flv-module
make && make install
prefix为nginx的安装的目录
add-moudle为nginx-http-flv-module的目录
配置Nginx 以实现流转换
配置RTMP
rtmp
server
listen 1935;
application myapp
live on;
application live
live on; #开启实时
hls on; #开启hls
hls_path /usr/local/etc/nginx/html/multimedia/hls; #hls的ts切片存放路径
hls_fragment 2s; #本地切片长度
hls_playlist_length 6s; #HLS播放列表长度
配置HLS拉流
location /live
types
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
alias /usr/local/etc/nginx/html/multimedia/hls/;
add_header Cache-Control no-cache;
完整nginx配置
user nginx;
# 自动分配工作进程数
worker_processes auto;
# 绑定cpu
worker_cpu_affinity auto;
# 指明worker进程的ince值
worker_priority -15;
# 错误日志存放位置
error_log /var/log/nginx/error.log warn;
# pid文件存放位置
pid /var/run/nginx.pid;
events
worker_connections 1024;
accept_mutex on; # 设置单个请求只唤醒一个进程
multi_accept on; # 设置一个工作进程可接收多个新网络连接
rtmp
server
listen 1985;
application myapp
live on;
application live
live on; #开启实时
hls on; #开启hls
hls_path /home/server/hls; #hls的ts切片存放路径
hls_fragment 2s;
hls_playlist_length 6s;
http
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
server_tokens off; #隐藏版本号
client_max_body_size 50m; #调整nginx上传文件限制
keepalive_timeout 65;
#gzip on; 开启压缩
gzip on;
gzip_vary on;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png application/x-protobuf;
server
listen 1997;
server_name localhost;
location /
root html;
index index.html index.htm;
error_page 500 502 503 504 /50x.html;
location = /50x.html
root html;
location /live/
types
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
alias /home/server/hls/;
add_header Cache-Control no-cache;
添加nginx软连接
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
启动nginx
nginx
使用FFmpeg进行转流
测试流地址:
rtmp://media3.scctv.net/live/scctv_800
使用ffmpeg进行转换
ffmpeg -re -i rtmp://media3.scctv.net/live/scctv_800 -c copy -f flv rtmp://127.0.0.1:1997/live/test
第一行的地址为测试地址
第二个地址为nginx中配置的rtmp中的live
第二个地址的IP需更改为nginx的服务器IP , 端口为rtmp中配置的端口
test部分为自定义 , 是hls文件夹下的.m3u8和切片的名称
测试拉流
使用vlc在windows中测试
拉流地址为 :
http://127.0.0.1:1997/live/test.m3u8
此处的test和ffmpeg转换的第二个地址末尾的test相对应
FFmpeg命令读取RTMP流如何设置超时时间
子标题:FFmpeg命令录制RTMP流为FLV文件时如何设置超时时间 | FFmpeg命令如何解决录制产生阻塞的问题
0x001: 前言
今天在测试程序时遇到两个问题。
Q1:ffmpeg录制RTMP流并保存为FLV文件时,推RTMP流的线程已经结束断掉了,而录制的线程却还一直在录。
Q2:ffmpeg录制RTMP流并保存为FLV文件时,被录制的RTMP流并未推流或并无此房间频道,而录制的线程却还一直在录。
观察日志文件发现录制程序一直阻塞在某个时间点上,经查验这是因为ffmpeg在拉取RTMP流时只要流媒体服务器能正常访问,不管当前拉取的流是否能正常访问都不会退出。
举个例子:rtmp://192.168.1.100:1935/live/changfang,只要192.168.1.100:1935这个服务器地址是能正常请求通的,不管当前changfang频道有没有在推流,ffmpeg都会阻塞至此。当你把整个服务器down掉,你会发现ffmpeg录制的程序会立马退出不再阻塞。此时第一个想法就是寻找设置超时的命令参数。
0x002: 解决方案
遇到问题就找找有没有前人也遇到类似情况,找了一遍基本是C++代码如何解决的问题,没有ffmpeg命令相关的结果。于是查看命令帮助,寻找timeout字眼,找了很多参数,经多次尝试发现有个 -rw_timeout
这是官方描述: -rw_timeout <int64> ED....... Timeout for IO operations (in microseconds) (from 0 to I64_MAX) (default 0)
读取流也属于IO操作,但此处要注意两点:1.参数单位是微秒,而不是秒。1秒(s)=1000000微秒(μs) 2.参数要放在开流前,否则不会生效
更改前的命令(为了便于分析观看,只留最基础的命令):
ffmpeg -i rtmp://192.168.1.100:1935/live/changfang -c copy -f flv /opt/video/123.flv
更改后的命令:
ffmpeg -rw_timeout 5000000 -i rtmp://192.168.1.100:1935/live/changfang -c copy -f flv /opt/video/123.flv
这样,不管是推流结束还是从未推过流,只要ffmpeg在开流时,IO操作超过设置的秒数,就会自动退出。(如果你读取的流是外网流或内网流不太通畅的情况下,不建议你把此时间设置过短,因为ffmpeg在录制时从开流到产生FLV录制文件也需要时间)
0x003: 完结
如果你正好遇到此问题,希望能帮到你!
以上是关于Linux下使用FFmpeg将RTMP流转换为HLS的主要内容,如果未能解决你的问题,请参考以下文章