diff options
3 files changed, 54 insertions, 9 deletions
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js index 70d42f2..12a322c 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js @@ -1,7 +1,7 @@ import React, { Component } from 'react' import { CURTAIN_COLOR_SELECT_OPTIONS, IMAGE_BACKGROUND_SIZE_OPTIONS } from 'app/constants' -import { Select, Checkbox } from 'app/common' +import { Select, Checkbox, TextInput, LabelDescription } from 'app/common' import { AnnotationFormFullscreen } from './annotationForm.utility' export const AnnotationFormVideo = ({ annotation, media, handleSettingsSelect, handleSettingsChange }) => { @@ -92,6 +92,18 @@ export const AnnotationFormVideo = ({ annotation, media, handleSettingsSelect, h defaultOption='Select size' onChange={handleSettingsSelect} /> + <TextInput + title="Video start time" + name="video_start_ts" + className="number" + placeholder="0:00" + data={annotation.settings} + onChange={handleSettingsChange} + autoComplete="off" + /> + <LabelDescription> + {'Auto-advances the video to this point when starting'} + </LabelDescription> {(annotation.settings.fullscreen && !annotation.settings.inline) && ( <AnnotationFormFullscreen diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js index 78c7807..b8d1a62 100644 --- a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js +++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js @@ -3,14 +3,22 @@ import { connect } from 'react-redux' import VimeoPlayer from 'app/utils/vendor/vimeo' import actions from 'app/actions' +import { timestampToSeconds } from 'app/utils' import { VideoScrubber } from '../components.media' class FullscreenVideo extends Component { state = { + // duration of the video, in seconds duration: 0.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, } constructor(props) { @@ -20,6 +28,14 @@ class FullscreenVideo extends Component { this.handleTimeUpdate = this.handleTimeUpdate.bind(this) this.handleEnd = this.handleEnd.bind(this) } + componentDidMount() { + const { video_start_ts } = this.props.element.settings + const seconds = timestampToSeconds(video_start_ts) || 0.0 + this.setState({ + video_start_ts: seconds, + seek: seconds, + }) + } componentDidUpdate(prevProps) { if (Math.abs(this.props.play_ts - prevProps.play_ts) > 1.0) { // handle seek @@ -44,7 +60,7 @@ class FullscreenVideo extends Component { render() { const { element, media, transitionDuration, playing } = this.props - const { duration, percent, seconds } = this.state + const { duration, seconds } = this.state const { color } = element const item = media.lookup[element.settings.media_id] const style = { @@ -52,6 +68,7 @@ class FullscreenVideo extends Component { color: color.textColor, transitionDuration, } + // return ( <div className='fullscreen-element video' @@ -76,6 +93,7 @@ class FullscreenVideo extends Component { </div> <VideoScrubber start_ts={element.start_ts} + video_start_ts={this.state.video_start_ts} playing={playing} duration={element.duration} timing={this.state} diff --git a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js index 01255f6..bb6a753 100644 --- a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js +++ b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js @@ -43,14 +43,22 @@ class VideoScrubber extends Component { this.setState({ showing: false }) } scrub(x, scrubbing) { - const { timing, start_ts, onScrub, duration } = this.props + const { timing, start_ts, video_start_ts, onScrub, duration } = this.props const bounds = this.scrubberRef.current.getBoundingClientRect() + // get percent offset from the scrubber const percent = clamp((x - bounds.left) / bounds.width, 0, 1) + // this offset in seconds based on the length of the fullscreen element const seconds = percent * duration + // we can use this to seek the audio actions.audio.seek(start_ts + seconds) + // apply the video start offset. + // in case the video loops, modulo the length of the original video + const video_seek = ((seconds + video_start_ts) % timing.duration) + // onScrub({ - seek: seconds % timing.duration, - percent, seconds, scrubbing + seek: video_seek, + seconds: video_seek, + scrubbing, }) } handleMouseDown(e) { @@ -74,10 +82,17 @@ class VideoScrubber extends Component { this.setState({ hovering: false }) } render() { - const { playing, volume, timing, duration } = this.props + const { playing, volume, timing, video_start_ts, duration } = this.props const { hovering, showing } = this.state - const timestampText = timestamp(clamp(timing.seconds, 0, duration)) + // remove video start offset from timing + const player_ts = timing.seconds - video_start_ts + // compute percent from the length of the fullscreen element + const percent = player_ts / duration + // display timestamp from the fullscreen element too + const timestampText = timestamp(clamp(player_ts, 0, duration)) + // show or hide the scrubber bar const className = (hovering || showing) ? 'video-scrubber show' : 'video-scrubber' + // console.log(timing.seconds, video_start_ts, duration) return ( <div className={className}> <div className='start-controls'> @@ -93,11 +108,11 @@ class VideoScrubber extends Component { <div className='scrub-bar' /> <div className='scrub-dot' - style={{ left: (100 * timing.percent) + "%" }} + style={{ left: (100 * percent) + "%" }} /> <div className='scrub-timestamp' - style={{ left: (100 * (timing.percent)) + "%" }} + style={{ left: (100 * percent) + "%" }} > {timestampText} </div> |
