Catch and render files with metadata at the end. Also notify if a file is
unplayable
This commit is contained in:
parent
96265b9ae6
commit
afcdd2271e
3 changed files with 77 additions and 9 deletions
|
@ -1,9 +1,9 @@
|
|||
import React from "react";
|
||||
|
||||
const LoadingScreen = ({ status }) =>
|
||||
const LoadingScreen = ({ status, spinner = true }) =>
|
||||
<div className="video__loading-screen">
|
||||
<div>
|
||||
<div className="video__loading-spinner" />
|
||||
{spinner && <div className="video__loading-spinner" />}
|
||||
|
||||
<div className="video__loading-status">
|
||||
{status}
|
||||
|
|
|
@ -2,30 +2,97 @@ import React from "react";
|
|||
import { Thumbnail } from "component/common";
|
||||
import player from "render-media";
|
||||
import fs from "fs";
|
||||
import LoadingScreen from "./loading-screen";
|
||||
|
||||
class VideoPlayer extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
hasMetadata: false,
|
||||
startedPlaying: false,
|
||||
unplayable: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const elem = this.refs.media;
|
||||
const container = this.refs.media;
|
||||
const { mediaType } = this.props;
|
||||
const loadedMetadata = e => {
|
||||
this.setState({ hasMetadata: true, startedPlaying: true });
|
||||
this.refs.media.children[0].play();
|
||||
};
|
||||
const renderMediaCallback = err => {
|
||||
if (err) this.setState({ unplayable: true });
|
||||
};
|
||||
|
||||
player.append(
|
||||
this.file(),
|
||||
container,
|
||||
{ autoplay: false, controls: true },
|
||||
renderMediaCallback.bind(this)
|
||||
);
|
||||
|
||||
const mediaElement = this.refs.media.children[0];
|
||||
if (mediaElement) {
|
||||
mediaElement.addEventListener(
|
||||
"loadedmetadata",
|
||||
loadedMetadata.bind(this),
|
||||
{
|
||||
once: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { mediaType, downloadCompleted } = this.props;
|
||||
const { startedPlaying } = this.state;
|
||||
|
||||
if (this.playableType() && !startedPlaying && downloadCompleted) {
|
||||
const container = this.refs.media.children[0];
|
||||
|
||||
player.render(this.file(), container, { autoplay: true, controls: true });
|
||||
}
|
||||
}
|
||||
|
||||
file() {
|
||||
const { downloadPath, filename } = this.props;
|
||||
const file = {
|
||||
|
||||
return {
|
||||
name: filename,
|
||||
createReadStream: opts => {
|
||||
return fs.createReadStream(downloadPath, opts);
|
||||
},
|
||||
};
|
||||
player.append(file, elem, {
|
||||
autoplay: true,
|
||||
controls: true,
|
||||
});
|
||||
}
|
||||
|
||||
playableType() {
|
||||
const { mediaType } = this.props;
|
||||
|
||||
return ["audio", "video"].indexOf(mediaType) !== -1;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { downloadPath, mediaType, poster } = this.props;
|
||||
const { mediaType, poster } = this.props;
|
||||
const { hasMetadata, unplayable } = this.state;
|
||||
const noMetadataMessage = "Waiting for metadata.";
|
||||
const unplayableMessage = "Sorry, looks like we can't play this file.";
|
||||
|
||||
const needsMetadata = this.playableType();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{["audio", "application"].indexOf(mediaType) !== -1 &&
|
||||
(!this.playableType() || hasMetadata) &&
|
||||
!unplayable &&
|
||||
<Thumbnail src={poster} className="video-embedded" />}
|
||||
{this.playableType() &&
|
||||
!hasMetadata &&
|
||||
!unplayable &&
|
||||
<LoadingScreen status={noMetadataMessage} />}
|
||||
{unplayable &&
|
||||
<LoadingScreen status={unplayableMessage} spinner={false} />}
|
||||
<div ref="media" />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -68,6 +68,7 @@ class Video extends React.PureComponent {
|
|||
poster={poster}
|
||||
downloadPath={fileInfo.download_path}
|
||||
mediaType={mediaType}
|
||||
downloadCompleted={fileInfo.completed}
|
||||
/>)}
|
||||
{!isPlaying &&
|
||||
<div
|
||||
|
|
Loading…
Reference in a new issue