diff --git a/__tests__/integration/mirador/index.html b/__tests__/integration/mirador/index.html index 67f6e82576ebea4a85f7dbadf4014410867cacaa..fc88683c3572037819a402c9f2fa0a394f7bf3b4 100644 --- a/__tests__/integration/mirador/index.html +++ b/__tests__/integration/mirador/index.html @@ -15,15 +15,13 @@ theme: { transitions: window.location.port === '4488' ? { create: () => 'none' } : {}, }, - windows: [{ - manifestId: 'https://iiif.harvardartmuseums.org/manifests/object/299843', - canvasId: 'https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174892', - thumbnailNavigationPosition: 'far-bottom', - }, - { - manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json', - }], catalog: [ + { manifestId: 'https://dzkimgs.l.u-tokyo.ac.jp/videos/iiif_in_japan_2017/manifest.json' }, + { manifestId: 'https://iiif.io/api/cookbook/recipe/0219-using-caption-file/manifest.json' }, + { manifestId: 'https://preview.iiif.io/cookbook/master/recipe/0003-mvm-video/manifest.json' }, + { manifestId: 'https://iiif.io/api/cookbook/recipe/0065-opera-multiple-canvases/manifest.json' }, + { manifestId: 'https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/manifest.json' }, + { manifestId: 'https://iiif.io/api/cookbook/recipe/0074-multiple-language-captions/manifest.json' }, { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json' }, { manifestId: 'https://iiif.harvardartmuseums.org/manifests/object/299843' }, { manifestId: "https://media.nga.gov/public/manifests/nga_highlights.json", provider: "National Gallery of Art"}, diff --git a/src/components/AnnotationsOverlayVideo.js b/src/components/AnnotationsOverlayVideo.js index bc4562cfcf609a475fa6823556286994f6edb571..f8adfc6f7b83ec5471c0b0cbe64153635211f57e 100755 --- a/src/components/AnnotationsOverlayVideo.js +++ b/src/components/AnnotationsOverlayVideo.js @@ -114,36 +114,26 @@ export class AnnotationsOverlayVideo extends Component { hoveredAnnotationIds, selectedAnnotationId, highlightAllAnnotations, paused, - seekToTime, + setCurrentTime, } = this.props; this.initializeViewer(); - let prevVideoPausedState; if (this.video) { - prevVideoPausedState = this.video.paused; - if (this.video.paused && !paused) { - const promise = this.video.play(); - if (promise !== undefined) { - promise.catch((e) => {}); - } - } else if (!this.video.paused && paused) { + if (paused && !this.video.paused) { this.video.pause(); + } else if (!paused && this.video.paused) { + this.video.play(); } - if (seekToTime !== prevProps.seekToTime) { - if (seekToTime !== undefined) { - this.seekTo(seekToTime, true); - return; - } + + // TODO another action // better way to determine if user changed time + // or if video is normally playing (both events modifies currentTime) + if (currentTime < prevProps.currentTime || (currentTime - prevProps.currentTime) > 1) { + this.video.currentTime = currentTime - this.temporalOffset; } if (this.video.seeking) { return; } - if (currentTime !== prevProps.currentTime) { - if (paused && this.video.paused) { - this.video.currentTime = currentTime - this.temporalOffset; - } - } } const annotationsUpdated = !AnnotationsOverlayVideo.annotationsMatch( @@ -179,7 +169,7 @@ export class AnnotationsOverlayVideo extends Component { const temporalfragment = resource.temporalfragmentSelector; if (temporalfragment && temporalfragment.length > 0 && this.video) { const seekto = temporalfragment[0] || 0; - this.seekTo(seekto, !prevVideoPausedState); + setCurrentTime(seekto); } } }); @@ -259,6 +249,7 @@ export class AnnotationsOverlayVideo extends Component { /** */ onVideoTimeUpdate(event) { + this.props.setCurrentTime(event.target.currentTime); this.updateCanvas(); } @@ -273,15 +264,6 @@ export class AnnotationsOverlayVideo extends Component { /** */ onVideoPlaying(event) { - if (this.video && this.video.currentTime !== 0) { - const { currentTime, seekToTime } = this.props; - const currentTimeToVideoTime = currentTime - this.temporalOffset; - const diff = Math.abs(currentTimeToVideoTime - this.video.currentTime); - const acceptableDiff = 1; // sec. - if (diff > acceptableDiff && seekToTime === undefined) { - this.seekTo(this.video.currentTime + this.temporalOffset, true); - } - } this.setState({ showProgress: false }); } @@ -436,19 +418,6 @@ export class AnnotationsOverlayVideo extends Component { return imageSource; } - /** @private */ - seekTo(seekTo, resume) { - const { setCurrentTime, setPaused } = this.props; - setPaused(true); - setCurrentTime(seekTo); - this.video.addEventListener('seeked', function seeked(event) { - event.currentTarget.removeEventListener(event.type, seeked); - if (resume) { - setPaused(false); - } - }); - } - /** @private */ isCanvasSizeSpecified() { const { canvas, canvasWorld } = this.props; @@ -648,7 +617,6 @@ AnnotationsOverlayVideo.defaultProps = { palette: {}, paused: true, searchAnnotations: [], - seekToTime: undefined, selectAnnotation: () => {}, selectedAnnotationId: undefined, setCurrentTime: () => {}, @@ -670,7 +638,6 @@ AnnotationsOverlayVideo.propTypes = { palette: PropTypes.object, // eslint-disable-line react/forbid-prop-types paused: PropTypes.bool, searchAnnotations: PropTypes.arrayOf(PropTypes.object), - seekToTime: PropTypes.number, selectAnnotation: PropTypes.func, selectedAnnotationId: PropTypes.string, setCurrentTime: PropTypes.func, diff --git a/src/components/VideoViewer.js b/src/components/VideoViewer.js index d13ebbdafd40db0370f8fd8b840960ce6e03cdaf..a194d5bf7444a6ec52f79a659f6d2e38b3578dd9 100644 --- a/src/components/VideoViewer.js +++ b/src/components/VideoViewer.js @@ -12,11 +12,6 @@ export class VideoViewer extends Component { constructor(props) { super(props); this.videoRef = React.createRef(); - - this.state = { - start: 0, - time: 0, - }; } /** */ @@ -37,32 +32,7 @@ export class VideoViewer extends Component { /** */ componentDidUpdate(prevProps) { - const { - canvas, currentTime, muted, paused, - setCurrentTime, setPaused, - textTrackDisabled, - } = this.props; - - if (paused !== prevProps.paused) { - if (currentTime === 0) { - this.timerReset(); - } - if (paused) { - this.timerStop(); - } else { - this.timerStart(); - } - } - if (currentTime !== prevProps.currentTime) { - const duration = canvas.getDuration(); - if (duration && duration < currentTime) { - if (!paused) { - setPaused(true); - setCurrentTime(0); - this.timerReset(); - } - } - } + const { muted, textTrackDisabled } = this.props; const video = this.videoRef.current; if (video) { if (video.muted !== muted) { @@ -77,38 +47,6 @@ export class VideoViewer extends Component { } } - /** */ - componentWillUnmount() { - this.timerStop(); - } - - /** */ - timerStart() { - const { currentTime } = this.props; - this.setState({ - start: Date.now() - currentTime * 1000, - time: currentTime * 1000, - }); - this.timer = setInterval(() => { - const { setCurrentTime } = this.props; - this.setState(prevState => ({ - time: Date.now() - prevState.start, - })); - const { time } = this.state; - setCurrentTime(time / 1000); - }, 100); - } - - /** */ - timerStop() { - clearInterval(this.timer); - } - - /** */ - timerReset() { - this.setState({ time: 0 }); - } - /* eslint-disable jsx-a11y/media-has-caption */ /** */ render() { @@ -184,7 +122,6 @@ VideoViewer.propTypes = { currentTime: PropTypes.number, muted: PropTypes.bool, paused: PropTypes.bool, - setCurrentTime: PropTypes.func, setHasTextTrack: PropTypes.func, setPaused: PropTypes.func, textTrackDisabled: PropTypes.bool, @@ -198,7 +135,6 @@ VideoViewer.defaultProps = { currentTime: 0, muted: false, paused: true, - setCurrentTime: () => {}, setHasTextTrack: () => {}, setPaused: () => {}, textTrackDisabled: true, diff --git a/src/components/ViewerNavigationVideo.js b/src/components/ViewerNavigationVideo.js index 0542fe7f61f93d3e123ecf01bcfc6dfa97853c62..0556f0bdb7b55bb6268fc79974324b1d2fae47f0 100755 --- a/src/components/ViewerNavigationVideo.js +++ b/src/components/ViewerNavigationVideo.js @@ -21,12 +21,9 @@ export class ViewerNavigationVideo extends Component { /** */ handleChange = (event, newValue) => { - const { paused, setCurrentTime, setSeekTo } = this.props; - if (!paused) { - setSeekTo(newValue); - } else { - setCurrentTime(newValue); - } + const { setCurrentTime } = this.props; + console.debug('[ViewerNavigationVideo] slider changed', event.type, newValue); + setCurrentTime(newValue); }; /** @@ -54,7 +51,13 @@ export class ViewerNavigationVideo extends Component { durationLabel = `${durationLabel} / ${new Date(duration * 1000).toISOString().substr(start, len)}`; slider = ( <div className={classes.sliderDiv}> - <Slider value={currentTime} min={0} max={duration} onChange={this.handleChange} /> + <Slider + value={currentTime} + min={0} + max={duration} + onChange={this.handleChange} + onChangeCommitted={this.handleChange} + /> </div> ); } @@ -105,7 +108,6 @@ ViewerNavigationVideo.propTypes = { setCurrentTime: PropTypes.func, setMuted: PropTypes.func, setPaused: PropTypes.func, - setSeekTo: PropTypes.func, setTextTrackDisabled: PropTypes.func, textTrackDisabled: PropTypes.bool, }; @@ -119,7 +121,6 @@ ViewerNavigationVideo.defaultProps = { setCurrentTime: () => {}, setMuted: () => {}, setPaused: () => {}, - setSeekTo: () => {}, setTextTrackDisabled: () => {}, textTrackDisabled: true, }; diff --git a/src/containers/AnnotationsOverlayVideo.js b/src/containers/AnnotationsOverlayVideo.js index bc32f71b81be0fe8707c4bf8a1a9de9cf62e76bd..5840561d5dedb024821da17351a371315f04539b 100755 --- a/src/containers/AnnotationsOverlayVideo.js +++ b/src/containers/AnnotationsOverlayVideo.js @@ -13,7 +13,6 @@ import { getConfig, getCurrentCanvas, getWindowCurrentTime, - getWindowSeekToTime, getWindowPausedStatus, getPresentAnnotationsOnSelectedCanvases, getSelectedAnnotationId, @@ -40,7 +39,6 @@ const mapStateToProps = (state, { windowId }) => ({ state, { windowId }, ), - seekToTime: getWindowSeekToTime(state, { windowId }), selectedAnnotationId: getSelectedAnnotationId(state, { windowId }), }); diff --git a/src/containers/ViewerNavigationVideo.js b/src/containers/ViewerNavigationVideo.js index 5d894b0d921a2b052c8b4156c0bc0e7466a5b6e2..67a5c1057395ebe777a668dd5ccef30cfc6e6ac9 100755 --- a/src/containers/ViewerNavigationVideo.js +++ b/src/containers/ViewerNavigationVideo.js @@ -33,7 +33,6 @@ const mapDispatchToProps = (dispatch, { windowId }) => ({ setCurrentTime: (...args) => dispatch(actions.setWindowCurrentTime(windowId, ...args)), setMuted: (...args) => dispatch(actions.setWindowMuted(windowId, ...args)), setPaused: (...args) => dispatch(actions.setWindowPaused(windowId, ...args)), - setSeekTo: (...args) => dispatch(actions.setWindowSeekTo(windowId, ...args)), setTextTrackDisabled: (...args) => dispatch( actions.setWindowTextTrackDisabled(windowId, ...args), ), diff --git a/src/state/actions/action-types.js b/src/state/actions/action-types.js index f234ac6ba33667f743f19e880544af86fcc5c56a..b6e78e6a6b11d9623159a5b500189857e79cf8f8 100644 --- a/src/state/actions/action-types.js +++ b/src/state/actions/action-types.js @@ -75,7 +75,6 @@ const ActionTypes = { HIDE_COLLECTION_DIALOG: 'mirador/HIDE_COLLECTION_DIALOG', SET_CURRENT_TIME: 'mirador/SET_CURRENT_TIME', - SET_SEEK_TO_TIME: 'mirador/SET_SEEK_TO_TIME', SET_VIDEO_PAUSED: 'mirador/SET_VIDEO_PAUSED', SET_VIDEO_MUTED: 'mirador/SET_VIDEO_MUTED', SET_VIDEO_TEXTTRACK_DISABLED: 'mirador/SET_VIDEO_TEXTTRACK_DISABLED', diff --git a/src/state/actions/window.js b/src/state/actions/window.js index 2609358ab702ca215e6f4bbbb55ebd751cbf6624..8cce3cb72b2e5b2f3d556cd62bd2c94315dc4542 100644 --- a/src/state/actions/window.js +++ b/src/state/actions/window.js @@ -222,17 +222,6 @@ export function setWindowCurrentTime(windowId, currentTime) { }); } -/** */ -export function setWindowSeekTo(windowId, seekToTime) { - return ((dispatch) => { - dispatch({ - seekToTime, - type: ActionTypes.SET_SEEK_TO_TIME, - windowId, - }); - }); -} - /** */ export function setWindowPaused(windowId, paused) { return ((dispatch) => { diff --git a/src/state/reducers/windows.js b/src/state/reducers/windows.js index 1009c575f60cea6c9fac8349ab64b5b2b779ffe2..ef77f707f538454a9049c027c760cdc09823d394 100644 --- a/src/state/reducers/windows.js +++ b/src/state/reducers/windows.js @@ -184,14 +184,6 @@ export const windowsReducer = (state = {}, action) => { currentTime: action.currentTime, }, }; - case ActionTypes.SET_SEEK_TO_TIME: - return { - ...state, - [action.windowId]: { - ...state[action.windowId], - seekToTime: action.seekToTime, - }, - }; case ActionTypes.SET_VIDEO_PAUSED: return { ...state, diff --git a/src/state/selectors/window.js b/src/state/selectors/window.js index 62a526c9d4b2d4bef455d53f0f2d7bbc82746585..51efd7bf94490fdc28590f240ce29e2e922c718c 100755 --- a/src/state/selectors/window.js +++ b/src/state/selectors/window.js @@ -12,17 +12,6 @@ export const getWindowCurrentTime = createSelector( }, ); -export const getWindowSeekToTime = createSelector( - [ - getWindow, - ], - (window) => { - if (!window) return undefined; - - return window.seekToTime; - }, -); - export const getWindowPausedStatus = createSelector( [ getWindow,