网上关于直播相关的文章很多,但是讲解还是不够系统,对于刚刚接触直播开发的朋友实施起来会浪费不少时间。下面结合我自己的经验,
介绍一下直播方面的实战经验。
分成两个部分
第一部分是标题中介绍的基于RTMP推送文件流与视频流,PC端拉流RTMP,移动端拉流m3u8也就是hls
下一篇介绍基于websocket,通过http-flv协议进行拉流播放。
一 准备工作
1.准备RTMP服务器,我是在win10下开发,我是安装了docker for windows,然后下载镜像nginx-rtmp-server,(使用linux的朋友就更方便了,docker pull antongulenko/rtmp-nginx-server),点击Create后自动安装
安装完成后,保存当前的端口号,为了防止每次重启容器端口号自动分配,点击保存按钮 如图:
1935是本机RTMP对应的端口,外部映射的是 32781,稍候我们会用到这个端口号进行推流。
此时nginx还没有进行配置,我们需要配置,首先找到nginx.conf,
首先进入容器,具体的操作我只记录docker for windows的,linux就更简洁了,docker exec 容器id。
可以查看容器的目录结构
nginx的路径是etc/nginx/nginx.conf
首先拷贝下来,修改后,再覆盖回去,覆盖后要重启nginx,才能生效。
下面的指令是分别从容器上把配置文件拷贝到D盘,修改后 将文件覆盖回容器内
具体conf内容如下:
worker_processes auto; rtmp_auto_push on; events {} rtmp { server { listen 1935; listen [::]:1935 ipv6only=on; application vod { play /opt/rtmp/vod; } application mirror_cache { play /opt/rtmp/vod_mirror; } application live{ # enable live streaming live on; max_connections 1024; } application hls{ live on; hls on; hls_path /usr/local/hls; hls_fragment 5s; } # Application names cannot contain patterns, and play_local_path fails for cached files # that contain slashes (error dir not found). Therefore, list every path of interest as a separate # application, so that only files without directory prefix are cached. application mirror/720 { play /opt/rtmp/vod_mirror http://www.sample-videos.com/video/flv/720/; play_local_path /opt/rtmp/vod_mirror; } application mirror/480 { play /opt/rtmp/vod_mirror http://www.sample-videos.com/video/flv/480/; play_local_path /opt/rtmp/vod_mirror; } application mirror/360 { play /opt/rtmp/vod_mirror http://www.sample-videos.com/video/flv/360/; play_local_path /opt/rtmp/vod_mirror; } application mirror/240 { play /opt/rtmp/vod_mirror http://www.sample-videos.com/video/flv/240/; play_local_path /opt/rtmp/vod_mirror; } } } http { server { listen 8080; # This URL provides RTMP statistics in XML location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root /opt/rtmp/http/; } location /hls{ types{ application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /usr/local/hls; add_header Cache-Control no-cache; } location /vod { autoindex on; alias /opt/rtmp/vod; } location /mirror_cache { autoindex on; alias /opt/rtmp/vod_mirror; } location /mirror/ { proxy_pass http://www.sample-videos.com/video/; } } }
配置文件中的 application live 与 application hls就是分别推送rtmp与hls协议的路由地址
而http节点就是用于手机端使用m3u8播放的时候(http://ip+port/hls/秘钥.m3u8)的配置。
然后重启容器就可以了。
2.github下载https://github.com/BoonyaCSharp-ASP/VedioFFmpegPushRTMP
基于c#封装的FFMPEG的推流方法,使用的时候需要下载FFMPEG的相关文件,
我这里提供一下连接,直接解压覆盖,注意link类型为shared
https://ffmpeg.zeranoe.com/builds/
这个c#工程可以直接运行,配置使用也是很难得,不过我为了测试方便还是直接用命令行的方式进行推流
命令行进入x64文件夹下,直接使用ffmpeg.exe进行推流,ffplay.exe以直接进行播放。
下面开始推流:
1.推送文件流,我在x64下面放置了1.MP4的文件
推流指令如下
ffmpeg.exe -re -i 1.mp4 -f flv rtmp://192.168.1.253:32781/rtmp/test
192.168.1.253是我的rtmp服务器ip 32781是docker中rtmp的外部端口 (如果不使用docker自然就是1935了)
rtmp 是nginx.conf 配置的rtmp的路由节点名称 test类似于房间号的概念,拉流的时候也指定这个房间号,就可以对应到自己要看的直播流
推流如下:
如果有异常信息就是相关参数的配置,具体问题留言讨论。
拉取文件流
可以下载vlc播放器,然后配置拉流地址 rtmp://192.168.1.253:32781/rtmp/test 就可以点击播放
PC端播放rtmp代码如下,建议使用Chrome,并且设置flash允许
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>使用video.js实现rtmp流的直播播放</title> <!--引入播放器样式--> <link href="http://vjs.zencdn.net/5.19/video-js.min.css" rel="stylesheet"> <!--引入播放器js--> <script src="http://vjs.zencdn.net/5.19/video.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/videojs-flash@2/dist/videojs- flash.min.js"></script> </head> <body> <!--vjs-big-play-centered 播放按钮居中--> <!--poster默认的显示界面,就是还没点播放,给你显示的界面--> <!--controls 规定浏览器应该为视频提供播放控件--> <!--preload="auto" 是否提前加载--> <!--autoplay 自动播放--> <!--loop=true 自动循环--> <!--data-setup=‘{"example_option":true}‘ 可以把一些属性写到这个里面来,如data-setup= {"autoplay":true}--> <video id="my-player" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" autoplay="autoplay" poster="//vjs.zencdn.net/v/oceans.png" width="500" height="400" data- setup=‘{}‘> <!--src: 规定媒体文件的 URL type:规定媒体资源的类型--> <source src=‘rtmp://192.168.1.253:32781/live/test‘ type=‘rtmp/flv‘/> </video> <script type="text/javascript"> // 设置flash路径,用于在videojs发现浏览器不支持HTML5播放器的时候自动唤起flash播放器 videojs.options.flash.swf = ‘https://cdn.bootcss.com/videojs-swf/5.4.1/video- js.swf‘; var player = videojs(‘my-player‘); //my-player为页面video元素的id player.play(); //播放 // 1. 播放 player.play() // 2. 停止 player.pause() // 3. 暂停 player.pause() </script> </body> </html>
2.推送视频流
如果直接按照如下命令推送
ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -acodec aac -f flv rtmp://192.168.1.253:32781/live/test
很有可能vlc ffplay可以正常拉流播放,但是网页播放不了,推荐一个网址测试对应的rtmp协议流是否能通过flash播放
https://blog.csdn.net/liuzehn/article/details/81036195
可用的RTMP源:http://www.mamicode.com/info-detail-2539819.html
如果测试过程中能够接受到流,但是不能播放就是视频格式的问题,
这时候使用如下的指令进行播放:
ffmpeg.exe -f dshow -i video="Integrated Camera" -vcodec libx264 -pix_fmt yuv420p -f flv rtmp://192.168.1.253:32781/live/test
其中 Integrated Camera 是摄像头的名字,如果是USB的则填写对应的名字
具体的获得摄像头名称的操作方式参考:
https://www.jianshu.com/p/c141fc7881e7
3.推送视频流,hls播放
推流指令如下:
ffmpeg.exe -f dshow -i video="Integrated Camera" -vcodec libx264 -pix_fmt yuv420p -f flv rtmp://192.168.1.253:32781/hls/test
移动端拉流代码:
<!DOCTYPE html> <html lang="en"> <head> <title>Video.js | HTML5 Video Player</title> <!-- <link href="video-js-6.2.0/video-js.css" rel="stylesheet"> <script src="video-js-6.2.0/videojs-ie8.min.js"></script> --> <link href="http://vjs.zencdn.net/5.20.1/video-js.css" rel="stylesheet"> <script src="http://vjs.zencdn.net/5.20.1/videojs-ie8.min.js"></script> </head> <body> <video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="1280" height="720" poster="http://vjs.zencdn.net/v/oceans.png" data-setup="{}"> <!-- <source src="1.mp4" type="video/mp4"> rtmp://192.168.1.253:32781/live/test --> <source src="http://192.168.1.253:32780/hls/test.m3u8" type="application/x- mpegURL" > <p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p> </video> <object height="900px" width="100%" classid="clsid:D27CDB6E-AE6D-11cf-96B8- 444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#versio n=9,0,28,0" id="abcdef"> <param value="index.swf(flash路径)" name="movie"> <param value="high" name="quality"> <param value="transparent" name="wmode"> <embed height="900px" width="100%" name="abcdef" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/shockwave/download/download.cgi? P1_Prod_Version=ShockwaveFlash" quality="high" src="rtmp://192.168.1.253:32781/live/test"> </object> <script src="http://vjs.zencdn.net/5.20.1/video.js"></script> </body> </html>
rtmp如果有vlc会有延迟,是vlc本身的缓存原因,ffplay几乎0延迟,PC版本的一秒左右延迟,m3u8分片的方式处理,所以延迟会比较明显。
下一篇再介绍基于websocket的移动端直播