Catch and render files with metadata at the end. Also notify if a file is

unplayable
This commit is contained in:
6ea86b96 2017-06-11 00:07:28 +07:00
parent 96265b9ae6
commit afcdd2271e
3 changed files with 77 additions and 9 deletions

View file

@ -1,9 +1,9 @@
import React from "react"; import React from "react";
const LoadingScreen = ({ status }) => const LoadingScreen = ({ status, spinner = true }) =>
<div className="video__loading-screen"> <div className="video__loading-screen">
<div> <div>
<div className="video__loading-spinner" /> {spinner && <div className="video__loading-spinner" />}
<div className="video__loading-status"> <div className="video__loading-status">
{status} {status}

View file

@ -2,30 +2,97 @@ import React from "react";
import { Thumbnail } from "component/common"; import { Thumbnail } from "component/common";
import player from "render-media"; import player from "render-media";
import fs from "fs"; import fs from "fs";
import LoadingScreen from "./loading-screen";
class VideoPlayer extends React.PureComponent { class VideoPlayer extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
hasMetadata: false,
startedPlaying: false,
unplayable: false,
};
}
componentDidMount() { 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 { downloadPath, filename } = this.props;
const file = {
return {
name: filename, name: filename,
createReadStream: opts => { createReadStream: opts => {
return fs.createReadStream(downloadPath, 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() { 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 ( return (
<div> <div>
{["audio", "application"].indexOf(mediaType) !== -1 && {["audio", "application"].indexOf(mediaType) !== -1 &&
(!this.playableType() || hasMetadata) &&
!unplayable &&
<Thumbnail src={poster} className="video-embedded" />} <Thumbnail src={poster} className="video-embedded" />}
{this.playableType() &&
!hasMetadata &&
!unplayable &&
<LoadingScreen status={noMetadataMessage} />}
{unplayable &&
<LoadingScreen status={unplayableMessage} spinner={false} />}
<div ref="media" /> <div ref="media" />
</div> </div>
); );

View file

@ -68,6 +68,7 @@ class Video extends React.PureComponent {
poster={poster} poster={poster}
downloadPath={fileInfo.download_path} downloadPath={fileInfo.download_path}
mediaType={mediaType} mediaType={mediaType}
downloadCompleted={fileInfo.completed}
/>)} />)}
{!isPlaying && {!isPlaying &&
<div <div