[TOC]

视频问题

格式分析

flv 网络环境要求较高
rtmp
hls
m3u8
mp4

flash/h5-video

flash

object embed;鼠标右键目录显示adobe flash player
https://www.jb51.net/web/165456.html
OBJECT 标签是用于windows IE3.0及以后浏览器或者其它支持Activex控件的浏览器。“classid”和“codebase”属性必须要精确地按上例所示的写法写,它们告 诉浏览器自动下载flash player的地址。如果你没有安装过flash player 那么IE3.0以后的浏览器会跳出一个提示框访问是否要自动安装flash player。当然,如果你不想让那些没有安装flash player的用户自动下载播放器,或许你可以省略掉这些代码。
EMBED标签是用于Netscape Navigator2.0及以后的浏览器或其它支持Netscape插件的浏览器。“pluginspage”属性告诉浏览器下载flash player的地址,如果还没有安装flash player的话,用户安装完后需要重启浏览器才能正常使用。
为了确保大多数浏览器能正常显 示flash,你需要把EMBED标签嵌套放在OBJECT标签内,就如上面代码例子一样。支持Activex控件的浏览器将会忽略OBJECT标签内的 EMBED标签。Netscape和使用插件的IE浏览器将只读取EMBED标签而不会识别OBJECT标签。也就是说,如果你省略了EMBED标签,那 firefox就不能识别你的flash了(不过纳闷的是,省略了object只写embed,IE也能正常显示flash…

h5-video

video;鼠标右键显示正常右键目录

视频链接动态更换问题

https://blog.csdn.net/guo_qiangqiang/article/details/106897514
使用jquery动态修改video标签source的src不起作用问题解决方案

代码

//html代码
 <audio controls="controls" style="margin-top: 10px;" id="audio_bill_music">
<source src="<?= $bill_info['bill_music']; ?>" id="source_bill_music"  type="audio/mpeg">
<embed height="40" width="100" src="http://www.qipa250.com/qipa250.mp3" id="embed_bill_music"></embed>
</audio>
//jquery 代码
$('#source_bill_music').attr('src', bill_music);
$('#embed_bill_music').attr('src', bill_music);

通过 jQuery 确实是给 source 的 src 赋值成功,从调试来看,浏览器并没有去发起请求去获得相应的视频,可以推断出来的是,当 video 中存在 source 标签的时候,浏览器渲染之后会自动去获取地址,即便地址改变,
浏览器也不会再去获取地址。但是通过动态的插入 source 标签的方式,可以触发浏览器进行重排,从而去获取相应地址的文件进行播放。
解决方案load() 方法重新加载音频/视频元素
load() 方法用于在更改来源或其他设置后对音频/视频元素进行更新

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>奇葩天地网(www.qipa250.com)</title> 
</head> 
<body>
<video id="qipaVideo" controls autoplay>
    <source id="mp4_src" src="mov_bbb.mp4" type="video/mp4">
      <source id="ogg_src"  src="mov_bbb.ogg" type="video/ogg">
      您的浏览器不支持 video 标签。
</video>
<p>点击按钮修改视频资源,并重新加载。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction() {
    document.getElementById("mp4_src").src = "movie.mp4";
    document.getElementById("ogg_src").src = "movie.ogg";
    document.getElementById("qipaVideo").load();
}
</script>
<p>视频由<a href="http://www.qipa250.com/" target="_blank">Big Buck Bunny</a>奇葩</p>
</body>
</html>

https://www.cnblogs.com/xi-li/p/jquery.html
如题
参考https://blog.csdn.net/weixin_42519137/article/details/85159900



1 $(``'#img7'``).attr(``'src'``,isDefine(result[0].vedio)?result[0].vedio:``""``);

答案如下:
通过 jQuery 确实是给 source 的 src 赋值成功,从调试来看,浏览器并没有去发起请求去获得相应的视频,
而只是单纯的将 a 标签的 data-src 中的值赋值给 source 了。
因此,可以推断出来的是,当 video 中存在 source 标签的时候,浏览器渲染之后会自动去获取地址,即便地址改变,
浏览器也不会再去获取地址。但是通过动态的插入 source 标签的方式,可以触发浏览器进行重排,从而去获取相应地址的文件进行播放。
如果直接把标签替换掉的话,第一次是可以播放,但再切换别的src还是会显示第一个播放的视频的src。
所以,正确方法是连同video标签一起换了。

混流

音视频混流基本原理
https://cloud.tencent.com/developer/article/1494869
http://www.voidcn.com/article/p-ezpqnqdt-bqm.html

ckplayer

https://www.ckplayer.com/manual/14.html#m55

萤石云视频

萤石云视频接入:https://open.ys7.com/doc/zh/book/index/live_proto.html
配置链接:https://www.ckplayer.com/manual/12.html#m49
动态切换播放地址:https://blog.csdn.net/F_048731/article/details/108664943

code(rtmp):

    <video class="video_left" id="playerLeft" poster="" preload controls playsInline webkit-playsinline autoplay><br />            <source :src="videoList[0]" type="" /><br />        </video>

    handlePlay () {<br />            this.$nextTick(() => {<br />                this.playerLeft = new EZuikit.EZUIPlayer('playerLeft')<br />                this.playerRightTop = new EZuikit.EZUIPlayer('playerRightTop')<br />                this.playerRightCenter = new EZuikit.EZUIPlayer('playerRightCenter')<br />                this.playerRightBottom = new EZuikit.EZUIPlayer('playerRightBottom')<br />                try {<br />                    this.playerLeft.play()<br />                } catch (error) {<br />                    console.log(error)

code(live):

    <div class="video_left" id="playerLeft"></div><br />        <div><br />            <div class="video_right_item g-reset-video g-w" id="playerRightTop"></div><br />            <div class="video_right_item g-reset-video g-w" id="playerRightCenter"></div><br />            <div class="video_right_item g-reset-video g-w" id="playerRightBottom"></div><br />        </div>

import EZUIKit from “ezuikit-js”

        params: {<br />                autoplay: true,<br />                accessToken:'此处替换萤石云的token',<br />                template: 'simple' // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版;<br />                // 视频上方头部控件<br />                //header: ['capturePicture, 'save, 'zoom], // 如果templete参数不为simple,该字段将被覆盖<br />                //plugin: ['talk'],                       // 加载插件,talk-对讲<br />                // 视频下方底部控件<br />                // footer: [talk, 'broadcast, 'hd, 'fullScreen], // 如果template参数不为simple,该字段将被覆盖<br />                // audio: 1, // 是否默认开启声音 0 - 关闭 1 - 开启<br />                // openSoundCallBack: data => console.log('开启声音回调', data),<br />                // closeSoundCallBack: data => console.log('关闭声音回调', data),<br />                // startSaveCallBack: data => console.log('开始录像回调', data),<br />                // stopSaveCallBack: data => console.log('录像回调', data),<br />                // capturePictureCallBack: data => console.log('截图成功回调', data),<br />                // fullScreenCallBack: data => console.log('全屏回调', data),<br />                // getOSDTimeCallBack: data => console.log('获取OSDTime回调', data)<br />            },<br />            rightParams: {<br />                width: document.documentElement.clientWidth * .25,<br />                height: document.documentElement.clientHeight / 3<br />            },<br />            playerLeft: null,<br />            playerRightTop: null,<br />            playerRightCenter: null,<br />            playerRightBottom: null,<br />            videoList: []

    handlePlay (videoList) {<br />            this.playerLeft =  new EZUIKit.EZUIKitPlayer({<br />                ...this.params,<br />                id: 'playerLeft',<br />                url: videoList[0],<br />                width: document.documentElement.clientWidth * .75,<br />                height: document.documentElement.clientHeight<br />            })<br />            this.playerRightTop =  new EZUIKit.EZUIKitPlayer({<br />                ...this.params,<br />                ...this.rightParams,<br />                id: 'playerRightTop',<br />                url: videoList[1] || 'ezopen://open.ys7.com/D31988747/1.hd.live'<br />            })<br />            // this.player.play()<br />            // setTimeout(()=>{<br />            //   player.stop() // 方法调用示例,10秒后关闭视频<br />            // },10000)

腾讯云视频

官方文档:https://cloud.tencent.com/document/product/266/14603
技术文档:https://video.qcloud.com/download/docs/QVOD_Player_Web_SDK_Developer_Guide.pdf?_ga=1.91848537.279779573.1607480774
官方参数配置文档:https://cloud.tencent.com/document/product/454/7503#step-5.EF.BC.9A.E5.A4.9A.E6.B8.85.E6.99.B0.E5.BA.A6.E7.9A.84.E6.94.AF.E6.8C.81
TCPlayer腾讯云vod播放器开发文档整理edusoho:https://www.jianshu.com/p/7fcb35a08330
腾讯TcPlayer listener函数监听(

尝试5次拉流

https://www.yht7.com/news/98391
Web播放器 TcPlayer——腾讯直播sdk的网页播放器
https://www.cnblogs.com/stnlcd/p/7262034.html

code(rtmp/flv):









import { TcPlayer } from “tcplayer”
playerLeft: null,
playerRightTop: null,
playerRightCenter: null,
playerRightBottom: null,
videoList: [],
this.$nextTick(this.handleTcPlayer(‘playerLeft’, this.videoList[0], ‘’, 500, 700, 500))
handleTcPlayer (video, url, img, outTime = 500, width, height) {
let endUrl = ‘’
if (url && url.includes(‘.flv’)) endUrl = url
setTimeout(() => {
this[video] = new TcPlayer(video, {
// ‘m3u8’: ${url.replace('.flv', '')}.m3u8,
‘flv’: endUrl,
‘rtmp’: url,
‘autoplay’: true, // iOS 下 safari 浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
‘posterImage’: false,
‘poster’: img || ‘’,
// ‘width’: width, // 视频的显示宽度,请尽量使用视频分辨率宽度
// ‘height’: height, // 视频的显示高度,请尽量使用视频分辨率高度
‘h5flv’: true,
‘flash’: true,
‘live’: true,
‘x5_player’: true,
‘x5_type’: ‘h5-page’,
‘systemFullscreen’: true,
‘stretch_full’: true,
‘plugins’: {
ContinuePlay: {
auto: true
}
},
‘listener’: _msg
=> {
if (msg.type == ‘fullscreen’) {
if (!msg.detail.isFullscreen) {
this.handleResetOrder(video)
// sessionStorage.case = ‘changeVideo’
// sessionStorage.optionList = JSON.stringify(this.optionList)
// sessionStorage.optionItem = JSON.stringify(this.params)
// sessionStorage.videoList = JSON.stringify(this.videoList)
// location.reload()
}
}
}
})
}, outTime)
}

新增控制栏操作项

code:(后续修改load为重新new播放器-因为切换视频的重复问题)

handleResetBtn () {
let vcpBox = document.getElementsByClassName(‘vcp-controls-panel’)
let vcpMove = document.createElement(‘div’)
vcpMove.className = ‘vcp-move’
let dataCaseList = [‘playerRightTop’, ‘playerRightCenter’, ‘playerRightBottom’]
vcpBox.forEach((item, index) => {
if (index != 0) {
let addVcpMove = vcpMove.cloneNode(true)
addVcpMove.setAttribute(‘data-case’, dataCaseList[index - 1])
addVcpMove.setAttribute(‘data-index’, index)
addVcpMove.onclick = e => {
let dataCase = e.target.getAttribute(‘data-case’)
let dataIndex = parseInt(e.target.getAttribute(‘data-index’))
let tempUrl = this.videoList[dataIndex]
this.videoList[dataIndex] = this.videoList[0]
this.videoList[0] = tempUrl
if (tempUrl && !tempUrl.includes(‘.hd.flv’)) {
tempUrl = tempUrl.replace(‘.flv’, ‘.hd.flv’)
}
this.playerLeft.load(tempUrl)
this[dataCase].load(this.videoList[dataIndex])
window.event ? window.event.cancelBubble = true : e.stopPropagation()
e.preventDefault ? e.preventDefault() : window.event.returnValue == false
e.stopImmediatePropagation()
return false
}
if (!document.querySelector(‘div[data-case=playerRightBottom]’)) {
item.appendChild(addVcpMove)
}
}
})
},
.vcp-clarityswitcher {
display: none;
}

.vcp-move {
position: relative;
width: 3em;
height: 3em;
float: right;
cursor: pointer;
z-index: 1001;
background: url(‘../../assets/images/switchcaram.png’) no-repeat;
_background-size
: 100% 100%;
}

重新拉流

code

‘listener’: msg => {
if (msg.type == ‘load’ && video == ‘playerRightBottom’) {
this.handleResetBtn()
}
if (msg.type == ‘fullscreen’) {
this.counts[video] = 1
}
if(msg.type == ‘error’) {
console.log(msg, ‘播放报错’)
if (!this.counts[video]) {
this.counts[video] = 1
} else {
this.counts[video]++
}
// 可以尝试80次拉流
if (this[video] && this.counts[video] < 80) {
let timer = setTimeout(() => {
console.log(‘重试拉流’)
this[video] && this[video].load()
clearTimeout(timer)
}, 5000)
}
} else if (msg.type == “play”) {
console.log(msg, ‘拉流成功’)
}
}

去除console

原文:
如何屏蔽某个js文件中的 console
https://www.cnblogs.com/daysme/p/7153686.html
flv
http://imgcache.qq.com/open/qcloud/video/vcplayer/libs/flv.min.1.5.js
warn: Found another AVCDecoderConfigurationRecord!
log:[FLVDemuxer] > Parsed AVCDecoderConfigurationRecord
image.png

code(index.html):


去除缓存

code












headers: {
// ‘Content-Type’: ‘application/x-www-form-urlencoded’
‘Content-Type’: ‘application/json;charset=UTF-8’,
‘Cache-Control’: ‘no-cache’
},

添加轮询

浏览器内存过大导致不响应哦~,如果您要使用TCplater做多路监控播放器的话,建议您可以过端做个轮询,每几个小时重新初始化下页面或播放器哦~

code

created:
this.timer = setTimeout(() => {
clearTimeout(this.timer)
this.handleSaveCurrent()
}, 1.08e7)
handleSaveCurrent () {
sessionStorage.case = ‘saveCurrent’
sessionStorage.optionList = JSON.stringify(this.optionList)
sessionStorage.selectList = JSON.stringify(this.selectList)
sessionStorage.videoList = JSON.stringify(this.videoList)
sessionStorage.params = JSON.stringify(this.params)
location.reload()
},

视频加载失败

带宽问题

https://blog.csdn.net/weixin_33973600/article/details/93768580
测试视频观看并发量,发现了一个很严重的问题:带宽不足。9 或 10 个人同时观看视频的时候,就会出现有些用户加载不了视频的问题。

跨域问题

在播放器通过外链来播放视频的时候,发现出现跨域被拒绝的问题 (ERROR:HLSError(code/url/msg)=1tp:Cannot load M3U8: crossdomain access denied:Error #2048),google 了问题,发现原来Flash 播放器在加载跨域视频时,会先去加载云端的 corssdomain.xml 文件,然后判断是否被允许加载。
解决方法:需要在云端上传 crossdomian.xml 文件

<cross-domain-policy>
    <allow-access-from domain="*"/>
    <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

TBS视频播放器

https://x5.tencent.com/tbs/product/video.html