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 component = this; const container = this.refs.media; const { downloadPath, mediaType } = this.props; const loadedMetadata = e => { const media = this.refs.media.children[0]; if ("audio" === media.tagName.toLowerCase()) { // Load the entire audio file so that the length is available before playing let xhr = new XMLHttpRequest(); const xhrLoaded = () => { if (xhr.status === 200) { media.src = URL.createObjectURL(xhr.response); this.setState({ hasMetadata: true, startedPlaying: true }); media.play(); } }; xhr.open("GET", downloadPath, true); xhr.onload = xhrLoaded.bind(this); xhr.responseType = "blob"; xhr.send(); } else { this.setState({ hasMetadata: true, startedPlaying: true }); media.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; return { name: filename, createReadStream: opts => { return fs.createReadStream(downloadPath, opts); }, }; } *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 (
{["audio", "application"].indexOf(mediaType) !== -1 && (!this.playableType() || hasMetadata) && !unplayable && } {this.playableType() && !hasMetadata && !unplayable && } {unplayable && }
); } } export default VideoPlayer;