diff --git a/src/components/VideoViewer.js b/src/components/VideoViewer.js index 3e72dbcc28217cd1351499b50e7cd09edf965506..2eec0d0ab30fb358d757b60d15d916d5e3a892f7 100644 --- a/src/components/VideoViewer.js +++ b/src/components/VideoViewer.js @@ -6,8 +6,7 @@ export class VideoViewer extends Component { /* eslint-disable jsx-a11y/media-has-caption */ /** */ render() { - const { classes, videoResources } = this.props; - + const { captions, classes, videoResources } = this.props; return ( <div className={classes.container}> <video controls className={classes.video}> @@ -16,6 +15,11 @@ export class VideoViewer extends Component { <source src={video.id} type={video.getFormat()} /> </Fragment> ))} + {captions.map(caption => ( + <Fragment key={caption.id}> + <track src={caption.id} label={caption.getLabel()} srcLang={caption.getProperty('language')} /> + </Fragment> + ))} </video> </div> ); @@ -24,10 +28,12 @@ export class VideoViewer extends Component { } VideoViewer.propTypes = { + captions: PropTypes.arrayOf(PropTypes.object), classes: PropTypes.objectOf(PropTypes.string).isRequired, videoResources: PropTypes.arrayOf(PropTypes.object), }; VideoViewer.defaultProps = { + captions: [], videoResources: [], }; diff --git a/src/containers/VideoViewer.js b/src/containers/VideoViewer.js index 97f7620362b99368aeea17222afb3dba83437873..f9480ac9b0a0c80a99cf73f2f42a416f7cbcedea 100644 --- a/src/containers/VideoViewer.js +++ b/src/containers/VideoViewer.js @@ -4,11 +4,12 @@ import { withTranslation } from 'react-i18next'; import { withStyles } from '@material-ui/core'; import { withPlugins } from '../extend/withPlugins'; import { VideoViewer } from '../components/VideoViewer'; -import { getVisibleCanvasVideoResources } from '../state/selectors'; +import { getVisibleCanvasCaptions, getVisibleCanvasVideoResources } from '../state/selectors'; /** */ const mapStateToProps = (state, { windowId }) => ( { + captions: getVisibleCanvasCaptions(state, { windowId }) || [], videoResources: getVisibleCanvasVideoResources(state, { windowId }) || [], } ); diff --git a/src/lib/MiradorCanvas.js b/src/lib/MiradorCanvas.js index ebd45f2f5d81cf9b9ada0f663075f23404a765d9..3c490aed07dc85da4174ce4609c205823bd2a39e 100644 --- a/src/lib/MiradorCanvas.js +++ b/src/lib/MiradorCanvas.js @@ -99,6 +99,15 @@ export default class MiradorCanvas { return flatten(resources.filter((resource) => resource.getProperty('type') === 'Sound')); } + /** */ + get vttContent() { + const resources = flattenDeep([ + this.canvas.getContent().map(i => i.getBody()), + ]); + + return flatten(resources.filter((resource) => resource.getProperty('format') === 'text/vtt')); + } + /** */ get resourceAnnotations() { return flattenDeep([ diff --git a/src/state/selectors/canvases.js b/src/state/selectors/canvases.js index 71b3e274e370b82bf10b81ea86e043f4bddf2a85..a6408805608c234c2a1cc556e59d744e2fbf5808 100644 --- a/src/state/selectors/canvases.js +++ b/src/state/selectors/canvases.js @@ -192,6 +192,14 @@ export const getVisibleCanvasVideoResources = createSelector( .map(canvas => new MiradorCanvas(canvas).videoResources)), ); +export const getVisibleCanvasCaptions = createSelector( + [ + getVisibleCanvases, + ], + canvases => flatten(canvases + .map(canvas => new MiradorCanvas(canvas).vttContent)), +); + export const getVisibleCanvasAudioResources = createSelector( [ getVisibleCanvases,