是否可以强制VideoJS停止流式传输不再将主要焦点放在页面上或已暂停的视频?例如,如果我加载了两个视频,然后决定将其中一个视频全屏显示,从而使另一个视频失去焦点,或者如果我切换了标签页又都失去了焦点,我不仅希望暂停视频播放,而且要阻止播放器继续播放(通过xhr)下载视频流。
在需要时调用play
和pause
方法很简单,但是我还没有想办法也可以暂停这种流式传输-任何人都可以提出建议。我喜欢删除视频src
属性,因为看到某处提到了该属性,但这会导致一些错误,并且无法解决问题。
最初,我使用的是HLS代码(videojs-contrib-hls.js
),但在某处读到使用http流代码(videojs-http-streaming.js
)可能更好〜达到相同的结果。
使用videojs streaming test page播放时,默认播放列表不会显示此行为,但是其他播放列表的确会导致这种下载行为。
下面的代码是真实代码的伪传真,但是可以正常再现错误。当任一视频最大化和/或两个视频都暂停时,您可以在控制台中观察网络请求。
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Stop VideoJS buffering other videos that do not have focus</title>
<link href='https://unpkg.com/video.js/dist/video-js.css' rel='stylesheet' />
<style>
body,body *{box-sizing:border-box;}
div.container{ width:600px; height:400px; margin:1rem; display:inline-block;clear:none; padding:0; }
video{max-width:600px;max-height:400px;opacity:1}
[type='button'].play{ width:100%; padding:1rem; margin:auto; float:none; position:relative; top:130px; }
[type='button'][name='ctrl']{position:absolute;top:0;left:0}
</style>
<script src='//cdnjs.cloudflare.com/ajax/libs/video.js/7.7.1/video.min.js'></script>
<script src='//unpkg.com/@videojs/http-streaming/dist/videojs-http-streaming.js'></script>
<script>
document.addEventListener('DOMContentLoaded',()=>{
let urls=[
'https://edge1.dashmedia.tv/onestudio/gonefishing/playlist.m3u8?fluxustv.m3u8',
'https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8'
];
let players={};
let videos={};
const maximise=function(e){
let player=players[ this.previousElementSibling.id ];
player.requestFullscreen();
};
/*
For any video currently playing that is NOT fullscreen
or not visible ( calculated by IntersectionObserver not shown here )
should be paused and the network stream should be stopped
for the duration. How?
The methods below cause errors. Simply using `player.pause()` will
happily pause the video but it will continue to stream the file
and so causing excessive network usage for hidden items.
*/
document.addEventListener( 'fullscreenchange', event=>{
let player;
let video;
const isFullscreen=function(){
return document.fullscreenElement!==null;
};
Object.keys( videos ).map( id =>{
player=players[ id ];
video=videos[ id ];
if( video && video != event.target.querySelector('video') ){
if( isFullscreen() )player.pause();
else player.play();
}
console.info('%cPlayer:%s Paused:%s','color:yellow;background:fuchsia;',id,player.paused());
});
});
/* event listener to play/stop videos */
document.querySelector('input[name="ctrl"]').addEventListener('click', function(e){
urls.forEach( ( url, index )=>{
let id='player_'+index;
let oCont=document.createElement('div');
oCont.className='container';
let oVideo=document.createElement('video');
oVideo.id=id;
oVideo.width=600;
oVideo.width=400;
let oBttn=document.createElement('input');
oBttn.className='play';
oBttn.type='button';
oBttn.value='Maximise';
oBttn.onclick=maximise;
oCont.appendChild( oVideo );
oCont.appendChild( oBttn );
document.body.appendChild( oCont );
let video_options={
'controls':true,
'autoplay':true,
'preload':'auto',
'muted':true,
children:[]
};
let video=window.player = videojs( id, video_options );
video.src({ src:url, type:'application/x-mpegURL' } );
video.ready( ()=>{
video.name=id;
video.errorDisplay=false;
video.play();
});
video.on('error',function(e){
e.stopImmediatePropagation();
console.info( '%cError:%s\nCode:%s', 'background:lime;color:black;', this.error().message, this.error().code )
video.dispose();
})
players[ id ]=video;
videos[ id ]=oVideo;
});//end forEach
});//end play click handler
});//end listener
</script>
</head>
<body>
<input type='button' name='ctrl' value='Play videos' />
</body>
</html>