本文旨在在Windows 7系统上实现利用FFmpeg软件推流到部署的带RTMP模块的Nginx流媒体服务器上,在拉流端,基于VLC库的VLC-QT库实现拉流播放。
ffmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序,可以轻易实现多种视频格式之间的相互转换。作为开源免费软件,通过其官网可以下载。地址:https://ffmpeg.org/。对应GitHub地址:https://github.com/FFmpeg/FFmpeg。本应用中采用下载官方提供的库,无需使用GitHub提供的源码自己编译。
点击“Download”,在跳转的下载页面,点击Win10图标,选择“Windows builds from gyan.dev”(下面一个链接是GitHub对应页面)。
在跳转到页面中,可以下载essential和full版本,essential就是简版,只包含ffmpeg.exe、ffplay.exe、ffprobe.exe, 而full版本就包含了动态库和相关头文件,方便我们在开发中调用。点击“full-release-full-shared.7z”,下载。
解压后目录如下:
将bin目录的全路径添加到环境变量PATH。
cmd命令行到bin目录下(如已添加到PATH环境变量则无需),输入ffmpeg –version。出现下图则成功。
bin目录下文件:
可执行文件:
SDK动态库:
前提条件:各级目录不能用中文。
Nginx服务默认安装包不带RTMP模块,其地址:http://nginx.org/en/download.html。页面如下。
NGINX服务视频推流版地址:http://nginx-win.ecsds.eu/download/。页面如下。
下载其中的nginx 1.7.11.3 Gryphon.zip。
还需要下载nginx的rtmp模块nginx-rtmp-module,地址:https://github.com/arut/nginx-rtmp-module。[有RTMP配置文件详细配置,建议仔细阅读]。文件:nginx-rtmp-module-master.zip。
解压nginx 1.7.11.3 Gryphon.zip,解压nginx-rtmp-module-master.zip,并将其剪切到nginx 1.7.11.3 Gryphon目录下。
参考\nginx-rtmp-module-master\test\nginx.conf,改写 nginx 1.7.11.3 Gryphon\conf\nginx-win.conf,作为其启动配置文件(包含RTMP配置)。内容如下:
#user nobody;
# multiple workers works !
worker_processes 2; #Nginx进程数,建议设置为等于CPU总核数
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 8192; #工作模式与连接数上限
# max value 32768, nginx recycling connections+registry optimization =
# this.value * 20 = max concurrent connections currently tested with one worker
# C1000K should be possible depending there is enough ram/cpu power
# multi_accept on;
}
#RTMP服务
rtmp {
server {
listen 1935; #推流监听端口,可以更改
chunk_size 4000; #传输文件块的大小
application live { #创建名为live的应用
live on; #开启live应用
allow publish 127.0.0.1;#
allow play all;
}
}
}
http {
#include /nginx/conf/naxsi_core.rules;
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# # loadbalancing PHP
# upstream myLoadBalancer {
# server 127.0.0.1:9001 weight=1 fail_timeout=5;
# server 127.0.0.1:9002 weight=1 fail_timeout=5;
# server 127.0.0.1:9003 weight=1 fail_timeout=5;
# server 127.0.0.1:9004 weight=1 fail_timeout=5;
# server 127.0.0.1:9005 weight=1 fail_timeout=5;
# server 127.0.0.1:9006 weight=1 fail_timeout=5;
# server 127.0.0.1:9007 weight=1 fail_timeout=5;
# server 127.0.0.1:9008 weight=1 fail_timeout=5;
# server 127.0.0.1:9009 weight=1 fail_timeout=5;
# server 127.0.0.1:9010 weight=1 fail_timeout=5;
# least_conn;
# }
sendfile off;
#tcp_nopush on;
server_names_hash_bucket_size 128;
## Start: Timeouts ##
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 30;
send_timeout 10;
keepalive_requests 10;
## End: Timeouts ##
#gzip on;
server {
listen 80; #启动服务端口
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
## Caching Static Files, put before first location
#location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
# expires 14d;
# add_header Vary Accept-Encoding;
#}
# For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode
location / {
#include /nginx/conf/mysite.rules; # see also http block naxsi include line
##SecRulesEnabled;
##DeniedUrl "/RequestDenied";
##CheckRule "$SQL >= 8" BLOCK;
##CheckRule "$RFI >= 8" BLOCK;
##CheckRule "$TRAVERSAL >= 4" BLOCK;
##CheckRule "$XSS >= 8" BLOCK;
root html;
index index.html index.htm;
}
# For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi
##location /RequestDenied {
## return 412;
##}
## Lua examples !
# location /robots.txt {
# rewrite_by_lua '
# if ngx.var.http_host ~= "localhost" then
# return ngx.exec("/robots_disallow.txt");
# end
# ';
# }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000; # single backend process
# fastcgi_pass myLoadBalancer; # or multiple, see example above
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl spdy;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_prefer_server_ciphers On;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
nginx 1.7.11.3 Gryphon目录下cmd命令行启动Nginx:
nginx.exe -c ./conf/nginx-win.conf
或
start nginx -c ./conf/nginx-win.conf
注意:启动Nginx需要确保防火墙放行,方式1非后台运行,方式2后台运行,由于默认配置文件为nginx.conf,目前使用非默认配置文件,因此需要指定相对路径。
优雅停止Nginx命令:
nginx.exe -s quit -c ./conf/nginx-win.conf
浏览器输入:localhost:80,出现以下页面则配置成功。
在VLC-QT拉流前,可以利用VLC播放器拉流测试ffmpeg、Nginx是否配置正确。VLC播放器下载地址:http://download.videolan.org/vlc/3.0.17.4/win64/,选用目前最新版本3.0.17.4,下载vlc-3.0.17.4-win64.exe。
拷贝本地视频文件Wildlife.wmv到ffmpeg-5.0.1-full_build-shared\bin目录下,该目录下cmd执行命令推流:
ffmpeg.exe -re -i Wildlife.wmv -f flv rtmp://127.0.0.1:1935/live/home
推荐模式安装vlc-3.0.17.4-win64.exe,播放器中依次点击“媒体”==>“打开网络串流”,输入RTMP流媒体服务地址:rtmp://127.0.0.1:1935/live/home,点击“播放”。如下图。
则配置成功。
编译环境:
VS2017旗舰版
Qt 5.12.11(msvc2017_64)
CMake 3.15.3(带cmake-gui)
SDK与源码:
VLC SDK
VLC-QT源码
VLC-QT是基于VLC SDK的二次开发(Qt封装)的库,因此需要下载VLC SDK,下载地址:http://download.videolan.org/vlc/3.0.17.4/win64/,下载vlc-3.0.17.4-win64.7z(注意1.按需下载64位版本,2. 该页面下vlc-3.0.17.4-win64.zip中不含SDK目录,切勿使用)。
VLC-QT官网地址:https://vlc-qt.tano.si/,但仅提供指定Qt版本的库(基于VLC 2.2.4和Qt5.6.1的MSVC 2013的32位和64位库),一般需要下载源码编译。源码下载地址:https://github.com/vlc-qt/vlc-qt。
分别解压缩vlc-3.0.17.4-win64.7z、vlc-qt-master.zip。
新建环境变量VLC_PLUGIN_PATH,值为vlc-3.0.17.4\plugins路径。
在vlc-qt-master同级目录下新建build、install目录,分别作为build、install目录。
打开CMake,分别配置源码目录与构建目录。如下图,点击“Configure”。
弹出窗口中指定VS版本与平台。这里分别选择“Visual Studio 15 2017”和“x64”。点击“Finish”。
对于CMake的configure结果,按照以下方式配置。
到目录build下,用VS2017打开VLC-Qt.sln。
在debug、release模式下,分别修改Core,PluginQml,Qml,Widgets工程的属性==>链接器==>命令行==>其它选项下填入/SAFESEH:NO。
这是关闭一种警告,如果不设置这项,在生成工程时,会将这类警告看成错误,进而造成项目生成不成功。
设置完成后,在ALL_BUILD工程上右击生成,生成动态库,生成成功后在“INSTALL”工程上右击生成,可将库提取到安装目录里。(debug、release模式下按此顺序各执行一圈)。
错误修复:
利用https://github.com/vlc-qt/examples下载的examples-master.zip对编译的VLC-QT库进行测试。
利用Qt 5.12.11所带的QtCreator打开examples-master\simple-player下的simple-player.pro。构建设置中,对于“编辑构建配置”,分别选择Debug、Rlease,并去除“Shadow build”勾选。
修改src.pro,如下:
#
# VLC-Qt Simple Player
# Copyright (C) 2015 Tadej Novak
#
TARGET = simple-player
TEMPLATE = app
CONFIG += c++11
QT += widgets
SOURCES += main.cpp \
SimplePlayer.cpp \
EqualizerDialog.cpp
HEADERS += SimplePlayer.h \
EqualizerDialog.h
FORMS += SimplePlayer.ui \
EqualizerDialog.ui
#LIBS += -lVLCQtCore –lVLCQtWidgets #注释掉
# Edit below for custom library location
#LIBS += -L/Users/tadej/workspace/tanoprojects/install/vlc-qt/lib -lVLCQtCore –lVLCQtWidgets #注释掉
#INCLUDEPATH += /Users/tadej/workspace/tanoprojects/install/vlc-qt/include #注释掉
#添加以下部分
win32:CONFIG(release,debug|release): LIBS += -L$$PWD/../../../install/lib -lVLCQtCore -lVLCQtWidgets
else:win32:CONFIG(debug,debug|release): LIBS += -L$$PWD/../../../install/lib -lVLCQtCored -lVLCQtWidgetsd
INCLUDEPATH += $$PWD/../../../install/include
DEPENDPATH += $$PWD/../../../install/lib
对simple-player工程依次右键:清除=>执行qmake=>构建=>运行(运行前拷贝VLC-QT库目录install下bin目录下所有文件到examples-master\simple-player\src\release、examples-master\simple-player\src\debug中)。
在启动的程序中,点击“open url”按钮,输入地址:rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp,或前面的自建流媒体服务地址:rtmp://127.0.0.1:1935/live/home,即可拉流播放。
Github有个vlcplayer的范例可以参考,地址:
https://github.com/KikyoShaw/vlcPlayer/tree/master/vlcPlayer
注意:其位数为32位,且其不依赖VLC-QT,直接调用VLC库。
对于RTMP拉流开源库选型,Oliver-cs有相关总结:
自己尝试后,不得不对Qt原生的多媒体库(QMediaPlayer系列)敬而远之。有其优点,但是缺点非常严重。
QMediaPlayer优点:
QMediaPlayer缺点:
而OpenCV的缺点也比较突出:
VLC-QT除了需要编译之外,其支持格式众多,支持打开多种直播流链接,满足RTMP拉流需求。故最后选择VLC-QT。
【1】 FFmpeg windows下载安装. https://blog.csdn.net/luoyayun361/article/details/120961899
【2】 Windows下下载安装.ffmpeg.https://zhuanlan.zhihu.com/p/141765024
【3】 ffmpeg的下载及安装. https://blog.csdn.net/qq_33697094/article/details/112718101
【4】 Windows nginx + rtmp 流媒体服务器搭建(uniapp可用). https://blog.csdn.net/qq_41820930/article/details/119169265
【5】 nginx搭建rtmp服务器(windows). https://zhuanlan.zhihu.com/p/93525011
【6】 VLC-Qt VS2017编译Mark. https://blog.csdn.net/icebergkevin/article/details/115708404
【7】 VS2015+QT5.9.3+vlc-qt 完全编译. https://blog.csdn.net/octdream/article/details/82079907
【8】 vlc-qt编译VS2017+QT5.9.0. https://blog.csdn.net/HelloEarth_/article/details/103046448
【9】 QT | 聊聊QT与直播流播放——从QMediaPlayer到Qt-AV. https://www.cnblogs.com/QingHuan/p/8830562.html