基本上,我有两个标签,一个是隐藏的,一个是显示的。
隐藏的视频将在后台加载视频,当前一个视频完成后,我会通过隐藏显示的视频来交换两个视频。
我还将在服务器端列出可播放的视频列表,我将使用ajax获取列表并决定下一个要加载的列表。
无论如何你很难尝试这个,因为你需要有一个视频服务器,我发现很难砍掉代码,所以我只会告诉你整个源代码(带一些注释),希望你能理解。
我使用了jquery和video.js。源代码如下,
HTML:
<div class="container" id="video-container-1">
</div>
<div class="container" id="video-container-2">
</div>
使用Javascript:
//I am making a live video by chopping the video into MP4 files of 800ms each
//The play rate has to be adjustable or the local browser and live server will not sync
var play_rate = { 1.0:800, 1.01:790, 1.02:785, 1.03:777, 1.04:770, 1.05:762, 1.06:755, 1.07:748,
1.08:741, 1.09:734, 1.1:727 };
var min_rate=1.0;
var max_rate=1.1;
var base_rate = 1.03;
var current_rate = base_rate;
var timer_value = play_rate[current_rate];
var key_to_play;
var timer_id;
var newest_key;
var video_server_address = "192.168.100.1:20001";
var current_play = 1;
var container = new Array();
var player = new Array;
function video_html(container_id, id) {
return '<video id="video-js-' + container_id + '" class="video-js vjs-default-skin" ' +
' preload="auto" width="960" height="540" crossorigin="anonymous" ' +
'data-setup=\'{"example_option":true}\'>' +
'\t<source src="http://' + video_server_address +'/live/' + id + '.mp4" type="video/mp4" /> \n' +
'\t\t<track id="video-vtt" kind="subtitle" label="english" srclang="en" src="http://' + video_server_address + '/live/' + id + '.vtt" default></track>\n ' +
'\t\t<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>\n' +
'</video>';
}
function play_next()
{
var next_play;
if (current_play == 1)
next_play = 2;
else
next_play = 1;
player[next_play - 1].play();
container[next_play - 1].show();
container[current_play - 1].hide();
if (player[current_play - 1])
player[current_play - 1].dispose();
key_to_play++;
//switch current & next
current_play = next_play;
timer_id = setTimeout(function() {
play_next();
}, timer_value);
//Assuming get list + load video < 700ms
$.get("http://" + video_server_address + "/live/list",
function(list){
keys = list["keys"];
newest_key = keys[keys.length - 1];
console.log("key_to_play: " + key_to_play + " newest_key: " + newest_key);
var next_play;
if (current_play == 1)
next_play = 2;
else
next_play = 1;
//-----------------begin-------------------
//not really useful to you because these are just
//to let the video play sync with video server, we can safely
//remove these but the video play will out of sync after some time
if (key_to_play > newest_key)
{
//too fast
//make it slower?
if (current_rate > min_rate)
{
current_rate = current_rate - 0.01;
timer_value = play_rate[current_rate];
}
else
{
//it is already 1.0 (the slowest settings)
//have to crop on the timer_value
timer_value = play_rate[current_rate] + 5 * (key_to_play - newest_key);
}
//either wait or play again? just play again and test for stability first
key_to_play = newest_key;
}
else if (key_to_play == newest_key || key_to_play == newest_key - 1)
{
//the best situation we got
//don't change anything
}
else
{
//a little slow
if (current_rate < max_rate)
{
current_rate = current_rate + 0.01;
timer_value = play_rate[current_rate];
}
else
{
timer_value = play_rate[current_rate] - 5 * (newest_key - key_to_play);
}
//tooo slow, drop 4 * 800ms data
if (newest_key - key_to_play > 5)
{
key_to_play = newest_key - 1;
}
}
//-------------------end------------
container[next_play - 1].html(video_html(next_play, key_to_play));
player[next_play - 1] = videojs('video-js-' + next_play, {}, function(){
// Player (this) is initialized and ready.
//the following is only to make the browser show subtitle
//without this, the FF will not show subtitle by default
$('#video-container-' + next_play + " div.vjs-subtitles-button li.vjs-menu-item").eq(1).trigger('click');
});
player[next_play - 1].playbackRate(current_rate);
console.log(timer_value);
}
);
}
$( document ).ready(function() {
$.get("http://" + video_server_address + "/live/list", function(list){
keys = list["keys"];
key_to_play = keys[keys.length - 2];
newest_key = keys[keys.length - 1];
container[0] = $("div#video-container-1");
container[1] = $("div#video-container-2");
container[0].hide();
container[1].html(video_html(2, key_to_play));
player[0] = null;
player[1] = videojs("video-js-2",{}, function(){
// Player (this) is initialized and ready.
console.log($("#video-container-2 div.vjs-subtitles-button li.vjs-menu-item").eq(1).text());
$("#video-container-2 div.vjs-subtitles-button li.vjs-menu-item").eq(1).trigger('click');
});
player[1].playbackRate(current_rate);
play_next();
});
});
</script>
此代码在chrome和FF上运行良好,但是,在尝试使用IE11时,新视频无法加载,它将每800毫秒在两个视频(比如视频1和2)之间切换,我认为它会加载后者其中(3,4,5等),但它不会播放,只是继续播放1和2以及1和2。
当我尝试调试它时,我打开IE11开发工具,然后当开发工具准备就绪时,IE11将运行良好。
只要我关闭开发工具,IE11就会糟透了。
我想也许IE11做了一些优化并优化了一些代码?我怎么检查呢?
感谢。
答案 0 :(得分:15)
取自对原始问题的评论:
Why does JavaScript only work after opening developer tools in IE once?
对于OP来说,这是他的Ajax请求的缓存导致了这个问题。通过禁用缓存解决:
$.ajax({cache: false, ...})
答案 1 :(得分:5)
当您使用以下代码时
console.log("key_to_play: " + key_to_play + " newest_key: " + newest_key);
在这里你应该检查控制台对象是否存在,当你按F12时,它会自动创建控制台对象,你应该这样写它
if (typeof console == "object") {
console.log("key_to_play: " + key_to_play + " newest_key: " + newest_key);
}
else{
//do nothing`enter code here`
}
答案 2 :(得分:0)
这个答案是针对IE中的相同行为(缓存ajkax调用)但是使用AngularJS而不是JQuery。我会在这里发布,这样可以帮助像我这样的另一个人。
我们发现IE在某些页面上效果不佳,除非DevTools(F12)第一次处于活动状态。最后,感谢这个问题,我注意到IE正在缓存JS GET调用。因此,在使用angular时,为了避免这种行为,你应该这样做:
$httpProvider.defaults.headers.common['If-Modified-Since'] = '0';