我有一个定制的JW Player 7 Pro嵌入在以下页面:http://dev.sharepoint-videos.com/jw-player-self-hosted/。
嵌入代码如下:
<!--Course Video, Scripts and Style-->
<div id="visualSPPlayer">Loading the player...</div>
<script type="text/javascript">
var playerInstance = jwplayer("visualSPPlayer");
playerInstance.setup({
file: "http://dbt8c2ssdzlxg.cloudfront.net/Search2013.mp4",
primary: "HTML5",
image: "https://assets-jpcust.jwpsrv.com/thumbs/2kOAeo0k-320.jpg?1443200073230",
width: "100%",
aspectratio: "16:9",
tracks: [
{
file: "http://dbt8c2ssdzlxg.cloudfront.net/captions/Search/Captions.srt",
label: "English",
kind: "captions",
},
{
file: 'http://dbt8c2ssdzlxg.cloudfront.net/chapters/Search/Chapters.vtt',
kind: 'chapters'
},
{
file: "http://dbt8c2ssdzlxg.cloudfront.net/thumbnails/search_thumbnails.vtt",
kind: "thumbnails"
}
],
skin: {
name: "vapor",
active: "#E16933",
inactive: "#E16933",
background: "#333333"
}
});
</script>
<script type="application/javascript" src="http://dev.sharepoint-videos.com/wp-content/themes/symplex-child/js/player.js"></script>
<link rel="stylesheet" href="http://dev.sharepoint-videos.com/wp-content/themes/symplex-child/css/player.css" type="text/css" media="screen"/>
player.js文件内容:
jQuery(document).ready(function () {
jQuery(function ($) {
var playerInstance = jwplayer();
var chapters = [];
var captions = [];
var toc = [];
var caption = -1;
var matches = [];
var seekArr = [];
var seekPos = [];
var seePos;
var query = "";
var cycle = -1;
var transcript = document.getElementById('courseTranscript');
var search = document.getElementById('courseSearch');
var match = document.getElementById('courseMatch');
var caption_file;
var chapter_file;
playerInstance.onReady(function () {
//Self-Hosted
caption_file = playerInstance.getPlaylist()[0].tracks[0].file;
chapter_file = playerInstance.getPlaylist()[0].tracks[1].file;
if (playerInstance.getRenderingMode() == "flash") {
return;
}
tag = document.querySelector('video');
tag.defaultPlaybackRate = 1.0;
tag.playbackRate = 1.0;
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/hare.png", "1.5x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 1.5;
}, "playerHighSpeed");
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/normal.png", "1.0x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 1.0;
}, "playerNormalSpeed");
playerInstance.addButton("http://dev.sharepoint-videos.com/wp-content/uploads/2015/09/snail.png", "0.5x", function () {
playerInstance.seek(playerInstance.getPosition());
tag.playbackRate = 0.5;
}, "playerSlowSpeed");
});
//Adds Player Focus on Playing
playerInstance.on('play', function () {
$('html, body').animate({
scrollTop: $(".jwplayer").offset().top - 190
}, 1000);
});
playerInstance.onReady(function () {
$.get(caption_file, function (data) {
data = data.trim();
var t = data.split("nrn");
for (var i = 0; i < t.length; i++) {
var c = parse(t[i]);
chapters.push(c);
}
loadCaptions();
loadChapters();
});
//
});
// Load chapters / captions
function loadCaptions() {
$.get(caption_file, function (data) {
data = data.trim();
var t = data.split("nrn");
t.pop();
var h = "<p>";
var s = 0;
for (var i = 0; i < t.length; i++) {
var c = parse(t[i]);
if (s < chapters.length && c.begin > chapters[s].begin) {
s++;
}
h += "<span id='caption" + i + "'>" + c.text + "</span>";
captions.push(c);
}
transcript.innerHTML = h + "</p>";
});
};
function parse(d) {
var a = d.split("n");
//console.log(a[1]);
var i = a[1].indexOf(' --> ');
var t = a[2]; //Caption text
if (a[3]) {
t += " " + a[3];
}
t = t.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return {
begin: seconds(a[1].substr(0, i)),
btext: a[1].substr(3, i - 7),
end: seconds(a[1].substr(i + 5)),
text: t
}
};
function seconds(s) {
var a = s.split(':');
secs = a[2].substring(0, a[2].indexOf(','));
var r = Number(secs) + Number(a[a.length - 2]) * 60;
if (a.length > 2) {
r += Number(a[a.length - 3]) * 3600;
}
return r;
};
function toc_seconds(s) {
var a = s.split(':');
secs = a[2].substring(0, a[2].indexOf('.'));
var r = Number(secs) + Number(a[a.length - 2]) * 60;
if (a.length > 2) {
r += Number(a[a.length - 3]) * 3600;
}
return r;
};
function toc_time(s) {
var a = s.split(':');
var ms = a[2].split(".");
var h = a[0];
if (h != "00") {
var r = a[0] + ":" + a[1] + ":" + ms[0];
} else {
var r = a[1] + ":" + ms[0];
}
return r;
};
// Highlight current caption and chapter
playerInstance.onTime(function (e) {
var p = e.position;
for (var j = 0; j < captions.length; j++) {
if (captions[j].begin < p && captions[j].end > p) {
if (j != caption) {
var c = document.getElementById('caption' + j);
if (caption > -1) {
document.getElementById('caption' + caption).className = "";
}
c.className = "current";
if (query == "") {
transcript.scrollTop = c.offsetTop - transcript.offsetTop - 40;
}
caption = j;
}
break;
}
}
});
// Hook up interactivity
transcript.addEventListener("click", function (e) {
if (e.target.id.indexOf("caption") == 0) {
var i = Number(e.target.id.replace("caption", ""));
playerInstance.seek(captions[i].begin);
}
});
/**/
search.addEventListener('focus', function (e) {
setTimeout(function () {
search.select();
}, 100);
resetSearch();
$("#prevMatchLink").hide();
$("#nextMatchLink").hide();
});
search.addEventListener('keydown', function (e) {
if (e.keyCode == 27) {
resetSearch();
$("#prevMatchLink").hide();
$("#nextMatchLink").hide();
} else if (e.keyCode == 13) {
$("#prevMatchLink").show();
$("#nextMatchLink").show();
var q = this.value.toLowerCase();
if (q.length > 0) {
if (q == query) {
if (cycle >= matches.length - 1) {
cycleSearch(0);
} else {
cycleSearch(cycle + 1);
}
} else {
resetSearch();
searchTranscript(q);
}
} else {
resetSearch();
}
} else if (e.keyCode == 37) {
cycleSearch(cycle - 1);
}
else if (e.keyCode == 39) {
cycleSearch(cycle + 1);
}
});
$("#prevMatchLink").click(function (e) {
e.preventDefault();
cycleSearch(cycle - 1);
});
$("#nextMatchLink").click(function (e) {
e.preventDefault();
cycleSearch(cycle + 1);
});
// Execute search
function searchTranscript(q) {
matches = [];
query = q;
for (var i = 0; i < captions.length; i++) {
var m = captions[i].text.toLowerCase().indexOf(q);
if (m > -1) {
document.getElementById('caption' + i).innerHTML =
captions[i].text.substr(0, m) + "<em>" +
captions[i].text.substr(m, q.length) + "</em>" +
captions[i].text.substr(m + q.length);
matches.push(i);
}
}
if (matches.length) {
cycleSearch(0);
} else {
resetSearch();
}
};
function cycleSearch(i) {
if (cycle > -1) {
var o = document.getElementById('caption' + matches[cycle]);
o.getElementsByTagName("em")[0].className = "";
}
var c = document.getElementById('caption' + matches[i]);
c.getElementsByTagName("em")[0].className = "current";
match.innerHTML = (i + 1) + " of " + matches.length;
transcript.scrollTop = c.offsetTop - transcript.offsetTop - 40;
cycle = i;
};
function resetSearch() {
if (matches.length) {
for (var i = 0; i < captions.length; i++) {
document.getElementById('caption' + i).innerHTML = captions[i].text;
}
}
query = "";
matches = [];
match.innerHTML = "0 of 0";
cycle = -1;
transcript.scrollTop = 0;
};
var videoTitle = $(".videoTitle").text();
var hasPlayed = false;
playerInstance.onBeforePlay(function (event) {
if (hasPlayed == false) {
ga('send', 'event', 'Video', 'Play', videoTitle);
hasPlayed = true;
}
});
//Can be used to trigger the Course to Marked Completed so the user doesn't have to
playerInstance.on('complete', function () {
});
function loadChapters() {
$.get(chapter_file, function (data) {
data = data.trim();
var c = data.split("nrn");
var d;
for (var i = 0; i < c.length; i++) {
d = c[i].split("n");
//pushes in Title for each chapter
toc.push(d[0]);
//pushes in the time intervals for each chapter
seekArr.push(d[1]);
};
for (var a = 0; a < seekArr.length; a++) {
//Splits the time interval and pushes the start interval for each chapter
var tempPos = seekArr[a].split(" --> ");
seekPos.push(tempPos[0]);
};
runTOC(seekPos);
var toc_output = "";
$.each(toc, function (i, v) {
toc_output += "<li class=ch" + i + "><a href='#' onclick='jwplayer().seek(" + toc_seconds(seekPos[i]) + ");'>" + v + "</a> (" + toc_time(seekPos[i]) + ")</li>"
});
if (toc.length < 7) {
toc_output += " <li class='blank'> </li><li class='blank'> </li>";
}
$(".courseTitles ul").html(toc_output);
});
};
function runTOC(x) {
playerInstance.onTime(function (event) {
for (var i = 0; i < x.length; i++) {
if (event.position > toc_seconds(x[i])) {
$(".courseTitles ul li").removeClass("active");
$(".courseTitles ul li.ch" + i).addClass('active');
}
};
});
}
});
});
我们正在使用Amazon Web Services与Cloudfront托管视频和章节/标题VTT文件。
我们已经包含了字幕中的交互式文本,以及视频准备播放时要加载的动态视频章节。
我注意到的一件事是,章节和文本并不总是加载,并且需要页面刷新几次,所以我认为这可能是AWS方面的缓存问题。
我使用过谷歌浏览器,当章节和成绩单不加载时,开发人员控制台没有错误。
应该注意的是,当我们使用JW平台云托管解决方案时,这个功能可以完美地工作,所以它似乎是AWS/Cloudfront CDN的一个因素。
function load_jwp_scripts() {
wp_enqueue_script('jwplayer-js', plugins_url( "/js/jwplayer.js", __FILE__), array(), '1.0', false);
wp_enqueue_script('jwplayer-license-js', plugins_url( "/js/jwplayer_license.js", __FILE__), array(), '1.0', false);
wp_enqueue_script('jwplayer-player-js', plugins_url( "/js/player.js", __FILE__), array('jquery'), '1.0', true);
}
add_action('wp_enqueue_scripts', 'load_jwp_scripts');
我找到了一个可行的解决方案。
问题是$(document)的使用。准备好声明。jwplayer.on("ready")不兼容。