网上关于直播相关的文章很多,但是讲解还是不够系统,对于刚刚接触直播开发的朋友实施起来会浪费不少时间。下面结合我自己的经验,

介绍一下直播方面的实战经验。

分成两个部分

第一部分是标题中介绍的基于RTMP推送文件流与视频流,PC端拉流RTMP,移动端拉流m3u8也就是hls

下一篇介绍基于websocket+canvas,进行拉流播放。

一 准备工作

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分片的方式处理,所以延迟会比较明显。

flv的直播 可参考连接https://hub.docker.com/r/mugennsou/nginx-http-flv ,但是需要注意的是

如果要推送摄像头到服务器并在手机端显示,要参考下面的指令和代码:

推送指令:

 ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -pix_fmt yuv420p  -f flv rtmp://192.168.1.253:32782/demo/stream-1 
-pix_fmt yuv420p 这个参数很关键,是把摄像头或者是桌面的RGB编码转成H264转成YUV格式,最终转化成H264编码
 
Html界面代码:
<!DOCTYPE html>
<html lang="en"> <head>
<title>video</title>
<!-- Video.js -->
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
<script src="https://unpkg.com/video.js/dist/video.min.js"></script>
<script src="https://unpkg.com/flv.js/dist/flv.min.js"></script>
<script src="https://unpkg.com/videojs-flvjs/dist/videojs-flvjs.min.js"></script>
</head> <body>qwer
<div>
<video id="videojs-flvjs-player" class="video-js vjs-default-skin vjs-big-play-centered" width="1024" height="768"> </video>
</div>
</body> </html>
<script>
var flvUrl = "http://192.168.1.253:32783/live?app=demo&stream=stream-1";
//flvUrl="https://mister-ben.github.io/videojs-flvjs/bbb.flv"
var player = videojs('videojs-flvjs-player', {
techOrder: ['html5', 'flvjs'],
flvjs: {
mediaDataSource: {
isLive: true,
cors: true,
withCredentials: false,
},
},
sources: [{
src: flvUrl,
type: 'video/mp4'
}],
controls: true,
preload: "none"
}, function onPlayerReady() {
console.log('player ready') player.on('error', (err) => {
console.log('first source load fail') player.src({
src: flvUrl,
type: 'video/x-flv'
}); player.ready(function() {
console.log('player ready')
player.load();
player.play();
});
})
});
</script>

html文件最好是放到服务器中运行,本地打开的html页可能无法正常显示。

下一篇再介绍基于websocket的移动端直播

c# 基于RTMP推流 PC+移动端 拉流播放的更多相关文章

  1. 基于rtmp+nginx 、vlc实现FFmpeg推流与wpf端拉流

    这周在研究基于rtmp+nginx直播流的实现,现总结如下: 0.所需文件: 链接:https://pan.baidu.com/s/1U5gsNI8Rcl684l5gVL6swg 提取码:dli9 1 ...

  2. JavaCV 学习(二):使用 JavaCV + FFmpeg 制作拉流播放器

    一.前言 在 Android 音视频开发学习思路 中,我们不断的学习和了解音视频相关的知识,随着知识点不断的学习,我们现在应该做的事情,就是将知识点不断的串联起来.这样才能得到更深层次的领悟.通过整理 ...

  3. 用C#做一个 拉流播放器

    做拉流播放器第一个想到就是,.,..FFmpeg没错 我也是用强大的他它来做的.但是我用的不是  cmd 调用 而是用的强大的FFmpeg.AutoGen FFmpeg.AutoGen 这个是C# 一 ...

  4. 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框

    vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...

  5. SRS服务器搭建,ffmpeg 本地推流,srs从本地拉流

    参考: https://github.com/ossrs/srs/wiki/v2_CN_SampleFFMPEG git clone https://github.com/ossrs/srs cd s ...

  6. 直播推流之blibli和拉流LFLiveKit

    执行上面操作后,导入合成的拉流blibli包到工程中,然后新建个播放控制器来设置播放 1.  播放的一些操作. 2. 高斯模糊. 3. 新建聊天控制器. - (void)viewDidLoad { [ ...

  7. EasyNVR摄像机无插件直播按需RTSP拉流播放流程详解

    1.背景需求 有许多客户现场,有许多设备但是不需要一直向设备端取视频流,因为在用户不观看的情况下,还在获取视频资源,一方面大大的浪费了网络带宽资源,一方面对设备服务器要求也较高,用户成本就要提高,这是 ...

  8. 基于rtmp的移动端推流解决方案

    因工作需要,及考虑成本因素,需要探索一套免费的移动端基于rtmp推流的直播解决方案,过程虽稍显曲折,但最终还是完成了目标.在这里将记录下来,以便日后查阅. 总体思路 移动端推流(RTMP) ---&g ...

  9. iOS - 直播流程,视频推流,视频拉流,简介,SMTP、RTMP、HLS、 PLPlayerKit

    收藏笔记 1 . 音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放显示1.数据采集:摄像机及拾音器收集视频及音频数据,此时得到的为原始数据涉及技术或协议:摄像机: ...

随机推荐

  1. (10)Go结构体struct

    结构体 Go语言中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,Go语言提供了一种自定义数据类型,可以封装多个 ...

  2. vue使用axios发送请求,都会发送两次请求

    vue 使用axios,每次的请求都会发送两次,第一次的请求头为options CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sha ...

  3. SSM项目实战 之 EasyUI

    目录 EasyUI 简介 概述 使用EasyUI panel组件 简介 示例 JS形式及属性介绍 panel事件与方法 Window组件 概述 使用 行为 dialog 概述 使用 tabs组件 概述 ...

  4. 安装mininet 一直显示 ‘Cloning into openflow'

    问题描述. 安装mininet卡在了下载openflow. git clone --branch 2.2.2 git@github.com:mininet/mininet.git ,然后输入命令./i ...

  5. vue-admin-template 切换回中文

    使用vue-admin-template开发项目,使用的是element-ui的控件,但这个框架走的是国际化,是英文版,好吧!快速切换为中文版: 找到main.js 第七行: 替换为: import ...

  6. mysql监控工具sqlprofiler,类似sqlserver的profiler工具安装(一)

    最近无意发现了mysql的客户端监控工具“Nero Profile SQL”,刚开始还不知道怎么使用,经过半小时摸索,现将使用步骤写下来. 背景:开发的时候,如果数据存储层这块使用EF,或者其他orm ...

  7. python 传入任意多个参数(方法调用可传参或不传参)

    1.可传参数与不传参数,在定义中给参数设置默认值 class HandleYmal: """ 获取测试环境的配置 """ def __ini ...

  8. 【SSH进阶之路】Spring的IOC逐层深入——为什么要使用IOC[实例讲解](二)

    上篇博客[SSH进阶之路]Spring简介,搭建Spring环境——轻量级容器框架(一),我们简单的介绍了Spring的基本概念,并且搭建了两个版本的Spring开发环境,但是我们剩下了Spring最 ...

  9. Azure上部署Barracuda WAF集群 --- 2

    前面一篇文章讲了如何在Azure上部署Barracuda.这篇文章聊一聊如何配置Barracuda. License 向Barracuda的销售人员申请WAF的License.得到License后打开 ...

  10. mongoDB杂项

    密码更改:db.changeUserPassword('tank2','test'); 在这里我遇到了一个问题: mongod: error while loading shared librarie ...