nginx + nginx-http-flv-module-1.2.10(包含nginx-rtmp-module) + video标签播放 http-flv 视频
1. nginx安装nginx-http-flv-module-1.2.10插件 下载地址nginx-http-flv-module-1.2.10
2. 配置nginx rmtp服务
server{listen 7703;location /live { # 拉流时的 uri ,可以自行修改flv_live on; # 打开 http-flv 服务chunked_transfer_encoding on;add_header Access-Control-Allow-Origin *; # 允许跨域add_header Access-Control-Allow-Credentials true;}location /hls {types {application/vnd.apple.mpegurl m3u8;#application/x-mpegURL;video/mp2t ts;}root /www/wwwroot/;expires -1;add_header Cache-Control no-cache;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;add_header Access-Control-Allow-Methods *;add_header Access-Control-Max-Age 3600;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin *;}location /stat {rtmp_stat all;rtmp_stat_stylesheet stat.xsl;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;add_header Access-Control-Allow-Methods *;add_header Access-Control-Max-Age 3600;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin *;}location /stat.xsl {# XML stylesheet to view RTMP stats.# Copy stat.xsl wherever you want# and put the full directory path hereroot /www/server/nginx-http-flv-module-1.2.10;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;add_header Access-Control-Allow-Methods *;add_header Access-Control-Max-Age 3600;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin *;}}
include /www/server/panel/vhost/nginx/*.conf;
include /www/server/nginx/conf/vhost/*.conf;
}rtmp {out_queue 4096;out_cork 8;max_streams 128;timeout 15s;drop_idle_publisher 15s;log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用log_size 1m; #log模块用来记录日志的缓冲区大小server {listen 7702;chunk_size 8192;application play {play /www/wwwroot/html7702;}application hls {live on; # 打开直播hls on;meta off;# 为了兼容网页前端的 flv.js,设置为 off 可以避免报错gop_cache on; # 支持GOP缓存,以减少首屏时间allow play all; # 允许来自任何 ip 的人拉流hls_path /www/wwwroot/hls;hls_fragment 1s;hls_playlist_length 4s;}application myapp { # myapp 模块,可以自行更换名字live on; # 打开直播#hls on;meta off;# 为了兼容网页前端的 flv.js,设置为 off 可以避免报错gop_cache on; # 支持GOP缓存,以减少首屏时间allow play all; # 允许来自任何 ip 的人拉流#hls_path /www/wwwroot/myapp;#hls_fragment 1s;#hls_playlist_length 4s;}}
}
rmtp 推流地址:rmtp:域名:7702/myapp/yjx
拉流地址:http://域名:7703/live?port=7702&app=myapp&stream=yjx
3. vue播放
vue 安装flv.js
npm install --save flv.js
封装成vue组件
videoFlv.vue
<template><div><div class="hello" style="width:100%; height:100%;background-color:#000000;"><section v-if="!loadStatus" style="width:100%; height:100%;"><div class="video-box"><video autoplay controls width="100%" height="220px" :id="id" muted></video><div class="left-up-video-img" @click="leftUpVideoImgClick"></div><div class="left-down-video-img" @click="leftDownVideoImgClick"></div><div class="right-up-video-img" @click="rightUpVideoImgClick"></div><div class="right-down-video-img" @click="rightDownVideoImgClick"></div></div></section><div v-elsestyle="width: 100%;height: 100%;display: flex;justify-content:center;align-items:center;cursor: pointer"><span style="color: wheat;font-size: 14px;"><i class="el-icon-warning-outline"style="margin-right: 10px"></i>{{ statusMsg }}</span></div></div></div>
</template><script>
import flvjs from "flv.js";
export default {name: 'videoFlv',comments() {},data() {return {src: "", //flv格式的地址timerId: null,loadStatus: true,id: 'videoElement' + Math.random(),statusMsg: '摄像机未开启,请联系',flvPlayer: null,lastDecodedFrame: 0,videoElement: null,headerData: {// 页面设置属性name: '直播', //页面名称details: '', //页面描述isPerson: false, // 是否显示个人中心isBack: false, // 是否返回按钮titleHeight: 35, // 高度bgColor: 'rgba(249, 249, 249, 10)', //背景颜色bgImg: '' // 背景图片}};},created() {if (this.timerId) {clearInterval(this.timerId)this.timerId = null}},mounted() {this.$nextTick(() => {this.setsrc();})},destroyed() {console.log("destorying video");if (this.timerId) {clearInterval(this.timerId)this.timerId = null}if (this.flvPlayer !== null) {this.flvPlayer.pause();this.flvPlayer.destroy();this.flvPlayer = null;}},methods: {createVideo() {let that = thisconsole.log(that.flvPlayer);if (that.flvPlayer) {that.flvPlayer.pause();that.flvPlayer.destroy();that.flvPlayer = null;}if (that.timerId !== null) {clearInterval(that.timerId);}that.videoElement = document.getElementById(that.id)if (flvjs.isSupported()) {that.flvPlayer = flvjs.createPlayer({type: 'flv',url: that.src,isLive: true,}, {// cors: true, // 是否跨域// enableWorker: true, // 是否多线程工作// enableStashBuffer: false, // 是否启用缓存// stashInitialSize: 128, // 缓存大小(kb) 默认384kb// autoCleanupSourceBuffer: true // 是否自动清理缓存enableWorker: false, //不启用分离线程enableStashBuffer: false, //关闭IO隐藏缓冲区isLive: true,lazyLoad: false,})}that.flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {console.log("errorType:", errorType);console.log("errorDetail:", errorDetail);console.log("errorInfo:", errorInfo);this.loadStatus = truethis.statusMsg = "正在重连。。。"//视频出错后销毁重新创建if (that.flvPlayer) {that.flvPlayer.pause();that.flvPlayer.unload();that.flvPlayer.detachMediaElement();that.flvPlayer.destroy();that.flvPlayer = null;}that.createVideo();});that.flvPlayer.on("statistics_info", function (res) {if (that.lastDecodedFrame == 0) {that.lastDecodedFrame = res.decodedFrames;return;}if (that.lastDecodedFrame != res.decodedFrames) {that.lastDecodedFrame = res.decodedFrames;} else {that.lastDecodedFrame = 0;if (that.flvPlayer) {that.flvPlayer.pause();that.flvPlayer.unload();that.flvPlayer.detachMediaElement();that.flvPlayer.destroy();that.flvPlayer = null;that.createVideo();}}});that.flvPlayer.attachMediaElement(this.videoElement)that.flvPlayer.load()that.flvPlayer.play()if (that.timerId !== null) {clearInterval(that.timerId);}that.timerId = setInterval(() => {if (that.videoElement.buffered.length > 0) {const end = that.videoElement.buffered.end(0); // 视频结尾时间const current = that.videoElement.currentTime; // 视频当前时间const diff = end - current;// 相差时间console.log(diff);const diffCritical = 4; // 这里设定了超过4秒以上就进行跳转const diffSpeedUp = 1; // 这里设置了超过1秒以上则进行视频加速播放const maxPlaybackRate = 4;// 自定义设置允许的最大播放速度let playbackRate = 1.0; // 播放速度if (diff > diffCritical) {console.log("相差超过4秒,进行跳转");that.videoElement.currentTime = end - 1.5;playbackRate = Math.max(1, Math.min(diffCritical, 16));} else if (diff > diffSpeedUp) {console.log("相差超过1秒,进行加速");playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16))}that.videoElement.playbackRate = playbackRate;if (that.videoElement.paused) {that.flvPlayer.play()}}}, 1000);},setsrc() {if (this.url) {this.src = this.url;this.createVideo();}},leftUpVideoImgClick() {this.$toast("我是左上按钮")},leftDownVideoImgClick() {this.$toast("我是左下按钮")},rightUpVideoImgClick(){this.$toast("我是右上按钮")},rightDownVideoImgClick(){this.$toast("我是右下按钮")}},props: {url: {default: null,required: true,type: String | null},},watch: {url: {handler(newValue) {if (newValue != null) {this.loadStatus = falsethis.src = newValuethis.$nextTick(() => {this.setsrc();})}},deep: true,immediate: true,}},
}
</script><style scoped>
h3 {margin: 40px 0 0;
}ul {list-style-type: none;padding: 0;
}li {display: inline-block;margin: 0 10px;
}a {color: #42b983;
}.video-box {position: relative;
}.video-box video {display: inline-block;vertical-align: baseline;
}.video-box .left-up-video-img {position: absolute;top: 100px;bottom: 10px;left: 20px;/*right: 20px;*/width: 10px;height: 10px;z-index: 999;background: url(../../../assets/images/icon_jt.png) no-repeat;background-size: 100% 100%;cursor: pointer
}
.video-box .left-down-video-img {position: absolute;top: 150px;bottom: 10px;left: 20px;/*right: 20px;*/width: 10px;height: 10px;z-index: 999;background: url(../../../assets/images/icon_jt.png) no-repeat;background-size: 100% 100%;cursor: pointer
}
.video-box .right-up-video-img {position: absolute;top: 100px;bottom: 10px;/*left: 20px;*/right: 20px;width: 10px;height: 10px;z-index: 999;background: url(../../../assets/images/icon_jt.png) no-repeat;background-size: 100% 100%;cursor: pointer
}
.video-box .right-down-video-img {position: absolute;top: 150px;bottom: 10px;/*left: 20px;*/right: 20px;width: 10px;height: 10px;z-index: 999;background: url(../../../assets/images/icon_jt.png) no-repeat;background-size: 100% 100%;cursor: pointer
}
</style>
调用方法
<template><div><!-- <video-flv :url="src"></video-flv>--><div style="width: 100%; height:220px" v-for="(item,index) in urllist" :key="index"><video-flv :url="item.url"/></div></div>
</template><script>
import VideoFlv from "@/views/tabbar/live/flvVideo";export default {components: {VideoFlv},data() {return {urllist: [{//nginx 流媒体服务器// url: "http://ip:7703/live?port=7702&app=myapp&stream=yjx"//推流地址 rtmp://yjx.yjx-show.top:7702/myapp /yjxurl: "http://ip:7703/live?port=7702&app=myapp&stream=yjx"//推流地址 rtmp://yjx.yjx-show.top:7702/myapp /yj},// {// url: "http://yjx.yjx-show.top:7703/live?port=7702&app=myapp&stream=ypt"// },]}},comments() {flvVideo}
}
</script>
<style lang="less" scoped>
//.dplayer {
// width: 500px;
//}
</style>
使用obs进行推流
直播延迟1-3秒
nginx + nginx-http-flv-module-1.2.10(包含nginx-rtmp-module) + video标签播放 http-flv 视频相关推荐
- vue中使用video标签播放FLV总结
Audio/Video 标签属性及自定义(进度条.播放.快进.全屏) - SeaJson - 博客园 (cnblogs.com) //全屏按钮video::-webkit-media-controls ...
- html5 video 播放状态,10分钟了解HTML5的Video标签属性、方法和事件
标签的属性 src :视频的属性 poster:视频封面,没有播放时显示的图片 preload:预加载 autoplay:自动播放 loop:循环播放 controls:浏览器自带的控制条 width ...
- Nginx Rtmp Module - HLS切片和级联播放
#Nginx Rtmp Module - HLS切片和播放 1.名词解释 媒体片段文件(.ts): 媒体片段是由源站生成的,基于编码后的媒体源,并且是由一系列的 .ts 格式的文件组成,其中包含了你想 ...
- Ubuntu10.10 Server+Nginx+Django+Postgresql安装步骤
1,安装Ubuntu 10.10 1.1 使用默认安装,在更新apt的时候选择跳过 1.2 设置管理员的用户名和密码 1.3 安装openssh-server启动ssh服务,方便使用Bitvise T ...
- ffmpeg api推流,谷歌浏览器播放大华、海康威视网络摄像头rtsp视频流方案(hls、m3u8、flv、webrtc、srs、nginx、nginx-rtmp、rtmp)比较
ffmpeg api推流,谷歌浏览器播放大华.海康威视网络摄像头rtsp视频流方案(hls.m3u8.flv.webrtc.srs.nginx.nginx-rtmp.rtmp)比较 将网络摄像头视频流 ...
- Nginx学习总结(10)——Nginx前后端分离将多个请求转发到多个Tomcat,负载均衡反向代理
一.谈谈"渲染" 相信好多人都挺听过"渲染"这个词,但不清楚它是什么意思?前端开发以为这是后端的活儿,后端开发以为是前端的事儿,推着推着就不了了之.其实渲染很简 ...
- php require persion denied,php,nginx_php+nginx配置权限问题(13: Permission denied),php,nginx - phpStudy...
php+nginx配置权限问题(13: Permission denied) ps查看nginx数据: _www 508 0.0 0.0 2461508 1320 ?? S 10:46下午 0:00. ...
- 转载:编译安装Nginx(1.5.1)《深入理解Nginx》(陶辉)
原文:https://book.2cto.com/201304/19618.html 1.5 configure详解 可以看出,configure命令至关重要,下文将详细介绍如何使用configure ...
- Windows上搭建Nginx RTMP服务器并使用FFmpeg实现本地视频推流
场景 RTMP RTMP协议 (1)是流媒体协议. (2)RTMP协议是 Adobe 的私有协议,未完全公开. (3)RTMP协议一般传输的是 flv,f4v 格式流. (4)RTMP一般在 TCP ...
最新文章
- oracle的cols,Oracle cols_as_rows 比对数据
- 线程编程常见API简介(上)
- 干货!Java字节码增强探秘
- 初学ActionScript 3.0(一):Hello World
- java 常量表达式_JavaSwitch语句:常量表达式是必需的,但它是常量
- 【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C++)
- 100级大橙武升级流程_DNF:女气功升级100级无暇手套,前后伤害对比。
- Linux的crond的配置流程,Linux之定时任务Crond详解
- 网站开发用什么语言好_兰州网站开发哪家策划效果好
- LCD TTL/LVDS 任意分辨率 timing 时序配置及时序关系(前肩后肩)
- 孩子的编程启蒙好伙伴,自己动手打造小世界,长毛象教育AI百变编程积木套件上手
- 厦门大学麦嘉仪:统计学专业到微众银行风控岗!
- 计算机系统如何禁止文件删除功能,Win7如何禁止在C盘上安装软件?|win7系统c盘哪些文件是可以删除的...
- SQL 压力测试实战
- 温莎大学应用计算机,加拿大留学,温莎大学英语计算机专业了解一下
- Sublime Text:选择变量的所有实例并编辑变量名称
- A survey on semi-supervised learning
- 云服务器和VPS有什么区别?
- spring boot 设置默认主页
- 抖音取图小程序,同款抖音壁纸,表情包小程序搭建
热门文章
- JavaScript聊天框插入表情: 点击表情时输入框失焦, 无法插入到输入框.
- 蓝桥杯真题跑步锻炼(Excel快速准确解法)
- R 基本函数sweep的使用(apply函数的利器)
- 微信小程序入坑教程二十一:使用wx.saveImageToPhotosAlbum保存图片时通过检测scope.writePhotosAlbum权限来提醒用户是否需要授权
- 异步电机发波方式总结与比较
- C# HTTP系列10 form表单的enctype属性
- html冻结表格——类似excel功能
- SLAM第五讲点云拼接思路笔记
- IT应届实习不加班可能吗?高薪与健康无法兼得吗?
- js输出100以内的质数_JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例...