- );
+ );
}
diff --git a/frontend/src/static/js/components/media-viewer/VideoViewer/index.js b/frontend/src/static/js/components/media-viewer/VideoViewer/index.js
index 7cec399c..905b242e 100644
--- a/frontend/src/static/js/components/media-viewer/VideoViewer/index.js
+++ b/frontend/src/static/js/components/media-viewer/VideoViewer/index.js
@@ -6,647 +6,732 @@ import { PageStore, MediaPageStore, VideoViewerStore } from '../../../utils/stor
import { addClassname, removeClassname, formatInnerLink } from '../../../utils/helpers/';
import { BrowserCache, UpNextLoaderView, MediaDurationInfo, PlayerRecommendedMedia } from '../../../utils/classes/';
import {
- orderedSupportedVideoFormats,
- videoAvailableCodecsAndResolutions,
- extractDefaultVideoResolution,
+ orderedSupportedVideoFormats,
+ videoAvailableCodecsAndResolutions,
+ extractDefaultVideoResolution,
} from './functions';
-import { VideoPlayer, VideoPlayerError } from '../../video-player/VideoPlayer';
+// import { VideoPlayer, VideoPlayerError } from '../../video-player/VideoPlayer';
+import VideoJSEmbed from '../../VideoJS/VideoJSEmbed';
import '../VideoViewer.scss';
function filterVideoEncoding(encoding_status) {
- switch (encoding_status) {
- case 'running_X':
- MediaPageStore.set('media-load-error-type', 'encodingRunning');
- MediaPageStore.set('media-load-error-message', 'Media encoding is currently running. Try again in few minutes.');
- break;
- case 'pending_X':
- MediaPageStore.set('media-load-error-type', 'encodingPending');
- MediaPageStore.set('media-load-error-message', 'Media encoding is pending');
- break;
- case 'fail':
- MediaPageStore.set('media-load-error-type', 'encodingFailed');
- MediaPageStore.set('media-load-error-message', 'Media encoding failed');
- break;
- }
+ switch (encoding_status) {
+ case 'running_X':
+ MediaPageStore.set('media-load-error-type', 'encodingRunning');
+ MediaPageStore.set(
+ 'media-load-error-message',
+ 'Media encoding is currently running. Try again in few minutes.'
+ );
+ break;
+ case 'pending_X':
+ MediaPageStore.set('media-load-error-type', 'encodingPending');
+ MediaPageStore.set('media-load-error-message', 'Media encoding is pending');
+ break;
+ case 'fail':
+ MediaPageStore.set('media-load-error-type', 'encodingFailed');
+ MediaPageStore.set('media-load-error-message', 'Media encoding failed');
+ break;
+ }
}
export default class VideoViewer extends React.PureComponent {
- constructor(props) {
- super(props);
+ constructor(props) {
+ super(props);
- this.state = {
- displayPlayer: false,
- };
+ this.state = {
+ displayPlayer: false,
+ };
- this.videoSources = [];
+ this.videoSources = [];
- filterVideoEncoding(this.props.data.encoding_status);
+ filterVideoEncoding(this.props.data.encoding_status);
- if (null !== MediaPageStore.get('media-load-error-type')) {
- this.state.displayPlayer = true;
- return;
- }
-
- if ('string' === typeof this.props.data.poster_url) {
- this.videoPoster = formatInnerLink(this.props.data.poster_url, this.props.siteUrl);
- } else if ('string' === typeof this.props.data.thumbnail_url) {
- this.videoPoster = formatInnerLink(this.props.data.thumbnail_url, this.props.siteUrl);
- }
-
- this.videoInfo = videoAvailableCodecsAndResolutions(this.props.data.encodings_info, this.props.data.hls_info);
-
- const resolutionsKeys = Object.keys(this.videoInfo);
-
- if (!resolutionsKeys.length) {
- this.videoInfo = null;
- } else {
- let defaultResolution = VideoViewerStore.get('video-quality');
-
- if (null === defaultResolution || ('Auto' === defaultResolution && void 0 === this.videoInfo['Auto'])) {
- defaultResolution = 720; // Default resolution.
- }
-
- let defaultVideoResolution = extractDefaultVideoResolution(defaultResolution, this.videoInfo);
-
- if ('Auto' === defaultResolution && void 0 !== this.videoInfo['Auto']) {
- this.videoSources.push({ src: this.videoInfo['Auto'].url[0] });
- }
-
- const supportedFormats = orderedSupportedVideoFormats();
-
- let srcUrl, k;
-
- k = 0;
- while (k < this.videoInfo[defaultVideoResolution].format.length) {
- if ('hls' === this.videoInfo[defaultVideoResolution].format[k]) {
- this.videoSources.push({ src: this.videoInfo[defaultVideoResolution].url[k] });
- break;
+ if (null !== MediaPageStore.get('media-load-error-type')) {
+ this.state.displayPlayer = true;
+ return;
}
- k += 1;
- }
- for (k in this.props.data.encodings_info[defaultVideoResolution]) {
- if (this.props.data.encodings_info[defaultVideoResolution].hasOwnProperty(k)) {
- if (supportedFormats.support[k]) {
- srcUrl = this.props.data.encodings_info[defaultVideoResolution][k].url;
+ if ('string' === typeof this.props.data.poster_url) {
+ this.videoPoster = formatInnerLink(this.props.data.poster_url, this.props.siteUrl);
+ } else if ('string' === typeof this.props.data.thumbnail_url) {
+ this.videoPoster = formatInnerLink(this.props.data.thumbnail_url, this.props.siteUrl);
+ }
- if (!!srcUrl) {
- srcUrl = formatInnerLink(srcUrl, this.props.siteUrl);
+ this.videoInfo = videoAvailableCodecsAndResolutions(this.props.data.encodings_info, this.props.data.hls_info);
- this.videoSources.push({
- src: srcUrl /*.replace("http://", "//").replace("https://", "//")*/,
- encodings_status: this.props.data.encodings_info[defaultVideoResolution][k].status,
- });
+ const resolutionsKeys = Object.keys(this.videoInfo);
+
+ if (!resolutionsKeys.length) {
+ this.videoInfo = null;
+ } else {
+ let defaultResolution = VideoViewerStore.get('video-quality');
+
+ if (null === defaultResolution || ('Auto' === defaultResolution && void 0 === this.videoInfo['Auto'])) {
+ defaultResolution = 720; // Default resolution.
}
- }
- }
- }
- // console.log( supportedFormats );
- // console.log( this.videoInfo );
- // console.log( defaultVideoResolution );
- // console.log( this.videoSources );
+ let defaultVideoResolution = extractDefaultVideoResolution(defaultResolution, this.videoInfo);
+
+ if ('Auto' === defaultResolution && void 0 !== this.videoInfo['Auto']) {
+ this.videoSources.push({ src: this.videoInfo['Auto'].url[0] });
+ }
+
+ const supportedFormats = orderedSupportedVideoFormats();
+
+ let srcUrl, k;
+
+ k = 0;
+ while (k < this.videoInfo[defaultVideoResolution].format.length) {
+ if ('hls' === this.videoInfo[defaultVideoResolution].format[k]) {
+ this.videoSources.push({
+ src: this.videoInfo[defaultVideoResolution].url[k],
+ });
+ break;
+ }
+ k += 1;
+ }
+
+ for (k in this.props.data.encodings_info[defaultVideoResolution]) {
+ if (this.props.data.encodings_info[defaultVideoResolution].hasOwnProperty(k)) {
+ if (supportedFormats.support[k]) {
+ srcUrl = this.props.data.encodings_info[defaultVideoResolution][k].url;
+
+ if (!!srcUrl) {
+ srcUrl = formatInnerLink(srcUrl, this.props.siteUrl);
+
+ this.videoSources.push({
+ src: srcUrl /*.replace("http://", "//").replace("https://", "//")*/,
+ encodings_status: this.props.data.encodings_info[defaultVideoResolution][k].status,
+ });
+ }
+ }
+ }
+ }
+
+ // console.log( supportedFormats );
+ // console.log( this.videoInfo );
+ // console.log( defaultVideoResolution );
+ // console.log( this.videoSources );
+ }
+
+ if (this.videoSources.length) {
+ if (
+ !this.props.inEmbed &&
+ 1 === this.videoSources.length &&
+ 'running' === this.videoSources[0].encodings_status
+ ) {
+ MediaPageStore.set('media-load-error-type', 'encodingRunning');
+ MediaPageStore.set(
+ 'media-load-error-message',
+ 'Media encoding is currently running. Try again in few minutes.'
+ );
+ return;
+ }
+ } else {
+ switch (MediaPageStore.get('media-load-error-type')) {
+ case 'encodingRunning':
+ case 'encodingPending':
+ case 'encodingFailed':
+ break;
+ default:
+ console.warn('VIDEO DEBUG:', "Video files don't exist");
+ }
+ }
+
+ PageStore.on('switched_media_auto_play', this.onUpdateMediaAutoPlay.bind(this));
+
+ this.browserCache = new BrowserCache(SiteContext._currentValue.id, 86400); // Keep cache data "fresh" for one day.
+
+ const _MediaDurationInfo = new MediaDurationInfo();
+
+ _MediaDurationInfo.update(this.props.data.duration);
+
+ this.durationISO8601 = _MediaDurationInfo.ISO8601();
+
+ this.playerElem = null;
+
+ this.playerInstance = null;
+
+ this.onPlayerInit = this.onPlayerInit.bind(this);
+
+ this.onClickNext = this.onClickNext.bind(this);
+ this.onClickPrevious = this.onClickPrevious.bind(this);
+ this.onStateUpdate = this.onStateUpdate.bind(this);
+
+ this.onVideoEnd = this.onVideoEnd.bind(this);
+ this.onVideoRestart = this.onVideoRestart.bind(this);
}
- if (this.videoSources.length) {
- if (
- !this.props.inEmbed &&
- 1 === this.videoSources.length &&
- 'running' === this.videoSources[0].encodings_status
- ) {
- MediaPageStore.set('media-load-error-type', 'encodingRunning');
- MediaPageStore.set(
- 'media-load-error-message',
- 'Media encoding is currently running. Try again in few minutes.'
- );
- return;
- }
- } else {
- switch (MediaPageStore.get('media-load-error-type')) {
- case 'encodingRunning':
- case 'encodingPending':
- case 'encodingFailed':
- break;
- default:
- console.warn('VIDEO DEBUG:', "Video files don't exist");
- }
- }
+ componentDidMount() {
+ if (this.videoSources.length) {
+ this.recommendedMedia = this.props.data.related_media.length
+ ? new PlayerRecommendedMedia(
+ this.props.data.related_media,
+ this.props.inEmbed,
+ !PageStore.get('config-media-item').displayViews
+ )
+ : null;
- PageStore.on('switched_media_auto_play', this.onUpdateMediaAutoPlay.bind(this));
+ this.upNextLoaderView =
+ !this.props.inEmbed && this.props.data.related_media.length
+ ? new UpNextLoaderView(this.props.data.related_media[0])
+ : null;
- this.browserCache = new BrowserCache(SiteContext._currentValue.id, 86400); // Keep cache data "fresh" for one day.
+ let topLeftHtml = null;
- const _MediaDurationInfo = new MediaDurationInfo();
+ if (this.props.inEmbed) {
+ let titleLink = document.createElement('a');
+ let userThumbLink = document.createElement('a');
- _MediaDurationInfo.update(this.props.data.duration);
+ topLeftHtml = document.createElement('div');
+ topLeftHtml.setAttribute('class', 'media-links-top-left');
- this.durationISO8601 = _MediaDurationInfo.ISO8601();
+ if (titleLink) {
+ titleLink.setAttribute('class', 'title-link');
+ titleLink.setAttribute('href', this.props.data.url);
+ titleLink.setAttribute('title', this.props.data.title);
+ titleLink.setAttribute('target', '_blank');
+ titleLink.innerHTML = this.props.data.title;
+ }
- this.playerElem = null;
+ if (userThumbLink) {
+ userThumbLink.setAttribute('class', 'user-thumb-link');
+ userThumbLink.setAttribute(
+ 'href',
+ formatInnerLink(this.props.data.author_profile, this.props.siteUrl)
+ );
+ userThumbLink.setAttribute('title', this.props.data.author_name);
+ userThumbLink.setAttribute('target', '_blank');
+ userThumbLink.setAttribute(
+ 'style',
+ 'background-image:url(' +
+ formatInnerLink(MediaPageStore.get('media-author-thumbnail-url'), this.props.siteUrl) +
+ ')'
+ );
+ }
- this.playerInstance = null;
+ topLeftHtml.appendChild(userThumbLink);
+ topLeftHtml.appendChild(titleLink);
+ }
- this.onPlayerInit = this.onPlayerInit.bind(this);
+ const mediaUrl = MediaPageStore.get('media-url');
- this.onClickNext = this.onClickNext.bind(this);
- this.onClickPrevious = this.onClickPrevious.bind(this);
- this.onStateUpdate = this.onStateUpdate.bind(this);
-
- this.onVideoEnd = this.onVideoEnd.bind(this);
- this.onVideoRestart = this.onVideoRestart.bind(this);
- }
-
- componentDidMount() {
- if (this.videoSources.length) {
- this.recommendedMedia = this.props.data.related_media.length
- ? new PlayerRecommendedMedia(
- this.props.data.related_media,
- this.props.inEmbed,
- !PageStore.get('config-media-item').displayViews
- )
- : null;
-
- this.upNextLoaderView =
- !this.props.inEmbed && this.props.data.related_media.length
- ? new UpNextLoaderView(this.props.data.related_media[0])
- : null;
-
- let topLeftHtml = null;
-
- if (this.props.inEmbed) {
- let titleLink = document.createElement('a');
- let userThumbLink = document.createElement('a');
-
- topLeftHtml = document.createElement('div');
- topLeftHtml.setAttribute('class', 'media-links-top-left');
-
- if (titleLink) {
- titleLink.setAttribute('class', 'title-link');
- titleLink.setAttribute('href', this.props.data.url);
- titleLink.setAttribute('title', this.props.data.title);
- titleLink.setAttribute('target', '_blank');
- titleLink.innerHTML = this.props.data.title;
- }
-
- if (userThumbLink) {
- userThumbLink.setAttribute('class', 'user-thumb-link');
- userThumbLink.setAttribute('href', formatInnerLink(this.props.data.author_profile, this.props.siteUrl));
- userThumbLink.setAttribute('title', this.props.data.author_name);
- userThumbLink.setAttribute('target', '_blank');
- userThumbLink.setAttribute(
- 'style',
- 'background-image:url(' +
- formatInnerLink(MediaPageStore.get('media-author-thumbnail-url'), this.props.siteUrl) +
- ')'
- );
- }
-
- topLeftHtml.appendChild(userThumbLink);
- topLeftHtml.appendChild(titleLink);
- }
-
- const mediaUrl = MediaPageStore.get('media-url');
-
- let bottomRightHTML =
- '
\
+ let bottomRightHTML =
+ '
';
+ bottomRightHTML +=
+ '
\
\
\
\
emailEmail\
+ mediaUrl +
+ '" title="">
emailEmail\
\
\
Facebook\
+ mediaUrl +
+ '" title="" target="_blank">
Facebook\
\
\
Twitter\
+ mediaUrl +
+ '" title="" target="_blank">
Twitter\
\
\
WhatsApp\
+ mediaUrl +
+ '" title="" target="_blank" data-action="share/whatsapp/share">
WhatsApp\
\
\
Telegram\
+ mediaUrl +
+ '&text=' +
+ this.props.data.title +
+ '" title="" target="_blank">
Telegram\
\
\
LinkedIn\
+ mediaUrl +
+ '" title="" target="_blank">
LinkedIn\
\
\
reddit\
+ mediaUrl +
+ '&title=' +
+ this.props.data.title +
+ '" title="" target="_blank">
reddit\
\
\
Tumblr\
+ mediaUrl +
+ '&title=' +
+ this.props.data.title +
+ '" title="" target="_blank">
Tumblr\
\
\
Pinterest\
+ mediaUrl +
+ '" title="" target="_blank">
Pinterest\
\
\
more_horiz\
+ mediaUrl +
+ '" title="More" target="_blank">
more_horiz\
\
\
\
';
- this.cornerLayers = {
- topLeft: topLeftHtml,
- topRight: this.upNextLoaderView ? this.upNextLoaderView.html() : null,
- bottomLeft: this.recommendedMedia ? this.recommendedMedia.html() : null,
- bottomRight: this.props.inEmbed ? bottomRightHTML : null,
- };
+ this.cornerLayers = {
+ topLeft: topLeftHtml,
+ topRight: this.upNextLoaderView ? this.upNextLoaderView.html() : null,
+ bottomLeft: this.recommendedMedia ? this.recommendedMedia.html() : null,
+ bottomRight: this.props.inEmbed ? bottomRightHTML : null,
+ };
- this.setState(
- {
- displayPlayer: true,
- },
- function () {
- setTimeout(function () {
- const shareBtn = document.querySelector('.share-video-btn');
- const shareWrap = document.querySelector('.share-options-wrapper');
- const shareInner = document.querySelector('.share-options-inner');
- if (shareBtn) {
- shareBtn.addEventListener('click', function (ev) {
- addClassname(document.querySelector('.video-js.vjs-mediacms'), 'vjs-visible-share-options');
- });
- }
- if (shareWrap) {
- shareWrap.addEventListener('click', function (ev) {
- if (ev.target === shareInner || ev.target === shareWrap) {
- removeClassname(document.querySelector('.video-js.vjs-mediacms'), 'vjs-visible-share-options');
+ this.setState(
+ {
+ displayPlayer: true,
+ },
+ function () {
+ setTimeout(function () {
+ const shareBtn = document.querySelector('.share-video-btn');
+ const shareWrap = document.querySelector('.share-options-wrapper');
+ const shareInner = document.querySelector('.share-options-inner');
+ if (shareBtn) {
+ shareBtn.addEventListener('click', function (ev) {
+ addClassname(
+ document.querySelector('.video-js.vjs-mediacms'),
+ 'vjs-visible-share-options'
+ );
+ });
+ }
+ if (shareWrap) {
+ shareWrap.addEventListener('click', function (ev) {
+ if (ev.target === shareInner || ev.target === shareWrap) {
+ removeClassname(
+ document.querySelector('.video-js.vjs-mediacms'),
+ 'vjs-visible-share-options'
+ );
+ }
+ });
+ }
+ }, 1000);
}
- });
+ );
+ }
+ }
+
+ componentWillUnmount() {
+ this.unsetRecommendedMedia();
+ }
+
+ initRecommendedMedia() {
+ if (null === this.recommendedMedia) {
+ return;
+ }
+
+ if (!this.props.inEmbed) {
+ this.recommendedMedia.init();
+ }
+
+ this.playerInstance.player.on('fullscreenchange', this.recommendedMedia.onResize);
+
+ PageStore.on('window_resize', this.recommendedMedia.onResize);
+
+ VideoViewerStore.on('changed_viewer_mode', this.recommendedMedia.onResize);
+ }
+
+ unsetRecommendedMedia() {
+ if (null === this.recommendedMedia) {
+ return;
+ }
+ this.playerInstance.player.off('fullscreenchange', this.recommendedMedia.onResize);
+ PageStore.removeListener('window_resize', this.recommendedMedia.onResize);
+ VideoViewerStore.removeListener('changed_viewer_mode', this.recommendedMedia.onResize);
+ this.recommendedMedia.destroy();
+ }
+
+ onClickNext() {
+ const playlistId = MediaPageStore.get('playlist-id');
+
+ let nextLink;
+
+ if (playlistId) {
+ nextLink = MediaPageStore.get('playlist-next-media-url');
+
+ if (null === nextLink) {
+ nextLink = this.props.data.related_media[0].url;
}
- }, 1000);
- }
- );
- }
- }
-
- componentWillUnmount() {
- this.unsetRecommendedMedia();
- }
-
- initRecommendedMedia() {
- if (null === this.recommendedMedia) {
- return;
- }
-
- if (!this.props.inEmbed) {
- this.recommendedMedia.init();
- }
-
- this.playerInstance.player.on('fullscreenchange', this.recommendedMedia.onResize);
-
- PageStore.on('window_resize', this.recommendedMedia.onResize);
-
- VideoViewerStore.on('changed_viewer_mode', this.recommendedMedia.onResize);
- }
-
- unsetRecommendedMedia() {
- if (null === this.recommendedMedia) {
- return;
- }
- this.playerInstance.player.off('fullscreenchange', this.recommendedMedia.onResize);
- PageStore.removeListener('window_resize', this.recommendedMedia.onResize);
- VideoViewerStore.removeListener('changed_viewer_mode', this.recommendedMedia.onResize);
- this.recommendedMedia.destroy();
- }
-
- onClickNext() {
- const playlistId = MediaPageStore.get('playlist-id');
-
- let nextLink;
-
- if (playlistId) {
- nextLink = MediaPageStore.get('playlist-next-media-url');
-
- if (null === nextLink) {
- nextLink = this.props.data.related_media[0].url;
- }
- } else if (!this.props.inEmbed) {
- nextLink = this.props.data.related_media[0].url;
- }
-
- window.location.href = nextLink;
- }
-
- onClickPrevious() {
- const playlistId = MediaPageStore.get('playlist-id');
-
- let previousLink;
-
- if (playlistId) {
- previousLink = MediaPageStore.get('playlist-previous-media-url');
-
- if (null === previousLink) {
- previousLink = this.props.data.related_media[0].url;
- }
- } else if (!this.props.inEmbed) {
- previousLink = this.props.data.related_media[0].url;
- }
-
- window.location.href = previousLink;
- }
-
- onStateUpdate(newState) {
- if (VideoViewerStore.get('in-theater-mode') !== newState.theaterMode) {
- VideoViewerActions.set_viewer_mode(newState.theaterMode);
- }
-
- if (VideoViewerStore.get('player-volume') !== newState.volume) {
- VideoViewerActions.set_player_volume(newState.volume);
- }
-
- if (VideoViewerStore.get('player-sound-muted') !== newState.soundMuted) {
- VideoViewerActions.set_player_sound_muted(newState.soundMuted);
- }
-
- if (VideoViewerStore.get('video-quality') !== newState.quality) {
- VideoViewerActions.set_video_quality(newState.quality);
- }
-
- if (VideoViewerStore.get('video-playback-speed') !== newState.playbackSpeed) {
- VideoViewerActions.set_video_playback_speed(newState.playbackSpeed);
- }
- }
-
- onPlayerInit(instance, elem) {
- this.playerElem = elem;
- this.playerInstance = instance;
-
- if (this.upNextLoaderView) {
- this.upNextLoaderView.setVideoJsPlayerElem(this.playerInstance.player.el_);
- this.onUpdateMediaAutoPlay();
- }
-
- if (!this.props.inEmbed) {
- this.playerElem.parentNode.focus(); // Focus on player.
- }
-
- if (null !== this.recommendedMedia) {
- this.recommendedMedia.initWrappers(this.playerElem.parentNode);
-
- if (this.props.inEmbed) {
- this.playerInstance.player.one('pause', this.recommendedMedia.init);
- this.initRecommendedMedia();
- }
- }
-
- this.playerInstance.player.one('ended', this.onVideoEnd);
- }
-
- onVideoRestart() {
- if (null !== this.recommendedMedia) {
- this.recommendedMedia.updateDisplayType('inline');
-
- if (this.props.inEmbed) {
- this.playerInstance.player.one('pause', this.recommendedMedia.init);
- }
-
- this.playerInstance.player.one('ended', this.onVideoEnd);
- }
- }
-
- onVideoEnd() {
- if (null !== this.recommendedMedia) {
- if (!this.props.inEmbed) {
- this.initRecommendedMedia();
- }
-
- this.recommendedMedia.updateDisplayType('full');
- this.playerInstance.player.one('playing', this.onVideoRestart);
- }
-
- const playlistId = this.props.inEmbed ? null : MediaPageStore.get('playlist-id');
-
- if (playlistId) {
- const moreMediaEl = document.querySelector('.video-player .more-media');
- const actionsAnimEl = document.querySelector('.video-player .vjs-actions-anim');
-
- this.upNextLoaderView.cancelTimer();
-
- const nextMediaUrl = MediaPageStore.get('playlist-next-media-url');
-
- if (nextMediaUrl) {
- if (moreMediaEl) {
- moreMediaEl.style.display = 'none';
+ } else if (!this.props.inEmbed) {
+ nextLink = this.props.data.related_media[0].url;
}
- if (actionsAnimEl) {
- actionsAnimEl.style.display = 'none';
- }
-
- window.location.href = nextMediaUrl;
- }
-
- this.upNextLoaderView.hideTimerView();
-
- return;
+ window.location.href = nextLink;
}
- if (this.upNextLoaderView) {
- if (PageStore.get('media-auto-play')) {
- this.upNextLoaderView.startTimer();
- this.playerInstance.player.one(
- 'play',
- function () {
+ onClickPrevious() {
+ const playlistId = MediaPageStore.get('playlist-id');
+
+ let previousLink;
+
+ if (playlistId) {
+ previousLink = MediaPageStore.get('playlist-previous-media-url');
+
+ if (null === previousLink) {
+ previousLink = this.props.data.related_media[0].url;
+ }
+ } else if (!this.props.inEmbed) {
+ previousLink = this.props.data.related_media[0].url;
+ }
+
+ window.location.href = previousLink;
+ }
+
+ onStateUpdate(newState) {
+ if (VideoViewerStore.get('in-theater-mode') !== newState.theaterMode) {
+ VideoViewerActions.set_viewer_mode(newState.theaterMode);
+ }
+
+ if (VideoViewerStore.get('player-volume') !== newState.volume) {
+ VideoViewerActions.set_player_volume(newState.volume);
+ }
+
+ if (VideoViewerStore.get('player-sound-muted') !== newState.soundMuted) {
+ VideoViewerActions.set_player_sound_muted(newState.soundMuted);
+ }
+
+ if (VideoViewerStore.get('video-quality') !== newState.quality) {
+ VideoViewerActions.set_video_quality(newState.quality);
+ }
+
+ if (VideoViewerStore.get('video-playback-speed') !== newState.playbackSpeed) {
+ VideoViewerActions.set_video_playback_speed(newState.playbackSpeed);
+ }
+ }
+
+ onPlayerInit(instance, elem) {
+ this.playerElem = elem;
+ this.playerInstance = instance;
+
+ if (this.upNextLoaderView) {
+ this.upNextLoaderView.setVideoJsPlayerElem(this.playerInstance.player.el_);
+ this.onUpdateMediaAutoPlay();
+ }
+
+ if (!this.props.inEmbed) {
+ this.playerElem.parentNode.focus(); // Focus on player.
+ }
+
+ if (null !== this.recommendedMedia) {
+ this.recommendedMedia.initWrappers(this.playerElem.parentNode);
+
+ if (this.props.inEmbed) {
+ this.playerInstance.player.one('pause', this.recommendedMedia.init);
+ this.initRecommendedMedia();
+ }
+ }
+
+ this.playerInstance.player.one('ended', this.onVideoEnd);
+ }
+
+ onVideoRestart() {
+ if (null !== this.recommendedMedia) {
+ this.recommendedMedia.updateDisplayType('inline');
+
+ if (this.props.inEmbed) {
+ this.playerInstance.player.one('pause', this.recommendedMedia.init);
+ }
+
+ this.playerInstance.player.one('ended', this.onVideoEnd);
+ }
+ }
+
+ onVideoEnd() {
+ if (null !== this.recommendedMedia) {
+ if (!this.props.inEmbed) {
+ this.initRecommendedMedia();
+ }
+
+ this.recommendedMedia.updateDisplayType('full');
+ this.playerInstance.player.one('playing', this.onVideoRestart);
+ }
+
+ const playlistId = this.props.inEmbed ? null : MediaPageStore.get('playlist-id');
+
+ if (playlistId) {
+ const moreMediaEl = document.querySelector('.video-player .more-media');
+ const actionsAnimEl = document.querySelector('.video-player .vjs-actions-anim');
+
this.upNextLoaderView.cancelTimer();
- }.bind(this)
- );
- } else {
- this.upNextLoaderView.cancelTimer();
- }
- }
- }
- onUpdateMediaAutoPlay() {
- if (this.upNextLoaderView) {
- if (PageStore.get('media-auto-play')) {
- this.upNextLoaderView.showTimerView(this.playerInstance.isEnded());
- } else {
- this.upNextLoaderView.hideTimerView();
- }
- }
- }
+ const nextMediaUrl = MediaPageStore.get('playlist-next-media-url');
- render() {
- let nextLink = null;
- let previousLink = null;
+ if (nextMediaUrl) {
+ if (moreMediaEl) {
+ moreMediaEl.style.display = 'none';
+ }
- const playlistId = this.props.inEmbed ? null : MediaPageStore.get('playlist-id');
+ if (actionsAnimEl) {
+ actionsAnimEl.style.display = 'none';
+ }
- if (playlistId) {
- nextLink = MediaPageStore.get('playlist-next-media-url');
- previousLink = MediaPageStore.get('playlist-previous-media-url');
- } else {
- nextLink =
- this.props.data.related_media.length && !this.props.inEmbed ? this.props.data.related_media[0].url : null;
- }
+ window.location.href = nextMediaUrl;
+ }
- const previewSprite = !!this.props.data.sprites_url
- ? {
- url: this.props.siteUrl + '/' + this.props.data.sprites_url.replace(/^\//g, ''),
- frame: { width: 160, height: 90, seconds: 10 },
+ this.upNextLoaderView.hideTimerView();
+
+ return;
}
- : null;
- return (
-
-
- {this.state.displayPlayer && null !== MediaPageStore.get('media-load-error-type') ? (
-
- ) : null}
+ if (this.upNextLoaderView) {
+ if (PageStore.get('media-auto-play')) {
+ this.upNextLoaderView.startTimer();
+ this.playerInstance.player.one(
+ 'play',
+ function () {
+ this.upNextLoaderView.cancelTimer();
+ }.bind(this)
+ );
+ } else {
+ this.upNextLoaderView.cancelTimer();
+ }
+ }
+ }
- {this.state.displayPlayer && null == MediaPageStore.get('media-load-error-type') ? (
-
-
- {(site) => (
-
- )}
-
-
- ) : null}
-
-
- );
- }
+ onUpdateMediaAutoPlay() {
+ if (this.upNextLoaderView) {
+ if (PageStore.get('media-auto-play')) {
+ this.upNextLoaderView.showTimerView(this.playerInstance.isEnded());
+ } else {
+ this.upNextLoaderView.hideTimerView();
+ }
+ }
+ }
+
+ render() {
+ let nextLink = null;
+ let previousLink = null;
+
+ const playlistId = this.props.inEmbed ? null : MediaPageStore.get('playlist-id');
+
+ if (playlistId) {
+ nextLink = MediaPageStore.get('playlist-next-media-url');
+ previousLink = MediaPageStore.get('playlist-previous-media-url');
+ } else {
+ nextLink =
+ this.props.data.related_media.length && !this.props.inEmbed
+ ? this.props.data.related_media[0].url
+ : null;
+ }
+
+ const previewSprite = !!this.props.data.sprites_url
+ ? {
+ url: this.props.siteUrl + '/' + this.props.data.sprites_url.replace(/^\//g, ''),
+ frame: { width: 160, height: 90, seconds: 10 },
+ }
+ : null;
+
+ return (
+ <>
+ {/* {React.createElement(VideoJSEmbed, {
+ data: this.props.data,
+ siteUrl: window.MediaCMS.site.url,
+ onLoad: () => console.log('Video js loaded in VideoViewer'),
+ onError: (error) => console.error('Video js error in VideoViewer:', error),
+ })} */}
+
+
+
+ {this.state.displayPlayer && null == MediaPageStore.get('media-load-error-type') ? (
+
+
+ {(site) => {
+ return React.createElement(VideoJSEmbed, {
+ data: this.props.data,
+ playerVolume: this.browserCache.get('player-volume'),
+ playerSoundMuted: this.browserCache.get('player-sound-muted'),
+ videoQuality: this.browserCache.get('video-quality'),
+ videoPlaybackSpeed: parseInt(
+ this.browserCache.get('video-playback-speed'),
+ 10
+ ),
+ inTheaterMode: this.browserCache.get('in-theater-mode'),
+ siteId: site.id,
+ siteUrl: site.url,
+ info: this.videoInfo,
+ cornerLayers: this.cornerLayers,
+ sources: this.videoSources,
+ poster: this.videoPoster,
+ previewSprite: previewSprite,
+ subtitlesInfo: this.props.data.subtitles_info,
+ enableAutoplay: !this.props.inEmbed,
+ inEmbed: this.props.inEmbed,
+ hasTheaterMode: !this.props.inEmbed,
+ hasNextLink: !!nextLink,
+ hasPreviousLink: !!previousLink,
+ errorMessage: MediaPageStore.get('media-load-error-message'),
+ onClickNextCallback: this.onClickNext,
+ onClickPreviousCallback: this.onClickPrevious,
+ onStateUpdateCallback: this.onStateUpdate,
+ onPlayerInitCallback: this.onPlayerInit,
+ });
+ }}
+
+
+ ) : null}
+
+
+
+ {/*
+
+ {this.state.displayPlayer && null !== MediaPageStore.get('media-load-error-type') ? (
+
+ ) : null}
+
+ {this.state.displayPlayer && null == MediaPageStore.get('media-load-error-type') ? (
+
+
+ {(site) => (
+
+ )}
+
+
+ ) : null}
+
+
*/}
+ >
+ );
+ }
}
VideoViewer.defaultProps = {
- inEmbed: !0,
- siteUrl: PropTypes.string.isRequired,
+ inEmbed: !0,
+ siteUrl: PropTypes.string.isRequired,
};
VideoViewer.propTypes = {
- inEmbed: PropTypes.bool,
+ inEmbed: PropTypes.bool,
};
function findGetParameter(parameterName) {
- let result = null;
- let tmp = [];
- var items = location.search.substr(1).split('&');
- for (let i = 0; i < items.length; i++) {
- tmp = items[i].split('=');
- if (tmp[0] === parameterName) {
- result = decodeURIComponent(tmp[1]);
+ let result = null;
+ let tmp = [];
+ var items = location.search.substr(1).split('&');
+ for (let i = 0; i < items.length; i++) {
+ tmp = items[i].split('=');
+ if (tmp[0] === parameterName) {
+ result = decodeURIComponent(tmp[1]);
+ }
}
- }
- return result;
+ return result;
}
- function handleCanvas(videoElem) { // Make sure it's a video element
+function handleCanvas(videoElem) {
+ // Make sure it's a video element
- if (!videoElem || !videoElem.tagName || videoElem.tagName.toLowerCase() !== 'video') {
- console.error('Invalid video element:', videoElem);
- return;
- }
+ if (!videoElem || !videoElem.tagName || videoElem.tagName.toLowerCase() !== 'video') {
+ console.error('Invalid video element:', videoElem);
+ return;
+ }
- const Player = videojs(videoElem);
- Player.playsinline(true);
+ const Player = videojs(videoElem);
+ Player.playsinline(true);
- Player.on('loadedmetadata', function () {
- const muted = parseInt(findGetParameter('muted'));
- const autoplay = parseInt(findGetParameter('autoplay'));
- const timestamp = parseInt(findGetParameter('t'));
+ Player.on('loadedmetadata', function () {
+ const muted = parseInt(findGetParameter('muted'));
+ const autoplay = parseInt(findGetParameter('autoplay'));
+ const timestamp = parseInt(findGetParameter('t'));
- // Handle timestamp clicks
- document.addEventListener('click', function (e) {
- if (e.target.classList.contains('video-timestamp')) {
- e.preventDefault();
- const timestamp = parseInt(e.target.dataset.timestamp, 10);
+ // Handle timestamp clicks
+ document.addEventListener('click', function (e) {
+ if (e.target.classList.contains('video-timestamp')) {
+ e.preventDefault();
+ const timestamp = parseInt(e.target.dataset.timestamp, 10);
+
+ if (timestamp >= 0 && timestamp < Player.duration()) {
+ Player.currentTime(timestamp);
+ } else if (timestamp >= 0) {
+ Player.play();
+ }
+ }
+ });
+
+ if (muted == 1) {
+ Player.muted(true);
+ }
if (timestamp >= 0 && timestamp < Player.duration()) {
- Player.currentTime(timestamp);
- } else if (timestamp >= 0) {
- Player.play();
+ // Start the video from the given time
+ Player.currentTime(timestamp);
+ } else if (timestamp >= 0 && timestamp >= Player.duration()) {
+ // Restart the video if the given time is greater than the duration
+ Player.play();
+ }
+ if (autoplay === 1) {
+ Player.play();
}
- }
});
-
- if (muted == 1) {
- Player.muted(true);
- }
-
- if (timestamp >= 0 && timestamp < Player.duration()) {
- // Start the video from the given time
- Player.currentTime(timestamp);
- } else if (timestamp >= 0 && timestamp >= Player.duration()) {
- // Restart the video if the given time is greater than the duration
- Player.play();
- }
- if (autoplay === 1) {
- Player.play();
- }
- });
}
const observer = new MutationObserver((mutations, me) => {
- const playerContainer = document.querySelector('.video-js.vjs-mediacms');
- if (playerContainer) {
- const video = playerContainer.querySelector('video');
- if (video) {
- handleCanvas(video);
- me.disconnect();
+ const playerContainer = document.querySelector('.video-js.vjs-mediacms');
+ if (playerContainer) {
+ const video = playerContainer.querySelector('video');
+ if (video) {
+ handleCanvas(video);
+ me.disconnect();
+ }
}
- }
});
observer.observe(document, {
- childList: true,
- subtree: true,
+ childList: true,
+ subtree: true,
});
diff --git a/frontend/src/static/js/components/video-player/VideoPlayer.jsx b/frontend/src/static/js/components/video-player/VideoPlayer.jsx
deleted file mode 100644
index baa79c90..00000000
--- a/frontend/src/static/js/components/video-player/VideoPlayer.jsx
+++ /dev/null
@@ -1,257 +0,0 @@
-import React, { useRef, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import urlParse from 'url-parse';
-
-import MediaPlayer from 'mediacms-player/dist/mediacms-player.js';
-import 'mediacms-player/dist/mediacms-player.css';
-
-import './VideoPlayer.scss';
-
-export function formatInnerLink(url, baseUrl) {
- let link = urlParse(url, {});
-
- if ('' === link.origin || 'null' === link.origin || !link.origin) {
- link = urlParse(baseUrl + '/' + url.replace(/^\//g, ''), {});
- }
-
- return link.toString();
-}
-
-export function VideoPlayerError(props) {
- return (
-
-
-
- error_outline
-
- {props.errorMessage}
-
-
- );
-}
-
-VideoPlayerError.propTypes = {
- errorMessage: PropTypes.string.isRequired,
-};
-
-export function VideoPlayer(props) {
- const videoElemRef = useRef(null);
-
- let player = null;
-
- const playerStates = {
- playerVolume: props.playerVolume,
- playerSoundMuted: props.playerSoundMuted,
- videoQuality: props.videoQuality,
- videoPlaybackSpeed: props.videoPlaybackSpeed,
- inTheaterMode: props.inTheaterMode,
- };
-
- playerStates.playerVolume =
- null === playerStates.playerVolume ? 1 : Math.max(Math.min(Number(playerStates.playerVolume), 1), 0);
- playerStates.playerSoundMuted = null !== playerStates.playerSoundMuted ? playerStates.playerSoundMuted : !1;
- playerStates.videoQuality = null !== playerStates.videoQuality ? playerStates.videoQuality : 'Auto';
- playerStates.videoPlaybackSpeed = null !== playerStates.videoPlaybackSpeed ? playerStates.videoPlaybackSpeed : !1;
- playerStates.inTheaterMode = null !== playerStates.inTheaterMode ? playerStates.inTheaterMode : !1;
-
- function onClickNext() {
- if (void 0 !== props.onClickNextCallback) {
- props.onClickNextCallback();
- }
- }
-
- function onClickPrevious() {
- if (void 0 !== props.onClickPreviousCallback) {
- props.onClickPreviousCallback();
- }
- }
-
- function onPlayerStateUpdate(newState) {
- if (playerStates.playerVolume !== newState.volume) {
- playerStates.playerVolume = newState.volume;
- }
-
- if (playerStates.playerSoundMuted !== newState.soundMuted) {
- playerStates.playerSoundMuted = newState.soundMuted;
- }
-
- if (playerStates.videoQuality !== newState.quality) {
- playerStates.videoQuality = newState.quality;
- }
-
- if (playerStates.videoPlaybackSpeed !== newState.playbackSpeed) {
- playerStates.videoPlaybackSpeed = newState.playbackSpeed;
- }
-
- if (playerStates.inTheaterMode !== newState.theaterMode) {
- playerStates.inTheaterMode = newState.theaterMode;
- }
-
- if (void 0 !== props.onStateUpdateCallback) {
- props.onStateUpdateCallback(newState);
- }
- }
-
- function initPlayer() {
- if (null !== player || null !== props.errorMessage) {
- return;
- }
-
- if (!props.inEmbed) {
- window.removeEventListener('focus', initPlayer);
- document.removeEventListener('visibilitychange', initPlayer);
- }
-
- if (!videoElemRef.current) {
- return;
- }
-
- if (!props.inEmbed) {
- videoElemRef.current.focus(); // Focus on player before instance init.
- }
-
- const subtitles = {
- on: false,
- };
-
- if (void 0 !== props.subtitlesInfo && null !== props.subtitlesInfo && props.subtitlesInfo.length) {
- subtitles.languages = [];
-
- let i = 0;
- while (i < props.subtitlesInfo.length) {
- if (
- void 0 !== props.subtitlesInfo[i].src &&
- void 0 !== props.subtitlesInfo[i].srclang &&
- void 0 !== props.subtitlesInfo[i].label
- ) {
- subtitles.languages.push({
- src: formatInnerLink(props.subtitlesInfo[i].src, props.siteUrl),
- srclang: props.subtitlesInfo[i].srclang,
- label: props.subtitlesInfo[i].label,
- });
- }
-
- i += 1;
- }
-
- if (subtitles.languages.length) {
- subtitles.on = true;
- }
- }
-
- player = new MediaPlayer(
- videoElemRef.current,
- {
- enabledTouchControls: true,
- sources: props.sources,
- poster: props.poster,
- autoplay: props.enableAutoplay,
- bigPlayButton: true,
- controlBar: {
- theaterMode: props.hasTheaterMode,
- pictureInPicture: false,
- next: props.hasNextLink ? true : false,
- previous: props.hasPreviousLink ? true : false,
- },
- subtitles: subtitles,
- cornerLayers: props.cornerLayers,
- videoPreviewThumb: props.previewSprite,
- },
- {
- volume: playerStates.playerVolume,
- soundMuted: playerStates.playerSoundMuted,
- theaterMode: playerStates.inTheaterMode,
- theSelectedQuality: void 0, // @note: Allow auto resolution selection by sources order.
- theSelectedPlaybackSpeed: playerStates.videoPlaybackSpeed || 1,
- },
- props.info,
- [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
- onPlayerStateUpdate,
- onClickNext,
- onClickPrevious
- );
-
- if (void 0 !== props.onPlayerInitCallback) {
- props.onPlayerInitCallback(player, videoElemRef.current);
- }
- }
-
- function unsetPlayer() {
- if (null === player) {
- return;
- }
- videojs(videoElemRef.current).dispose();
- player = null;
- }
-
- useEffect(() => {
- if (props.inEmbed || document.hasFocus() || 'visible' === document.visibilityState) {
- initPlayer();
- } else {
- window.addEventListener('focus', initPlayer);
- document.addEventListener('visibilitychange', initPlayer);
- }
-
- /*
- // We don't need this because we have a custom function in frontend/src/static/js/components/media-viewer/VideoViewer/index.js:617
- player && player.player.one('loadedmetadata', () => {
- const urlParams = new URLSearchParams(window.location.search);
- const paramT = Number(urlParams.get('t'));
- const timestamp = !isNaN(paramT) ? paramT : 0;
- player.player.currentTime(timestamp);
- }); */
-
- return () => {
- unsetPlayer();
-
- if (void 0 !== props.onUnmountCallback) {
- props.onUnmountCallback();
- }
- };
- }, []);
-
- return null === props.errorMessage ? (
-
- ) : (
-
-
-
- error_outline
-
- {props.errorMessage}
-
-
- );
-}
-
-VideoPlayer.propTypes = {
- playerVolume: PropTypes.string,
- playerSoundMuted: PropTypes.bool,
- videoQuality: PropTypes.string,
- videoPlaybackSpeed: PropTypes.number,
- inTheaterMode: PropTypes.bool,
- siteId: PropTypes.string.isRequired,
- siteUrl: PropTypes.string.isRequired,
- errorMessage: PropTypes.string,
- cornerLayers: PropTypes.object,
- subtitlesInfo: PropTypes.array.isRequired,
- inEmbed: PropTypes.bool.isRequired,
- sources: PropTypes.array.isRequired,
- info: PropTypes.object.isRequired,
- enableAutoplay: PropTypes.bool.isRequired,
- hasTheaterMode: PropTypes.bool.isRequired,
- hasNextLink: PropTypes.bool.isRequired,
- hasPreviousLink: PropTypes.bool.isRequired,
- poster: PropTypes.string,
- previewSprite: PropTypes.object,
- onClickPreviousCallback: PropTypes.func,
- onClickNextCallback: PropTypes.func,
- onPlayerInitCallback: PropTypes.func,
- onStateUpdateCallback: PropTypes.func,
- onUnmountCallback: PropTypes.func,
-};
-
-VideoPlayer.defaultProps = {
- errorMessage: null,
- cornerLayers: {},
-};