项目中,用到海康的设备,前端要调用视频,一切都木有问题了,但是视频有的秒开,有的点无数次都开不了,视频播放失败,但是过一会又可以点开了
后来得人提醒,是不是时间原因,
经过多次实验,实时推送的视频没法实时访问的,大概2分钟后访问就没有问题,所以拉取视频数据就要过滤下时间,只把当前时间2分钟后的视频数据返给前端就可以,所有视频都是秒开
放一个demo,vue的项目,一个自动回放,给大家参考
mounted () {//初始一定要放在mounted。不要放created
this.videoInitPlugin();
},
destroyed () {//退出一定要销毁
for (var i = 0; i < this.cameraArray.length; i++) {
WebVideoCtrl.I_Stop({iWndIndex: i});
}
var iRet = WebVideoCtrl.I_Logout(this.szIP);
if (iRet !== 0) {
console.log("WebVideoCtrl I_Logout failed");
} else {
console.log("WebVideoCtrl I_Logout success");
}
},
methods: {
onLogout() {
var iRet = WebVideoCtrl.I_Logout(this.szIP);
if (0 == iRet) {
console.log('退出成功')
} else {
console.log('退出失败')
}
},
downLoadPlugin () {
if (confirm(`是否下载该插件?`)) {
window.location.href = process.env.VUE_APP_BASE_API + `video/file/downloadFile`;
}
},
videoInitPlugin () {
var iRet = WebVideoCtrl.I_CheckPluginInstall();
if (iRet === -1) {
alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装!");
this.downLoadPlugin();
return;
}
console.log('1,videoInitPlugin')
this.initPlugin()
},
initPlugin: function () {
console.log('2,initPlugin')
WebVideoCtrl.I_InitPlugin(this.iWidth, this.iHeight, {
bWndFull: true,//是否支持单窗口双击全屏,默I_CheckPluginInstall
iWndowType: 1,
cbInitPluginComplete: function () {
WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin");
}
});
// 检查插件是否最新
/*if (WebVideoCtrl.I_CheckPluginVersion() === -1) {
alert("检测到新的插件版本,请升级!");
return;
}*/
console.log('3,I_Login')
this.login()
},
login(){
if(this.szIP==''|| this.iProtocol==''|| this.szPort==''|| this.szUsername==''|| this.szPassword==''){
alert('参数有空')
return false
}
let that=this
WebVideoCtrl.I_Login(this.szIP, 1, this.szPort, this.szUsername, this.szPassword, {
async: false,
success: function (xmlDoc) {
console.log(xmlDoc);//不能删除
console.log('登录成功')
// 开始预览
var szDeviceIdentify = this.szIP + "_" + this.szPort;
setTimeout(()=>{
that.getChannelInfo()
that.hf()
}, 100);
},
error: function () {
console.log("login error");
}
});
},
hf(){
console.log('4,hf')
if(this.szIP==''|| this.iProtocol==''|| this.szPort==''|| this.szUsername==''|| this.szPassword==''){
console.log('参数有空')
return false
}
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex);
let szDeviceIdentify = this.szIP //ip
let iChannelID=this.iProtocol //通道号,这里注意,通道号是number,之前我们数据返的是完整的,如601,其实只用传6即可,千万不要传601
let szStartTime=this.startTime
let szEndTime=this.endTime
let iStreamType=parseInt(1, 10)//可以不要
var startPlayback =function() {
let szInfo=''
console.log('进入播放')
WebVideoCtrl.I_StartPlayback(szDeviceIdentify, {
iStreamType:iStreamType,
iChannelID: iChannelID,
szStartTime: szStartTime,
szEndTime: szEndTime,
success: function () {
szInfo = "开始回放成功!";
console.log(szDeviceIdentify + " " + szInfo);
},
error: function (status, xmlDoc) {
if (403 === status) {
szInfo = "设备不支持Websocket取流!";
} else {
szInfo = "开始回放失败!";
}
console.log(szDeviceIdentify + " " + szInfo);
}
});
};
console.log('oWndInfo',oWndInfo)
if (oWndInfo != null) {// 已经在播放了,先停止
WebVideoCtrl.I_Stop({
success: function () {
startPlayback();
}
});
} else {
startPlayback();
}
},
getChannelInfo(){
// 模拟通道
let that=this
WebVideoCtrl.I_GetAnalogChannelInfo(this.szIP, {
async: false,
success: function (xmlDoc) {
var oChannels = $(xmlDoc).find("VideoInputChannel");
$.each(oChannels, function (i) {
console.log(i)
});
},
error: function () {
console.log( " 获取模拟通道失败!");
}
});
// 数字通道
WebVideoCtrl.I_GetDigitalChannelInfo(this.szIP, {
async: false,
success: function (xmlDoc) {
console.log(xmlDoc," 获取数字通道成功!");
},
error: function () {
console.log( " 获取数字通道失败!");
}
});
// 零通道
WebVideoCtrl.I_GetZeroChannelInfo(this.szIP, {
async: false,
success: function (xmlDoc) {
console.log(xmlDoc, " 获取零通道成功!");
},
error: function () {
console.log( " 获取零通道失败!");
}
});
}
}
参考:https://blog.csdn.net/ttxxsir/article/details/80498130
因为使用是官方免费提供的插件,目前只能兼容ie,谷歌低版本虽然也能兼容,但是太低了,还不如ie,所以,换成了b站之前提供的方案,nodejs+rtsp的方式,不兼容ie,但是也很赞,
如果主流浏览器和ie都想很好兼容,就做一个判断,ie用插件,其他用rtsp
或者官方有付费的视频插件,可以很好的兼容各浏览器,实时视频也不存在时间的问题,有钱就可可以为所欲为
<template>
<div>
<video class="demo-video" ref="player" muted autoplay></video>
</div>
</template>
<script>
import { parseTime } from '@/utils'
export default {
props:{
info:Object,
time:{
type:Number,
default:null
}
},
data () {
return {
id: "1",
rtsp: "",
player: null,
startTime: "",
endTime:"",
}
},
created(){
let {nvrUsername,nvrPassword,nvrIp,nvrPort,nvrChan}=this.info
let timeQuery=''
if(this.time){//前后15秒
let start=parseTime(this.time-15,'{y}{m}{d}')+'T'+parseTime(this.time-15,'{h}{i}{s}')+'Z'
let end=parseTime(this.time+15,'{y}{m}{d}')+'T'+parseTime(this.time+15,'{h}{i}{s}')+'Z'
this.startTime=start
this.endTime=end
this.rtsp= "rtsp://"+nvrUsername+":"+nvrPassword+"@"+nvrIp+":"+nvrPort+"/Streaming/tracks/"+nvrChan
}else{//直播
this.rtsp= "rtsp://"+nvrUsername+":"+nvrPassword+"@"+nvrIp+":"+nvrPort+"/Streaming/Channels/"+nvrChan
}
console.log(this.rtsp, this.startTime, this.endTime)
},
mounted () {
if (flvjs.isSupported()) {
let video = this.$refs.player;
if (video) {
console.log(`${process.env.VUE_APP_BASE_API_video}/rtsp/${this.id}/?url=${this.rtsp}&starttime=${this.startTime}&endtime=${this.endTime}`)
this.player = flvjs.createPlayer({
type: "flv",
isLive: true,
url: `${process.env.VUE_APP_BASE_API_video}/rtsp/${this.id}/?url=${this.rtsp}&starttime=${this.startTime}&endtime=${this.endTime}`
});
this.player.attachMediaElement(video);
try {
this.player.load();
setTimeout(()=>{
this.player.play();
}, 200);
} catch (error) {
console.log(error);
this.player.destroy();
};
}
}
},
beforeDestroy () {
this.player.destroy();
}
}
</script>
参考:https://blog.csdn.net/qq_32584661/article/details/103276360
网友评论