'use strict'; (function ($, videojs, undefined) { // default setting var defaultSetting = { markerStyle: { 'width': '8px', 'border-radius': '30%', 'background':'url(/ananas/modules/video/marker/point.png) no-repeat center center', 'background-size':'100%' }, markerStyle2: { 'width': '8px', 'border-radius': '30%', 'background':'url(/ananas/modules/video/marker/point2.png) no-repeat center center', 'background-size':'100%' }, markerTip: { display: true, text: function text(marker) { return "Break: " + marker.text; }, time: function time(marker) { return marker.time; }, timeFormat: function timeFormate(marker) { var a = marker.time; if (a < 0) { return "NaN"; } var hh = parseInt(a / 3600); if (hh == 0) { hh = ""; } else { hh = hh < 10 ? "0" + hh : hh; } var mm = parseInt((a - hh * 3600) / 60); if (mm < 10) { mm = "0" + mm; } var ss = parseInt((a - hh * 3600) % 60); if (ss < 10) { ss = "0" + ss; } return hh > 0 ? hh + ":" + mm + ":" + ss : mm + ":" + ss; }, timeFormat1: function timeFormat1(a) { if (a < 0) { return "NaN"; } var hh = parseInt(a / 3600); if (hh == 0) { hh = ""; } else { hh = hh < 10 ? "0" + hh : hh; } var mm = parseInt((a - hh * 3600) / 60); if (mm < 10) { mm = "0" + mm; } var ss = parseInt((a - hh * 3600) % 60); if (ss < 10) { ss = "0" + ss; } return hh > 0 ? hh + ":" + mm + ":" + ss : mm + ":" + ss; } }, breakOverlay: { display: false, displayTime: 3, text: function text(marker) { return "Break overlay: " + marker.overlayText; }, style: { 'width': '100%', 'height': '20%', 'background-color': 'rgba(0,0,0,0.7)', 'color': 'white', 'font-size': '17px' } }, onMarkerClick: function onMarkerClick(marker) {}, onMarkerReached: function onMarkerReached(marker, index) {}, markers: [] }; // create a non-colliding random number function generateUUID() { var d = new Date().getTime(); var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : r & 0x3 | 0x8).toString(16); }); return uuid; }; var NULL_INDEX = -1; function registerVideoJsMarkersPlugin(options) { /** * register the markers plugin (dependent on jquery) */ var setting = $.extend(true, {}, defaultSetting, options), markersMap = {}, markersList = [], // list of markers sorted by time videoWrapper = $(this.el()), currentMarkerIndex = NULL_INDEX, player = this, markerTip = null, breakOverlay = null, overlayIndex = NULL_INDEX; function sortMarkersList() { // sort the list by time in asc order markersList.sort(function (a, b) { return setting.markerTip.time(a) - setting.markerTip.time(b); }); } function addMarkers(newMarkers) { newMarkers.forEach(function (marker) { marker.key = generateUUID(); if(marker.type == "KnowledgePoint" && marker.endTime > 0) { videoWrapper.find('.vjs-progress-holder').append(createMarkerDiv(marker)).append(createPeriodDiv(marker)); }else { videoWrapper.find('.vjs-progress-holder').append(createMarkerDiv(marker)); } // store marker in an internal hash map markersMap[marker.key] = marker; markersList.push(marker); }); sortMarkersList(); } function getPosition(marker) { return setting.markerTip.time(marker) / player.duration() * 100; } function getTipPosition(marker) { var percent = setting.markerTip.time(marker) / player.duration(); if (percent * setting.vjsProgressWidth < parseFloat(markerTip.width()) / 2) { return "-20px"; } else if (percent * setting.vjsProgressWidth + parseFloat(markerTip.width()) / 2 > setting.vjsProgressWidth){ return setting.vjsProgressWidth - parseFloat(markerTip.width()) / 2 + "px"; } else { return setting.markerTip.time(marker) / player.duration() * 100 + "%"; } } function getTipMarginLeft(marker) { var percent = setting.markerTip.time(marker) / player.duration(); if (percent * setting.vjsProgressWidth < parseFloat(markerTip.width()) / 2) { return "0px"; } else { return -parseFloat(markerTip.outerWidth()) / 2 + 'px'; } } function createMarkerDiv(marker) { var markerDiv = $("
"); var styleStr = setting.markerStyle; if(marker.text == "片头" || marker.text == "片尾") { styleStr = setting.markerStyle2; } markerDiv.css(styleStr).css({ "margin-left": -parseFloat(markerDiv.css("width")) / 2 + 'px', "left": getPosition(marker) + '%' }).attr("data-marker-key", marker.key).attr("data-marker-time", setting.markerTip.time(marker)); // add user-defined class to marker if (marker.class) { markerDiv.addClass(marker.class); } // bind click event to seek to marker time markerDiv.on('click', function (e) { var preventDefault = false; if (typeof setting.onMarkerClick === "function") { // if return false, prevent default behavior preventDefault = setting.onMarkerClick(marker) === false; } if (!preventDefault) { var key = $(this).data('marker-key'); player.currentTime(setting.markerTip.time(markersMap[key])); } }); if (setting.markerTip.display) { registerMarkerTipHandler(markerDiv); } return markerDiv; } function createPeriodDiv(marker) { var periodDiv = $(''); var left = getPosition(marker); var right = marker.endTime / player.duration() * 100; var width = right - left; periodDiv.css({ "margin-left": '-4px', "left": left + '%', "width": width + "%" }).attr("data-marker-key", marker.key); if (setting.markerTip.display) { registerPeriodTipHandler(periodDiv); } return periodDiv; } function updateMarkers() { // update UI for markers whose time changed markersList.forEach(function (marker) { var markerDiv = videoWrapper.find(".vjs-marker[data-marker-key='" + marker.key + "']"); var markerTime = setting.markerTip.time(marker); if (markerDiv.data('marker-time') !== markerTime) { markerDiv.css({ "left": getPosition(marker) + '%' }).attr("data-marker-time", markerTime); } }); sortMarkersList(); } function removeMarkers(indexArray) { // reset overlay if (!!breakOverlay) { overlayIndex = NULL_INDEX; breakOverlay.css("visibility", "hidden"); } currentMarkerIndex = NULL_INDEX; var deleteIndexList = []; indexArray.forEach(function (index) { var marker = markersList[index]; if (marker) { // delete from memory delete markersMap[marker.key]; deleteIndexList.push(index); // delete from dom videoWrapper.find(".vjs-marker[data-marker-key='" + marker.key + "']").remove(); } }); // clean up markers array deleteIndexList.reverse(); deleteIndexList.forEach(function (deleteIndex) { markersList.splice(deleteIndex, 1); }); // sort again sortMarkersList(); } // attach hover event handler function registerMarkerTipHandler(markerDiv) { markerDiv.on('mouseover', function () { var marker = markersMap[$(markerDiv).data('marker-key')]; if (!!markerTip) { var sTime = setting.markerTip.timeFormat(marker); var left = getTipPosition(marker); var endText = ''; if (marker.type == "KnowledgePoint" && marker.endTime > 0) { endText = '-' + setting.markerTip.timeFormat1(marker.endTime); } var textDiv = '