Merge pull request #1044 from lbryio/issue/1012
Fixes Video Player "waits for metadata" bug
This commit is contained in:
commit
47cd0193b0
2 changed files with 59 additions and 64 deletions
|
@ -1,5 +1,4 @@
|
||||||
const { remote } = require('electron');
|
import { remote } from 'electron';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Thumbnail } from 'component/common';
|
import { Thumbnail } from 'component/common';
|
||||||
import player from 'render-media';
|
import player from 'render-media';
|
||||||
|
@ -21,33 +20,21 @@ class VideoPlayer extends React.PureComponent {
|
||||||
this.togglePlayListener = this.togglePlay.bind(this);
|
this.togglePlayListener = this.togglePlay.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(next) {
|
|
||||||
const el = this.refs.media.children[0];
|
|
||||||
if (!this.props.paused && next.paused && !el.paused) el.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const container = this.refs.media;
|
const container = this.media;
|
||||||
const {
|
const { contentType, changeVolume, volume, position, claim } = this.props;
|
||||||
contentType,
|
|
||||||
downloadPath,
|
|
||||||
mediaType,
|
|
||||||
changeVolume,
|
|
||||||
volume,
|
|
||||||
position,
|
|
||||||
claim,
|
|
||||||
uri,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const loadedMetadata = e => {
|
const loadedMetadata = () => {
|
||||||
this.setState({ hasMetadata: true, startedPlaying: true });
|
this.setState({ hasMetadata: true, startedPlaying: true });
|
||||||
this.refs.media.children[0].play();
|
this.media.children[0].play();
|
||||||
};
|
};
|
||||||
const renderMediaCallback = err => {
|
|
||||||
if (err) this.setState({ unplayable: true });
|
const renderMediaCallback = error => {
|
||||||
|
if (error) this.setState({ unplayable: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle fullscreen change for the Windows platform
|
// Handle fullscreen change for the Windows platform
|
||||||
const win32FullScreenChange = e => {
|
const win32FullScreenChange = () => {
|
||||||
const win = remote.BrowserWindow.getFocusedWindow();
|
const win = remote.BrowserWindow.getFocusedWindow();
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
win.setMenu(document.webkitIsFullScreen ? null : remote.Menu.getApplicationMenu());
|
win.setMenu(document.webkitIsFullScreen ? null : remote.Menu.getApplicationMenu());
|
||||||
|
@ -61,13 +48,13 @@ class VideoPlayer extends React.PureComponent {
|
||||||
player.append(
|
player.append(
|
||||||
this.file(),
|
this.file(),
|
||||||
container,
|
container,
|
||||||
{ autoplay: false, controls: true },
|
{ autoplay: true, controls: true },
|
||||||
renderMediaCallback.bind(this)
|
renderMediaCallback.bind(this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('keydown', this.togglePlayListener);
|
document.addEventListener('keydown', this.togglePlayListener);
|
||||||
const mediaElement = this.refs.media.children[0];
|
const mediaElement = this.media.children[0];
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
mediaElement.currentTime = position || 0;
|
mediaElement.currentTime = position || 0;
|
||||||
mediaElement.addEventListener('play', () => this.props.doPlay());
|
mediaElement.addEventListener('play', () => this.props.doPlay());
|
||||||
|
@ -87,29 +74,38 @@ class VideoPlayer extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(next) {
|
||||||
|
const el = this.media.children[0];
|
||||||
|
if (!this.props.paused && next.paused && !el.paused) el.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { contentType, downloadCompleted } = this.props;
|
||||||
|
const { startedPlaying } = this.state;
|
||||||
|
|
||||||
|
if (this.playableType() && !startedPlaying && downloadCompleted) {
|
||||||
|
const container = this.media.children[0];
|
||||||
|
|
||||||
|
if (VideoPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
|
||||||
|
this.renderAudio(this.media, true);
|
||||||
|
} else {
|
||||||
|
player.render(this.file(), container, {
|
||||||
|
autoplay: true,
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
document.removeEventListener('keydown', this.togglePlayListener);
|
document.removeEventListener('keydown', this.togglePlayListener);
|
||||||
const mediaElement = this.refs.media.children[0];
|
const mediaElement = this.media.children[0];
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
mediaElement.removeEventListener('click', this.togglePlayListener);
|
mediaElement.removeEventListener('click', this.togglePlayListener);
|
||||||
}
|
}
|
||||||
this.props.doPause();
|
this.props.doPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderAudio(container, autoplay) {
|
|
||||||
if (container.firstChild) {
|
|
||||||
container.firstChild.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear the container
|
|
||||||
const { downloadPath } = this.props;
|
|
||||||
const audio = document.createElement('audio');
|
|
||||||
audio.autoplay = autoplay;
|
|
||||||
audio.controls = true;
|
|
||||||
audio.src = downloadPath;
|
|
||||||
container.appendChild(audio);
|
|
||||||
}
|
|
||||||
|
|
||||||
togglePlay(event) {
|
togglePlay(event) {
|
||||||
// ignore all events except click and spacebar keydown, or input events in a form control
|
// ignore all events except click and spacebar keydown, or input events in a form control
|
||||||
if (
|
if (
|
||||||
|
@ -119,7 +115,7 @@ class VideoPlayer extends React.PureComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const mediaElement = this.refs.media.children[0];
|
const mediaElement = this.media.children[0];
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
if (!mediaElement.paused) {
|
if (!mediaElement.paused) {
|
||||||
mediaElement.pause();
|
mediaElement.pause();
|
||||||
|
@ -129,24 +125,6 @@ class VideoPlayer extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
|
||||||
const { contentType, downloadCompleted } = this.props;
|
|
||||||
const { startedPlaying } = this.state;
|
|
||||||
|
|
||||||
if (this.playableType() && !startedPlaying && downloadCompleted) {
|
|
||||||
const container = this.refs.media.children[0];
|
|
||||||
|
|
||||||
if (VideoPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
|
|
||||||
this.renderAudio(this.refs.media, true);
|
|
||||||
} else {
|
|
||||||
player.render(this.file(), container, {
|
|
||||||
autoplay: true,
|
|
||||||
controls: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file() {
|
file() {
|
||||||
const { downloadPath, filename } = this.props;
|
const { downloadPath, filename } = this.props;
|
||||||
|
|
||||||
|
@ -162,14 +140,26 @@ class VideoPlayer extends React.PureComponent {
|
||||||
return ['audio', 'video'].indexOf(mediaType) !== -1;
|
return ['audio', 'video'].indexOf(mediaType) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAudio(container, autoplay) {
|
||||||
|
if (container.firstChild) {
|
||||||
|
container.firstChild.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the container
|
||||||
|
const { downloadPath } = this.props;
|
||||||
|
const audio = document.createElement('audio');
|
||||||
|
audio.autoplay = autoplay;
|
||||||
|
audio.controls = true;
|
||||||
|
audio.src = downloadPath;
|
||||||
|
container.appendChild(audio);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { mediaType, poster } = this.props;
|
const { mediaType, poster } = this.props;
|
||||||
const { hasMetadata, unplayable } = this.state;
|
const { hasMetadata, unplayable } = this.state;
|
||||||
const noMetadataMessage = 'Waiting for metadata.';
|
const noMetadataMessage = 'Waiting for metadata.';
|
||||||
const unplayableMessage = "Sorry, looks like we can't play this file.";
|
const unplayableMessage = "Sorry, looks like we can't play this file.";
|
||||||
|
|
||||||
const needsMetadata = this.playableType();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{['audio', 'application'].indexOf(mediaType) !== -1 &&
|
{['audio', 'application'].indexOf(mediaType) !== -1 &&
|
||||||
|
@ -179,7 +169,12 @@ class VideoPlayer extends React.PureComponent {
|
||||||
!hasMetadata &&
|
!hasMetadata &&
|
||||||
!unplayable && <LoadingScreen status={noMetadataMessage} />}
|
!unplayable && <LoadingScreen status={noMetadataMessage} />}
|
||||||
{unplayable && <LoadingScreen status={unplayableMessage} spinner={false} />}
|
{unplayable && <LoadingScreen status={unplayableMessage} spinner={false} />}
|
||||||
<div ref="media" className="media" />
|
<div
|
||||||
|
ref={container => {
|
||||||
|
this.media = container;
|
||||||
|
}}
|
||||||
|
className="media"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@ import { remote } from 'electron';
|
||||||
|
|
||||||
const application = remote.app;
|
const application = remote.app;
|
||||||
const { dock } = application;
|
const { dock } = application;
|
||||||
const win = remote.BrowserWindow.getFocusedWindow();
|
const browserWindow = remote.getCurrentWindow();
|
||||||
const setBadge = text => {
|
const setBadge = text => {
|
||||||
if (!dock) return;
|
if (!dock) return;
|
||||||
if (win.isFocused()) return;
|
if (browserWindow.isFocused()) return;
|
||||||
|
|
||||||
dock.setBadge(text);
|
dock.setBadge(text);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue