docker-multiview/public/js/videojs.youtube.min.js
Martin Donnelly 42a9be107e init
2022-07-07 11:38:15 +01:00

545 lines
18 KiB
JavaScript

(function (root, factory) {
if (typeof exports === "object" && typeof module !== "undefined") {
var videojs = require("video.js");
module.exports = factory(videojs.default || videojs)
} else if (typeof define === "function" && define.amd) {
define(["videojs"], function (videojs) {
return root.Youtube = factory(videojs)
})
} else {
root.Youtube = factory(root.videojs)
}
})(this, function (videojs) {
"use strict";
var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_NATIVE_ANDROID;
var Tech = videojs.getTech("Tech");
var Youtube = videojs.extend(Tech, {
constructor: function (options, ready) {
Tech.call(this, options, ready);
this.setPoster(options.poster);
this.setSrc(this.options_.source, true);
this.setTimeout(function () {
if (this.el_) {
this.el_.parentNode.className += " vjs-youtube";
if (_isOnMobile) {
this.el_.parentNode.className += " vjs-youtube-mobile"
}
if (Youtube.isApiReady) {
this.initYTPlayer()
} else {
Youtube.apiReadyQueue.push(this)
}
}
}.bind(this))
}, dispose: function () {
if (this.ytPlayer) {
if (this.ytPlayer.stopVideo) {
this.ytPlayer.stopVideo()
}
if (this.ytPlayer.destroy) {
this.ytPlayer.destroy()
}
} else {
var index = Youtube.apiReadyQueue.indexOf(this);
if (index !== -1) {
Youtube.apiReadyQueue.splice(index, 1)
}
}
this.ytPlayer = null;
this.el_.parentNode.className = this.el_.parentNode.className.replace(" vjs-youtube", "").replace(" vjs-youtube-mobile", "");
this.el_.parentNode.removeChild(this.el_);
Tech.prototype.dispose.call(this)
}, createEl: function () {
var div = document.createElement("div");
div.setAttribute("id", this.options_.techId);
div.setAttribute("style", "width:100%;height:100%;top:0;left:0;position:absolute");
div.setAttribute("class", "vjs-tech");
var divWrapper = document.createElement("div");
divWrapper.appendChild(div);
if (!_isOnMobile && !this.options_.ytControls) {
var divBlocker = document.createElement("div");
divBlocker.setAttribute("class", "vjs-iframe-blocker");
divBlocker.setAttribute("style", "position:absolute;top:0;left:0;width:100%;height:100%");
divBlocker.onclick = function () {
this.pause()
}.bind(this);
divWrapper.appendChild(divBlocker)
}
return divWrapper
}, initYTPlayer: function () {
var playerVars = {controls: 0, modestbranding: 1, rel: 0, showinfo: 0, loop: this.options_.loop ? 1 : 0};
if (typeof this.options_.autohide !== "undefined") {
playerVars.autohide = this.options_.autohide
}
if (typeof this.options_["cc_load_policy"] !== "undefined") {
playerVars["cc_load_policy"] = this.options_["cc_load_policy"]
}
if (typeof this.options_.ytControls !== "undefined") {
playerVars.controls = this.options_.ytControls
}
if (typeof this.options_.disablekb !== "undefined") {
playerVars.disablekb = this.options_.disablekb
}
if (typeof this.options_.color !== "undefined") {
playerVars.color = this.options_.color
}
if (!playerVars.controls) {
playerVars.fs = 0
} else if (typeof this.options_.fs !== "undefined") {
playerVars.fs = this.options_.fs
}
if (this.options_.source.src.indexOf("end=") !== -1) {
var srcEndTime = this.options_.source.src.match(/end=([0-9]*)/);
this.options_.end = parseInt(srcEndTime[1])
}
if (typeof this.options_.end !== "undefined") {
playerVars.end = this.options_.end
}
if (typeof this.options_.hl !== "undefined") {
playerVars.hl = this.options_.hl
} else if (typeof this.options_.language !== "undefined") {
playerVars.hl = this.options_.language.substr(0, 2)
}
if (typeof this.options_["iv_load_policy"] !== "undefined") {
playerVars["iv_load_policy"] = this.options_["iv_load_policy"]
}
if (typeof this.options_.list !== "undefined") {
playerVars.list = this.options_.list
} else if (this.url && typeof this.url.listId !== "undefined") {
playerVars.list = this.url.listId
}
if (typeof this.options_.listType !== "undefined") {
playerVars.listType = this.options_.listType
}
if (typeof this.options_.modestbranding !== "undefined") {
playerVars.modestbranding = this.options_.modestbranding
}
if (typeof this.options_.playlist !== "undefined") {
playerVars.playlist = this.options_.playlist
}
if (typeof this.options_.playsinline !== "undefined") {
playerVars.playsinline = this.options_.playsinline
}
if (typeof this.options_.rel !== "undefined") {
playerVars.rel = this.options_.rel
}
if (typeof this.options_.showinfo !== "undefined") {
playerVars.showinfo = this.options_.showinfo
}
if (this.options_.source.src.indexOf("start=") !== -1) {
var srcStartTime = this.options_.source.src.match(/start=([0-9]*)/);
this.options_.start = parseInt(srcStartTime[1])
}
if (typeof this.options_.start !== "undefined") {
playerVars.start = this.options_.start
}
if (typeof this.options_.theme !== "undefined") {
playerVars.theme = this.options_.theme
}
if (typeof this.options_.customVars !== "undefined") {
var customVars = this.options_.customVars;
Object.keys(customVars).forEach(function (key) {
playerVars[key] = customVars[key]
})
}
this.activeVideoId = this.url ? this.url.videoId : null;
this.activeList = playerVars.list;
var playerConfig = {
videoId: this.activeVideoId,
playerVars: playerVars,
events: {
onReady: this.onPlayerReady.bind(this),
onPlaybackQualityChange: this.onPlayerPlaybackQualityChange.bind(this),
onPlaybackRateChange: this.onPlayerPlaybackRateChange.bind(this),
onStateChange: this.onPlayerStateChange.bind(this),
onVolumeChange: this.onPlayerVolumeChange.bind(this),
onError: this.onPlayerError.bind(this)
}
};
if (typeof this.options_.enablePrivacyEnhancedMode !== "undefined" && this.options_.enablePrivacyEnhancedMode) {
playerConfig.host = "https://www.youtube-nocookie.com"
}
this.ytPlayer = new YT.Player(this.options_.techId, playerConfig)
}, onPlayerReady: function () {
if (this.options_.muted) {
this.ytPlayer.mute()
}
var playbackRates = this.ytPlayer.getAvailablePlaybackRates();
if (playbackRates.length > 1) {
this.featuresPlaybackRate = true
}
this.playerReady_ = true;
this.triggerReady();
if (this.playOnReady) {
this.play()
} else if (this.cueOnReady) {
this.cueVideoById_(this.url.videoId);
this.activeVideoId = this.url.videoId
}
}, onPlayerPlaybackQualityChange: function () {
}, onPlayerPlaybackRateChange: function () {
this.trigger("ratechange")
}, onPlayerStateChange: function (e) {
var state = e.data;
if (state === this.lastState || this.errorNumber) {
return
}
this.lastState = state;
switch (state) {
case-1:
this.trigger("loadstart");
this.trigger("loadedmetadata");
this.trigger("durationchange");
this.trigger("ratechange");
break;
case YT.PlayerState.ENDED:
this.trigger("ended");
break;
case YT.PlayerState.PLAYING:
this.trigger("timeupdate");
this.trigger("durationchange");
this.trigger("playing");
this.trigger("play");
if (this.isSeeking) {
this.onSeeked()
}
break;
case YT.PlayerState.PAUSED:
this.trigger("canplay");
if (this.isSeeking) {
this.onSeeked()
} else {
this.trigger("pause")
}
break;
case YT.PlayerState.BUFFERING:
this.player_.trigger("timeupdate");
this.player_.trigger("waiting");
break
}
}, onPlayerVolumeChange: function () {
this.trigger("volumechange")
}, onPlayerError: function (e) {
this.errorNumber = e.data;
this.trigger("pause");
this.trigger("error")
}, error: function () {
var code = 1e3 + this.errorNumber;
switch (this.errorNumber) {
case 5:
return {code: code, message: "Error while trying to play the video"};
case 2:
case 100:
return {code: code, message: "Unable to find the video"};
case 101:
case 150:
return {code: code, message: "Playback on other Websites has been disabled by the video owner."}
}
return {code: code, message: "YouTube unknown error (" + this.errorNumber + ")"}
}, loadVideoById_: function (id) {
var options = {videoId: id};
if (this.options_.start) {
options.startSeconds = this.options_.start
}
if (this.options_.end) {
options.endEnd = this.options_.end
}
this.ytPlayer.loadVideoById(options)
}, cueVideoById_: function (id) {
var options = {videoId: id};
if (this.options_.start) {
options.startSeconds = this.options_.start
}
if (this.options_.end) {
options.endEnd = this.options_.end
}
this.ytPlayer.cueVideoById(options)
}, src: function (src) {
if (src) {
this.setSrc({src: src})
}
return this.source
}, poster: function () {
if (_isOnMobile) {
return null
}
return this.poster_
}, setPoster: function (poster) {
this.poster_ = poster
}, setSrc: function (source) {
if (!source || !source.src) {
return
}
delete this.errorNumber;
this.source = source;
this.url = Youtube.parseUrl(source.src);
if (!this.options_.poster) {
if (this.url.videoId) {
this.poster_ = "https://img.youtube.com/vi/" + this.url.videoId + "/0.jpg";
this.trigger("posterchange");
this.checkHighResPoster()
}
}
if (this.options_.autoplay && !_isOnMobile) {
if (this.isReady_) {
this.play()
} else {
this.playOnReady = true
}
} else if (this.activeVideoId !== this.url.videoId) {
if (this.isReady_) {
this.cueVideoById_(this.url.videoId);
this.activeVideoId = this.url.videoId
} else {
this.cueOnReady = true
}
}
}, autoplay: function () {
return this.options_.autoplay
}, setAutoplay: function (val) {
this.options_.autoplay = val
}, loop: function () {
return this.options_.loop
}, setLoop: function (val) {
this.options_.loop = val
}, play: function () {
if (!this.url || !this.url.videoId) {
return
}
this.wasPausedBeforeSeek = false;
if (this.isReady_) {
if (this.url.listId) {
if (this.activeList === this.url.listId) {
this.ytPlayer.playVideo()
} else {
this.ytPlayer.loadPlaylist(this.url.listId);
this.activeList = this.url.listId
}
}
if (this.activeVideoId === this.url.videoId) {
this.ytPlayer.playVideo()
} else {
this.loadVideoById_(this.url.videoId);
this.activeVideoId = this.url.videoId
}
} else {
this.trigger("waiting");
this.playOnReady = true
}
}, pause: function () {
if (this.ytPlayer) {
this.ytPlayer.pauseVideo()
}
}, paused: function () {
return this.ytPlayer ? this.lastState !== YT.PlayerState.PLAYING && this.lastState !== YT.PlayerState.BUFFERING : true
}, currentTime: function () {
return this.ytPlayer ? this.ytPlayer.getCurrentTime() : 0
}, setCurrentTime: function (seconds) {
if (this.lastState === YT.PlayerState.PAUSED) {
this.timeBeforeSeek = this.currentTime()
}
if (!this.isSeeking) {
this.wasPausedBeforeSeek = this.paused()
}
this.ytPlayer.seekTo(seconds, true);
this.trigger("timeupdate");
this.trigger("seeking");
this.isSeeking = true;
if (this.lastState === YT.PlayerState.PAUSED && this.timeBeforeSeek !== seconds) {
clearInterval(this.checkSeekedInPauseInterval);
this.checkSeekedInPauseInterval = setInterval(function () {
if (this.lastState !== YT.PlayerState.PAUSED || !this.isSeeking) {
clearInterval(this.checkSeekedInPauseInterval)
} else if (this.currentTime() !== this.timeBeforeSeek) {
this.trigger("timeupdate");
this.onSeeked()
}
}.bind(this), 250)
}
}, seeking: function () {
return this.isSeeking
}, seekable: function () {
if (!this.ytPlayer) {
return videojs.createTimeRange()
}
return videojs.createTimeRange(0, this.ytPlayer.getDuration())
}, onSeeked: function () {
clearInterval(this.checkSeekedInPauseInterval);
this.isSeeking = false;
if (this.wasPausedBeforeSeek) {
this.pause()
}
this.trigger("seeked")
}, playbackRate: function () {
return this.ytPlayer ? this.ytPlayer.getPlaybackRate() : 1
}, setPlaybackRate: function (suggestedRate) {
if (!this.ytPlayer) {
return
}
this.ytPlayer.setPlaybackRate(suggestedRate)
}, duration: function () {
return this.ytPlayer ? this.ytPlayer.getDuration() : 0
}, currentSrc: function () {
return this.source && this.source.src
}, ended: function () {
return this.ytPlayer ? this.lastState === YT.PlayerState.ENDED : false
}, volume: function () {
return this.ytPlayer ? this.ytPlayer.getVolume() / 100 : 1
}, setVolume: function (percentAsDecimal) {
if (!this.ytPlayer) {
return
}
this.ytPlayer.setVolume(percentAsDecimal * 100)
}, muted: function () {
return this.ytPlayer ? this.ytPlayer.isMuted() : false
}, setMuted: function (mute) {
if (!this.ytPlayer) {
return
} else {
this.muted(true)
}
if (mute) {
this.ytPlayer.mute()
} else {
this.ytPlayer.unMute()
}
this.setTimeout(function () {
this.trigger("volumechange")
}, 50)
}, buffered: function () {
if (!this.ytPlayer || !this.ytPlayer.getVideoLoadedFraction) {
return videojs.createTimeRange()
}
var bufferedEnd = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration();
return videojs.createTimeRange(0, bufferedEnd)
}, preload: function () {
}, load: function () {
}, reset: function () {
}, networkState: function () {
if (!this.ytPlayer) {
return 0
}
switch (this.ytPlayer.getPlayerState()) {
case-1:
return 0;
case 3:
return 2;
default:
return 1
}
}, readyState: function () {
if (!this.ytPlayer) {
return 0
}
switch (this.ytPlayer.getPlayerState()) {
case-1:
return 0;
case 5:
return 1;
case 3:
return 2;
default:
return 4
}
}, supportsFullScreen: function () {
return document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled
}, checkHighResPoster: function () {
var uri = "https://img.youtube.com/vi/" + this.url.videoId + "/maxresdefault.jpg";
try {
var image = new Image;
image.onload = function () {
if ("naturalHeight" in image) {
if (image.naturalHeight <= 90 || image.naturalWidth <= 120) {
return
}
} else if (image.height <= 90 || image.width <= 120) {
return
}
this.poster_ = uri;
this.trigger("posterchange")
}.bind(this);
image.onerror = function () {
};
image.src = uri
} catch (e) {
}
}
});
Youtube.isSupported = function () {
return true
};
Youtube.canPlaySource = function (e) {
return Youtube.canPlayType(e.type)
};
Youtube.canPlayType = function (e) {
return e === "video/youtube"
};
Youtube.parseUrl = function (url) {
var result = {videoId: null};
var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
var match = url.match(regex);
if (match && match[2].length === 11) {
result.videoId = match[2]
}
var regPlaylist = /[?&]list=([^#\&\?]+)/;
match = url.match(regPlaylist);
if (match && match[1]) {
result.listId = match[1]
}
return result
};
function apiLoaded() {
YT.ready(function () {
Youtube.isApiReady = true;
for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) {
Youtube.apiReadyQueue[i].initYTPlayer()
}
})
}
function loadScript(src, callback) {
var loaded = false;
var tag = document.createElement("script");
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
tag.onload = function () {
if (!loaded) {
loaded = true;
callback()
}
};
tag.onreadystatechange = function () {
if (!loaded && (this.readyState === "complete" || this.readyState === "loaded")) {
loaded = true;
callback()
}
};
tag.src = src
}
function injectCss() {
var css = ".vjs-youtube .vjs-iframe-blocker { display: none; }" + ".vjs-youtube.vjs-user-inactive .vjs-iframe-blocker { display: block; }" + ".vjs-youtube .vjs-poster { background-size: cover; }" + ".vjs-youtube-mobile .vjs-big-play-button { display: none; }";
var head = document.head || document.getElementsByTagName("head")[0];
var style = document.createElement("style");
style.type = "text/css";
if (style.styleSheet) {
style.styleSheet.cssText = css
} else {
style.appendChild(document.createTextNode(css))
}
head.appendChild(style)
}
Youtube.apiReadyQueue = [];
if (typeof document !== "undefined") {
loadScript("https://www.youtube.com/iframe_api", apiLoaded);
injectCss()
}
if (typeof videojs.registerTech !== "undefined") {
videojs.registerTech("Youtube", Youtube)
} else {
videojs.registerComponent("Youtube", Youtube)
}
});