1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-06 03:50:04 +02:00
Oinktube/node_modules/videojs-ima/src/dai/sdk-impl.js
2022-06-30 12:14:30 -03:00

356 lines
9.5 KiB
JavaScript

/**
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
/**
* Implementation of the IMA DAI SDK for the plugin.
*
* @param {DaiController!} daiController Reference to the parent DAI
* controller.
*
* @constructor
* @struct
* @final
*/
const SdkImpl = function(daiController) {
/**
* Plugin DAI controller.
*/
this.daiController = daiController;
/**
* The html5 stream player.
*/
this.streamPlayer = null;
/**
* The videoJS stream player.
*/
this.vjsPlayer = null;
/**
* IMA SDK StreamManager
*/
this.streamManager = null;
/**
* IMA stream UI settings.
*/
/* eslint no-undef: 'error' */
/* global google */
this.uiSettings = new google.ima.dai.api.UiSettings();
/**
* If the stream is currently in an ad break.
*/
this.isAdBreak = false;
/**
* If the stream is currently seeking from a snapback.
*/
this.isSnapback = false;
/**
* Originally seeked to time, to return stream to after ads.
*/
this.snapForwardTime = 0;
/**
* Timed metadata for the stream.
*/
this.timedMetadata;
/**
* Timed metadata record.
*/
this.metadataLoaded = {};
this.SOURCE_TYPES = {
hls: 'application/x-mpegURL',
dash: 'application/dash+xml',
};
};
/**
* Creates and initializes the IMA DAI SDK objects.
*/
SdkImpl.prototype.initImaDai = function() {
this.streamPlayer = this.daiController.getStreamPlayer();
this.vjsPlayer = this.daiController.getVjsPlayer();
this.createAdUiDiv();
if (this.daiController.getSettings().locale) {
this.uiSettings.setLocale(this.daiController.getSettings().locale);
}
this.streamManager = new google.ima.dai.api.StreamManager(
this.streamPlayer,
this.adUiDiv,
this.uiSettings);
this.streamPlayer.addEventListener('pause', this.onStreamPause);
this.streamPlayer.addEventListener('play', this.onStreamPlay);
this.streamManager.addEventListener(
[
google.ima.dai.api.StreamEvent.Type.LOADED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED,
],
this.onStreamEvent.bind(this),
false);
this.vjsPlayer.textTracks().onaddtrack = this.onAddTrack.bind(this);
this.vjsPlayer.trigger({
type: 'stream-manager',
StreamManager: this.streamManager,
});
this.requestStream();
};
/**
* Called when the video player has metadata to process.
* @param {Event!} event The event that triggered this call.
*/
SdkImpl.prototype.onAddTrack = function(event) {
const track = event.track;
if (track.kind === 'metadata') {
track.mode = 'hidden';
track.oncuechange = (e) => {
for (const cue of track.activeCues_) {
const metadata = {};
metadata[cue.value.key] = cue.value.data;
this.streamManager.onTimedMetadata(metadata);
}
};
}
};
/**
* Creates the ad UI container.
*/
SdkImpl.prototype.createAdUiDiv = function() {
const uiDiv = document.createElement('div');
uiDiv.id = 'ad-ui';
// 3em is the height of the control bar.
uiDiv.style.height = 'calc(100% - 3em)';
this.streamPlayer.parentNode.appendChild(uiDiv);
this.adUiDiv = uiDiv;
};
/**
* Called on pause to update the ad UI.
*/
SdkImpl.prototype.onStreamPause = function() {
if (this.isAdBreak) {
this.adUiDiv.style.display = 'none';
}
};
/**
* Called on play to update the ad UI.
*/
SdkImpl.prototype.onStreamPlay = function() {
if (this.isAdBreak) {
this.adUiDiv.style.display = 'block';
}
};
/**
* Called on play to update the ad UI.
* @param {number} currentTime the current time of the stream.
*/
SdkImpl.prototype.onSeekEnd = function(currentTime) {
const streamType = this.daiController.getSettings().streamType;
if (streamType === 'live') {
return;
}
if (this.isSnapback) {
this.isSnapback = false;
return;
}
const previousCuePoint =
this.streamManager.previousCuePointForStreamTime(currentTime);
if (previousCuePoint && !previousCuePoint.played) {
this.isSnapback = true;
this.snapForwardTime = currentTime;
this.vjsPlayer.currentTime(previousCuePoint.start);
}
};
/**
* Handles IMA events.
* @param {google.ima.StreamEvent!} event the IMA event
*/
SdkImpl.prototype.onStreamEvent = function(event) {
switch (event.type) {
case google.ima.dai.api.StreamEvent.Type.LOADED:
this.loadUrl(event.getStreamData().url);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
window.console.warn('Error loading stream, attempting to play backup ' +
'stream. ' + event.getStreamData().errorMessage);
this.daiController.onErrorLoadingAds(event);
if (this.daiController.getSettings().fallbackStreamUrl) {
this.loadurl(this.daiController.getSettings().fallbackStreamUrl);
}
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
this.isAdBreak = true;
this.adUiDiv.style.display = 'block';
this.daiController.onAdBreakStart();
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
this.isAdBreak = false;
this.adUiDiv.style.display = 'none';
this.daiController.onAdBreakEnd();
if (this.snapForwardTime && this.snapForwardTime >
this.vjsPlayer.currentTime()) {
this.vjsPlayer.currentTime(this.snapForwardTime);
this.snapForwardTime = 0;
}
break;
default:
break;
}
};
/**
* Loads the stream URL .
* @param {string} streamUrl the URL for the stream being loaded.
*/
SdkImpl.prototype.loadUrl = function(streamUrl) {
this.vjsPlayer.ready(function() {
const streamFormat = this.daiController.getSettings().streamFormat;
this.vjsPlayer.src({
src: streamUrl,
type: this.SOURCE_TYPES[streamFormat],
});
const bookmarkTime = this.daiController.getSettings().bookmarkTime;
if (bookmarkTime) {
const startTime =
this.streamManager.streamTimeForContentTime(bookmarkTime);
// Seeking on load triggers the onSeekEnd event, so treat this seek as
// if it's snapback. Without this, resuming at a bookmark kicks you
// back to the ad before the bookmark.
this.isSnapback = true;
this.vjsPlayer.currentTime(startTime);
}
}.bind(this));
};
/**
* Creates the AdsRequest and request ads through the AdsLoader.
*/
SdkImpl.prototype.requestStream = function() {
let streamRequest;
const streamType = this.daiController.getSettings().streamType;
if (streamType === 'vod') {
streamRequest = new google.ima.dai.api.VODStreamRequest();
streamRequest.contentSourceId = this.daiController.getSettings().cmsId;
streamRequest.videoId = this.daiController.getSettings().videoId;
} else if (streamType === 'live') {
streamRequest = new google.ima.dai.api.LiveStreamRequest();
streamRequest.assetKey = this.daiController.getSettings().assetKey;
} else {
window.console.warn('No valid stream type selected');
}
streamRequest.format = this.daiController.getSettings().streamFormat;
if (this.daiController.getSettings().apiKey) {
streamRequest.apiKey = this.daiController.getSettings().apiKey;
}
if (this.daiController.getSettings().authKey) {
streamRequest.authKey = this.daiController.getSettings().authKey;
}
if (this.daiController.getSettings().adTagParameters) {
streamRequest.adTagParameters =
this.daiController.getSettings().adTagParameters;
}
if (this.daiController.getSettings().streamActivityMonitorId) {
streamRequest.streamActivityMonitorId =
this.daiController.getSettings().streamActivityMonitorId;
}
if (this.daiController.getSettings().omidMode) {
streamRequest.omidAccessModeRules = {};
const omidValues = this.daiController.getSettings().omidMode;
if (omidValues.FULL) {
streamRequest.omidAccessModeRules[google.ima.OmidAccessMode.FULL] =
omidValues.FULL;
}
if (omidValues.DOMAIN) {
streamRequest.omidAccessModeRules[google.ima.OmidAccessMode.DOMAIN] =
omidValues.DOMAIN;
}
if (omidValues.LIMITED) {
streamRequest.omidAccessModeRules[google.ima.OmidAccessMode.LIMITED] =
omidValues.LIMITED;
}
}
this.streamManager.requestStream(streamRequest);
this.vjsPlayer.trigger({
type: 'stream-request',
StreamRequest: streamRequest,
});
};
/**
* Initiates IMA when the player is ready.
*/
SdkImpl.prototype.onPlayerReady = function() {
this.initImaDai();
};
/**
* Reset the StreamManager when the player is disposed.
*/
SdkImpl.prototype.onPlayerDisposed = function() {
if (this.streamManager) {
this.streamManager.reset();
}
};
/**
* Returns the instance of the StreamManager.
* @return {google.ima.StreamManager!} The StreamManager being used by the
* plugin.
*/
SdkImpl.prototype.getStreamManager = function() {
return this.StreamManager;
};
/**
* Reset the SDK implementation.
*/
SdkImpl.prototype.reset = function() {
if (this.StreamManager) {
this.StreamManager.reset();
}
};
export default SdkImpl;