203 lines
9.8 KiB
JavaScript
203 lines
9.8 KiB
JavaScript
export default function (playerInstance, options) {
|
|
playerInstance.setupThumbnailPreviewVtt = () => {
|
|
playerInstance.sendRequest(
|
|
playerInstance.displayOptions.layoutControls.timelinePreview.file,
|
|
true,
|
|
playerInstance.displayOptions.vastOptions.vastTimeout,
|
|
function () {
|
|
const convertVttRawData = function (vttRawData) {
|
|
if (!(
|
|
(typeof vttRawData.cues !== 'undefined') &&
|
|
(vttRawData.cues.length)
|
|
)) {
|
|
return [];
|
|
}
|
|
|
|
const result = [];
|
|
let tempThumbnailData = null;
|
|
let tempThumbnailCoordinates = null;
|
|
|
|
for (let i = 0; i < vttRawData.cues.length; i++) {
|
|
tempThumbnailData = vttRawData.cues[i].text.split('#');
|
|
let xCoords = 0, yCoords = 0, wCoords = 122.5, hCoords = 69;
|
|
|
|
// .vtt file contains sprite corrdinates
|
|
if (
|
|
(tempThumbnailData.length === 2) &&
|
|
(tempThumbnailData[1].indexOf('xywh=') === 0)
|
|
) {
|
|
tempThumbnailCoordinates = tempThumbnailData[1].substring(5);
|
|
tempThumbnailCoordinates = tempThumbnailCoordinates.split(',');
|
|
|
|
if (tempThumbnailCoordinates.length === 4) {
|
|
playerInstance.displayOptions.layoutControls.timelinePreview.spriteImage = true;
|
|
xCoords = parseInt(tempThumbnailCoordinates[0]);
|
|
yCoords = parseInt(tempThumbnailCoordinates[1]);
|
|
wCoords = parseInt(tempThumbnailCoordinates[2]);
|
|
hCoords = parseInt(tempThumbnailCoordinates[3]);
|
|
}
|
|
}
|
|
|
|
let imageUrl;
|
|
if (playerInstance.displayOptions.layoutControls.timelinePreview.spriteRelativePath
|
|
&& playerInstance.displayOptions.layoutControls.timelinePreview.file.indexOf('/') !== -1
|
|
&& (typeof playerInstance.displayOptions.layoutControls.timelinePreview.sprite === 'undefined' || playerInstance.displayOptions.layoutControls.timelinePreview.sprite === '')
|
|
) {
|
|
imageUrl = playerInstance.displayOptions.layoutControls.timelinePreview.file.substring(0, playerInstance.displayOptions.layoutControls.timelinePreview.file.lastIndexOf('/'));
|
|
imageUrl += '/' + tempThumbnailData[0];
|
|
} else {
|
|
imageUrl = (playerInstance.displayOptions.layoutControls.timelinePreview.sprite ? playerInstance.displayOptions.layoutControls.timelinePreview.sprite : tempThumbnailData[0]);
|
|
}
|
|
|
|
result.push({
|
|
startTime: vttRawData.cues[i].startTime,
|
|
endTime: vttRawData.cues[i].endTime,
|
|
image: imageUrl,
|
|
x: xCoords,
|
|
y: yCoords,
|
|
w: wCoords,
|
|
h: hCoords
|
|
});
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
const xmlHttpReq = this;
|
|
|
|
if ((xmlHttpReq.readyState === 4) && (xmlHttpReq.status !== 200)) {
|
|
//The response returned an error.
|
|
return;
|
|
}
|
|
|
|
if (!((xmlHttpReq.readyState === 4) && (xmlHttpReq.status === 200))) {
|
|
return;
|
|
}
|
|
|
|
const textResponse = xmlHttpReq.responseText;
|
|
|
|
const webVttParser = new window.WebVTTParser();
|
|
const vttRawData = webVttParser.parse(textResponse);
|
|
|
|
playerInstance.timelinePreviewData = convertVttRawData(vttRawData);
|
|
}
|
|
);
|
|
};
|
|
|
|
playerInstance.generateTimelinePreviewTags = () => {
|
|
const progressContainer = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
|
|
const previewContainer = document.createElement('div');
|
|
|
|
previewContainer.className = 'fluid_timeline_preview_container';
|
|
previewContainer.style.display = 'none';
|
|
previewContainer.style.position = 'absolute';
|
|
|
|
progressContainer.appendChild(previewContainer);
|
|
|
|
//Shadow is needed to not trigger mouseleave event, that stops showing thumbnails, in case one scrubs a bit too fast and leaves current thumb before new one drawn.
|
|
const previewContainerShadow = document.createElement('div');
|
|
previewContainerShadow.className = 'fluid_timeline_preview_container_shadow';
|
|
previewContainerShadow.style.position = 'absolute';
|
|
previewContainerShadow.style.display = 'none';
|
|
previewContainerShadow.style.opacity = 1;
|
|
progressContainer.appendChild(previewContainerShadow);
|
|
};
|
|
|
|
playerInstance.getThumbnailCoordinates = (second) => {
|
|
if (playerInstance.timelinePreviewData.length) {
|
|
for (let i = 0; i < playerInstance.timelinePreviewData.length; i++) {
|
|
if ((second >= playerInstance.timelinePreviewData[i].startTime) && (second <= playerInstance.timelinePreviewData[i].endTime)) {
|
|
return playerInstance.timelinePreviewData[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
playerInstance.drawTimelinePreview = (event) => {
|
|
const timelinePreviewTag = playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container');
|
|
const timelinePreviewShadow = playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container_shadow');
|
|
const progressContainer = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
|
|
const totalWidth = progressContainer.clientWidth;
|
|
|
|
if (playerInstance.isCurrentlyPlayingAd) {
|
|
if (timelinePreviewTag.style.display !== 'none') {
|
|
timelinePreviewTag.style.display = 'none';
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//get the hover position
|
|
const hoverX = playerInstance.getEventOffsetX(event, progressContainer);
|
|
let hoverSecond = null;
|
|
|
|
if (totalWidth) {
|
|
hoverSecond = playerInstance.currentVideoDuration * hoverX / totalWidth;
|
|
|
|
//get the corresponding thumbnail coordinates
|
|
const thumbnailCoordinates = playerInstance.getThumbnailCoordinates(hoverSecond);
|
|
timelinePreviewShadow.style.width = totalWidth + 'px';
|
|
timelinePreviewShadow.style.display = 'block';
|
|
|
|
if (thumbnailCoordinates !== false) {
|
|
timelinePreviewTag.style.width = thumbnailCoordinates.w + 'px';
|
|
timelinePreviewTag.style.height = thumbnailCoordinates.h + 'px';
|
|
timelinePreviewShadow.style.height = thumbnailCoordinates.h + 'px';
|
|
timelinePreviewTag.style.background =
|
|
'url(' + thumbnailCoordinates.image + ') no-repeat scroll -' + thumbnailCoordinates.x + 'px -' + thumbnailCoordinates.y + 'px';
|
|
timelinePreviewTag.style.left = hoverX - (thumbnailCoordinates.w / 2) + 'px';
|
|
timelinePreviewTag.style.display = 'block';
|
|
if (!playerInstance.displayOptions.layoutControls.timelinePreview.spriteImage) {
|
|
timelinePreviewTag.style.backgroundSize = 'contain';
|
|
}
|
|
|
|
} else {
|
|
timelinePreviewTag.style.display = 'none';
|
|
}
|
|
}
|
|
};
|
|
|
|
playerInstance.setupThumbnailPreview = () => {
|
|
let timelinePreview = playerInstance.displayOptions.layoutControls.timelinePreview;
|
|
if (!timelinePreview || !timelinePreview.type) {
|
|
return;
|
|
}
|
|
|
|
let eventOn = 'mousemove';
|
|
let eventOff = 'mouseleave';
|
|
if (playerInstance.mobileInfo.userOs) {
|
|
eventOn = 'touchmove';
|
|
eventOff = 'touchend';
|
|
}
|
|
playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container')
|
|
.addEventListener(eventOn, playerInstance.drawTimelinePreview.bind(playerInstance), false);
|
|
playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container')
|
|
.addEventListener(eventOff, function (event) {
|
|
const progress = playerInstance.domRef.wrapper.querySelector('.fluid_controls_progress_container');
|
|
if (typeof event.clientX !== 'undefined' && progress.contains(document.elementFromPoint(event.clientX, event.clientY))) {
|
|
//False positive (Chrome bug when fast click causes leave event)
|
|
return;
|
|
}
|
|
playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container').style.display = 'none';
|
|
playerInstance.domRef.wrapper.querySelector('.fluid_timeline_preview_container_shadow').style.display = 'none';
|
|
}, false);
|
|
playerInstance.generateTimelinePreviewTags();
|
|
|
|
if ('VTT' === timelinePreview.type && typeof timelinePreview.file === 'string') {
|
|
import(/* webpackChunkName: "webvtt" */ '../../vendor/webvtt').then((it) => {
|
|
window.WebVTTParser = it.default;
|
|
playerInstance.setupThumbnailPreviewVtt();
|
|
});
|
|
} else if ('static' === timelinePreview.type && typeof timelinePreview.frames === 'object') {
|
|
timelinePreview.spriteImage = true;
|
|
playerInstance.timelinePreviewData = timelinePreview.frames;
|
|
} else {
|
|
throw 'Invalid thumbnail-preview - type must be VTT or static';
|
|
}
|
|
|
|
playerInstance.showTimeOnHover = false;
|
|
};
|
|
}
|