lbry-desktop/ui/js/component/video/internal/player.jsx
2017-07-06 18:33:44 +01:00

126 lines
3.3 KiB
JavaScript

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 {
static MP3_CONTENT_TYPES = ["audio/mpeg3", "audio/mpeg"];
constructor(props) {
super(props);
this.state = {
hasMetadata: false,
startedPlaying: false,
unplayable: false,
};
}
componentDidMount() {
const component = this;
const container = this.refs.media;
const { contentType, downloadPath, 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 });
};
// use renderAudio override for mp3
if (VideoPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
this.renderAudio(container, false);
} else {
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,
}
);
}
}
renderAudio(container, autoplay) {
const { downloadPath } = this.props;
const audio = document.createElement("audio");
audio.autoplay = autoplay;
audio.controls = true;
audio.src = downloadPath;
container.appendChild(audio);
}
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(container, true);
} else {
player.render(this.file(), container, {
autoplay: true,
controls: true,
});
}
}
}
file() {
const { downloadPath, filename } = this.props;
const stat = fs.statSync(downloadPath);
return {
name: filename,
createReadStream: opts => {
return fs.createReadStream(downloadPath, opts);
},
length: stat.size,
};
}
*playableType() {
const { mediaType } = this.props;
return ["audio", "video"].indexOf(mediaType) !== -1;
}
render() {
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>
);
}
}
export default VideoPlayer;