video implemenations require container element in their constructor and layout itself in there

This commit is contained in:
NikolaBorislavovHristov 2018-11-23 14:27:24 +02:00
parent 2c07fb2d93
commit 0cc683c37c
4 changed files with 48 additions and 69 deletions

View file

@ -2,38 +2,38 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import HTMLVideo from './stremio-video/HTMLVideo';
import YouTubeVideo from './stremio-video/YouTubeVideo';
import styles from './styles';
class Video extends Component {
constructor(props) {
super(props);
this.videoRef = React.createRef();
this.state = {
implementation: null
};
this.video = null;
this.containerRef = React.createRef();
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.className !== this.props.className ||
nextState.implementation !== this.state.implementation;
shouldComponentUpdate() {
return false;
}
componentDidMount() {
this.prepareStream()
.then(({ source, implementation }) => {
this.setState({ implementation }, () => {
this.video = new this.state.implementation(this.videoRef.current);
this.video.on('ended', this.props.onEnded);
this.video.on('error', this.props.onError);
this.video.on('propValue', this.props.onPropValue);
this.video.on('propChanged', this.props.onPropChanged);
this.state.implementation.manifest.props.forEach((propName) => {
this.dispatch('observeProp', propName);
});
this.dispatch('command', 'load', { source });
const extra = {
time: 40000
};
const stream = {
ytId: 'E4A0bcCQke0',
// url: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
};
this.chooseImplementation(stream)
.then((implementation) => {
this.video = new implementation(this.containerRef.current);
this.video.on('ended', this.props.onEnded);
this.video.on('error', this.props.onError);
this.video.on('propValue', this.props.onPropValue);
this.video.on('propChanged', this.props.onPropChanged);
this.video.constructor.manifest.props.forEach((propName) => {
this.dispatch('observeProp', propName);
});
this.dispatch('command', 'load', stream, extra);
})
.catch((error) => {
this.props.onError(error);
@ -44,54 +44,31 @@ class Video extends Component {
this.dispatch('stop');
}
prepareStream = () => {
chooseImplementation = (stream) => {
return new Promise((resolve, reject) => {
// YT.ready(() => {
// resolve({
// source: 'J2z5uzqxJNU',
// implementation: YouTubeVideo
// });
// });
resolve({
source: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
implementation: HTMLVideo
});
if (stream.ytId) {
YT.ready(() => {
resolve(YouTubeVideo);
});
return;
}
resolve(HTMLVideo);
});
}
dispatch = (...args) => {
try {
this.state.implementation && this.video && this.video.dispatch(...args);
this.video && this.video.dispatch(...args);
} catch (e) {
console.error(this.state.implementation.manifest.name, e);
console.error(this.video.constructor.manifest.name, e);
}
}
renderHTMLVideo() {
return (
<div className={this.props.className}>
<video ref={this.videoRef} className={styles['html-video']} />
</div>
);
}
renderYouTubeVideo() {
return (
<div className={this.props.className}>
<div ref={this.videoRef} />
</div>
);
}
render() {
switch (this.state.implementation) {
case HTMLVideo:
return this.renderHTMLVideo();
case YouTubeVideo:
return this.renderYouTubeVideo();
default:
return null;
}
return (
<div ref={this.containerRef} className={this.props.className} />
);
}
}

View file

@ -1,6 +1,10 @@
var EventEmitter = require('events');
var HTMLVideo = function(videoElement) {
var HTMLVideo = function(containerElement) {
var videoElement = document.createElement('video');
videoElement.style.width = '100%';
videoElement.style.height = '100%';
containerElement.appendChild(videoElement);
var events = new EventEmitter();
var onEnded = function() {
events.emit('ended');
@ -101,10 +105,10 @@ var HTMLVideo = function(videoElement) {
} else if (arguments[0] === 'command') {
switch (arguments[1]) {
case 'load':
videoElement.src = arguments[2].source;
videoElement.src = arguments[2].url;
videoElement.autoplay = true;
if (!isNaN(arguments[2].time)) {
videoElement.currentTime = arguments[2].time / 1000;
if (!isNaN(arguments[3].time)) {
videoElement.currentTime = arguments[3].time / 1000;
}
videoElement.load();

View file

@ -1,6 +1,8 @@
var EventEmitter = require('events');
var YouTubeVideo = function(containerElement) {
var videoElement = document.createElement('div');
containerElement.appendChild(videoElement);
var events = new EventEmitter();
var ready = false;
var observedProps = {};
@ -87,7 +89,7 @@ var YouTubeVideo = function(containerElement) {
break;
}
};
var video = new YT.Player(containerElement, {
var video = new YT.Player(videoElement, {
height: '100%',
width: '100%',
playerVars: {
@ -174,8 +176,8 @@ var YouTubeVideo = function(containerElement) {
case 'load':
if (ready) {
video.loadVideoById({
videoId: arguments[2].source,
startSeconds: isNaN(arguments[2].time) ? 0 : arguments[2].time / 1000
videoId: arguments[2].ytId,
startSeconds: isNaN(arguments[3].time) ? 0 : arguments[3].time / 1000
});
}
break;

View file

@ -1,4 +0,0 @@
.html-video {
width: 100%;
height: 100%;
}