diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-11-19 16:35:06 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-11-19 16:35:06 +0100 |
| commit | 2db75c958876dca7e301ea387180342fc11d25a6 (patch) | |
| tree | e3206e8e33487dab02138e3b50b14ff5e1fa9467 | |
| parent | 17438f18e5943e5cdb12f2d4f9aed284c867e034 (diff) | |
implement audio volume fades within the skeleton dance video
6 files changed, 106 insertions, 10 deletions
diff --git a/animism-align/frontend/app/utils/vendor/vimeo/index.js b/animism-align/frontend/app/utils/vendor/vimeo/index.js index ffa374c..ebda418 100644 --- a/animism-align/frontend/app/utils/vendor/vimeo/index.js +++ b/animism-align/frontend/app/utils/vendor/vimeo/index.js @@ -69,7 +69,9 @@ class Vimeo extends React.Component { player.setLoop(value) break case 'volume': - player.setVolume(value) + if (!('targetVolume' in propNames)) { + player.setVolume(value) + } break case 'paused': player.getPaused().then((paused) => { @@ -114,7 +116,7 @@ class Vimeo extends React.Component { duration: value, easing: oktween.easing.quad_in_out, update: obj => { - console.log(obj.volume) + // console.log(obj.volume) player.setVolume(obj.volume) }, finished: () => { @@ -124,6 +126,25 @@ class Vimeo extends React.Component { }) break + case 'targetVolume': + if (this.props.muted || !value || this.fadeTween) return + console.log('fade audio to', value) + player.setVolume(value) + this.fadeTween = oktween.add({ + from: { volume: this.props.volume }, + to: { volume: this.props.targetVolume }, + duration: this.props.volumeFadeTime, + easing: oktween.easing.quad_in_out, + update: obj => { + // console.log(obj.volume) + player.setVolume(obj.volume) + }, + finished: () => { + this.fadeTween = null + } + }) + break + case 'video': if (value) { const { start } = this.props 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 56bb4ab..a947e2a 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 @@ -125,3 +125,28 @@ export const AnnotationFormVideo = ({ annotation, media, handleSettingsSelect, h </div> ) } + +export const AnnotationFormVideoSetVolume = ({ annotation, handleSettingsChange }) => { + return ( + <div className='options'> + <TextInput + title="Volume" + name="volume" + className="number" + placeholder="1.0" + data={annotation.settings} + onChange={handleSettingsChange} + autoComplete="off" + /> + <TextInput + title="Fade Time" + name="duration" + className="number" + placeholder="0:01" + data={annotation.settings} + onChange={handleSettingsChange} + autoComplete="off" + /> + </div> + ) +}
\ No newline at end of file diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js index 7b95332..8a1be48 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js @@ -7,6 +7,7 @@ import { import { AnnotationFormVideo, + AnnotationFormVideoSetVolume, } from './annotationForm.video' import { @@ -31,6 +32,7 @@ export const annotationFormLookup = { image: AnnotationFormImage, video: AnnotationFormVideo, + video_set_volume: AnnotationFormVideoSetVolume, gallery: AnnotationFormGallery, carousel: AnnotationFormGallery, diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.video.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.video.js index 4533a5d..4ea9595 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.video.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.video.js @@ -32,3 +32,20 @@ export const AnnotationVideo = ({ y, annotation, media, timeline, selected, onCl </div> ) } + +export const AnnotationVideoSetVolume = ({ y, annotation, timeline, selected, onClick, onDoubleClick }) => { + const className = selected ? 'annotation utility video_set_volume selected' : 'annotation utility video_set_volume' + let style = { + top: y, + } + return ( + <div + className={className} + style={style} + onClick={e => onClick(e, annotation)} + onDoubleClick={e => onDoubleClick(e, annotation)} + > + Set volume to {annotation.settings.volume} + </div> + ) +} diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js index 8fddee3..1a89dbd 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js @@ -12,6 +12,7 @@ import { import { AnnotationVideo, + AnnotationVideoSetVolume, } from './annotationTypes.video' import { @@ -40,6 +41,7 @@ export const AnnotationElementLookup = { subtitle: React.memo(AnnotationSubtitle), video: React.memo(AnnotationVideo), + video_set_volume: React.memo(AnnotationVideoSetVolume), image: React.memo(AnnotationImage), gallery: React.memo(AnnotationGallery), 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 cacd323..adbc443 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 @@ -24,6 +24,10 @@ class FullscreenVideo extends Component { ready: false, // trigger an audio fade-out fadeOut: false, + // volume + volume: 1.0, + volumeFadeTime: 1000, + lastCue: -1, } constructor(props) { super(props) @@ -43,17 +47,18 @@ class FullscreenVideo extends Component { } componentDidUpdate(prevProps) { // if the play_ts jumped more than a second, seek - const { play_ts, element, currentSection } = this.props + 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 (element.fadeOutDuration) { + if (fadeOutDuration) { // console.log("fade out audio", this.props.fadeOutDuration) setTimeout(() => this.setState({ fadeOut: true }), 0) } @@ -63,8 +68,28 @@ class FullscreenVideo extends Component { } } } - checkCuePosition() { - // if (this.) + 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 }) @@ -86,8 +111,8 @@ class FullscreenVideo extends Component { } render() { - const { element, media, transitionDuration, play_ts, playing, cc, volume } = this.props - const { duration, seconds, ready, fadeOut } = this.state + 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 = { @@ -99,6 +124,7 @@ class FullscreenVideo extends Component { opacity: ready ? 1.0 : 0.0 } // + // console.log(volume, playerVolume) return ( <div className='fullscreen-element video' @@ -119,12 +145,15 @@ class FullscreenVideo extends Component { responsive={true} controls={false} byline={false} - volume={element.settings.unmuted ? volume : 0.0} + 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 @@ -152,7 +181,7 @@ const mapStateToProps = state => ({ viewer: state.viewer, play_ts: state.audio.play_ts, playing: state.audio.playing, - volume: state.audio.volume, + playerVolume: state.audio.volume, cc: state.audio.cc, }) |
