diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-12-02 15:00:48 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-12-02 15:00:48 +0100 |
| commit | fa287a8b341926fa3866d7dee31b4f4090a5c98f (patch) | |
| tree | 62a72177acaf569a444e4d06a09ed8b705647920 /animism-align/frontend/app/views/viewer/modals/modals.video.js | |
| parent | 441b9efe7a76e801d5d079a70dcb4aeb1a132bb9 (diff) | |
starting full video modal
Diffstat (limited to 'animism-align/frontend/app/views/viewer/modals/modals.video.js')
| -rw-r--r-- | animism-align/frontend/app/views/viewer/modals/modals.video.js | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/animism-align/frontend/app/views/viewer/modals/modals.video.js b/animism-align/frontend/app/views/viewer/modals/modals.video.js new file mode 100644 index 0000000..e94b4c4 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/modals/modals.video.js @@ -0,0 +1,188 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import VimeoPlayer from 'app/utils/vendor/vimeo' + +import actions from 'app/actions' +import { timestampToSeconds } from 'app/utils' +import { VideoScrubber, VideoSubtitles } from '../components.media' + +class ModalVideo extends Component { + state = { + // duration of the video, in seconds + duration: 60.0, + // percentage offset from vimeo. not used + percent: 0.0, + // current timestamp from vimeo, in seconds + seconds: 0.0, + // video start offset, in seconds + video_start_ts: 0.0, + // seek position, used to tell the player to seek + seek: 0.0, + // whether or not the scrubber is scrubbing + scrubbing: false, + // whether or not the video is ready and displaying an image + ready: false, + // trigger an audio fade-out + fadeOut: false, + // volume + volume: 1.0, + volumeFadeTime: 1000, + lastCue: -1, + } + constructor(props) { + super(props) + this.handlePlay = this.handlePlay.bind(this) + this.handlePause = this.handlePause.bind(this) + this.handleTimeUpdate = this.handleTimeUpdate.bind(this) + this.handleScrub = this.handleScrub.bind(this) + this.handleEnd = this.handleEnd.bind(this) + } + componentDidMount() { + const video_start_ts = timestampToSeconds(this.props.element.settings.video_start_ts) || 0.0 + // TODO: here you can add the current play time modulo ... + this.setState({ + seek: video_start_ts, + video_start_ts, + }) + } + componentDidUpdate(prevProps) { + // if the play_ts jumped more than a second, seek + const { play_ts, element, currentSection, fadeOutDuration } = this.props + if (Math.abs(play_ts - prevProps.play_ts) > 1.0) { + // handle seek + const { duration, video_start_ts } = this.state + const seek = ((play_ts - element.start_ts) % duration) + video_start_ts + this.setState({ seek }) + } + // console.log(play_ts, currentSection.cues.length, fadeOutDuration, element.settings.unmuted, this.state.fadeOut) + // volume changes - only if unmuted and not already leaving. + if (element.settings.unmuted && !this.state.fadeOut) { + // if we just started leaving the element, fade out the audio + if (fadeOutDuration) { + // console.log("fade out audio", this.props.fadeOutDuration) + setTimeout(() => this.setState({ fadeOut: true }), 0) + } + // otherwise, check if we gotta set the volume based on the position + else if (currentSection.cues.length) { + this.checkCuePosition(play_ts, currentSection.cues) + } + } + } + checkCuePosition(play_ts, cues) { + // const { volume element.settings.unmuted ? volume : 0.0 + const { unmuted } = this.props.element.settings + let volume = unmuted ? 1.0 : 0.0 + let { volumeFadeTime, lastCue } = this.state + // console.log(cues) + cues.some((cue, i) => { + if (cue.start_ts < play_ts) { + lastCue = i + if (cue.settings.volume) { + volume = parseFloat(cue.settings.volume) + volumeFadeTime = timestampToSeconds(cue.settings.duration) * 1000 + // console.log(volume, volumeFadeTime) + return false + } + } + return true + }) + // console.log('last cue', lastCue, volume, volumeFadeTime) + if (lastCue !== this.state.lastCue) { + this.setState({ volume, volumeFadeTime, lastCue }) + } + } + handlePlay() { + this.setState({ ready: true }) + } + handlePause() { + + } + handleEnd() { + + } + handleTimeUpdate(timing) { + if (!this.state.scrubbing || ('scrubbing' in timing)) { + this.setState(timing) + } + } + handleScrub(timing) { + // console.log(timing) + this.setState(timing) + } + + render() { + const { element, media, transitionDuration, play_ts, playing, cc, playerVolume } = this.props + const { duration, seconds, ready, volume, volumeFadeTime, fadeOut, lastCue } = this.state + const { color } = element + const item = media.lookup[element.settings.media_id] + const style = { + backgroundColor: color.backgroundColor, + color: color.textColor, + transitionDuration, + } + const playerStyle = { + opacity: ready ? 1.0 : 0.0 + } + // + // console.log(volume, playerVolume) + return ( + <div + className='fullscreen-element video' + style={style} + > + <div + className='videoPlayer' + style={playerStyle} + > + <VimeoPlayer + video={item.url} + paused={!playing} + autoplay={true} + autopause={false} + muted={!element.settings.unmuted} + loop={!!element.settings.loop} + seek={this.state.seek} + responsive={true} + controls={false} + byline={false} + volume={element.settings.unmuted ? playerVolume : 0.0} + targetVolume={element.settings.unmuted ? volume * playerVolume : 0.0} + volumeFadeTime={volumeFadeTime} + fadeOut={fadeOut && this.props.fadeOutDuration} + onPlay={this.handlePlay} + onPause={this.handlePause} + onTimeUpdate={this.handleTimeUpdate} + onEnd={this.handleEnd} + lastCue={lastCue} + /> + </div> + <VideoScrubber + play_ts={play_ts} + start_ts={element.start_ts} + video_start_ts={this.state.video_start_ts} + playing={playing} + duration={element.duration} + timing={this.state} + mediaItem={item} + cc={cc} + onScrub={this.handleScrub} + /> + <VideoSubtitles + cc={cc} + play_ts={seconds} + mediaItem={item} + /> + </div> + ) + } +} + +const mapStateToProps = state => ({ + viewer: state.viewer, + play_ts: state.audio.play_ts, + playing: state.audio.playing, + playerVolume: state.audio.volume, + cc: state.audio.cc, +}) + +export default connect(mapStateToProps)(ModalVideo) |
