diff --git a/src/components/MediaPlayer/MediaPlayer.js b/src/components/MediaPlayer/MediaPlayer.js index a986b346..8509b146 100644 --- a/src/components/MediaPlayer/MediaPlayer.js +++ b/src/components/MediaPlayer/MediaPlayer.js @@ -210,6 +210,7 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => { poster: isVideo ? getPoster(manifest, canvasIndex) : null, controls: true, fluid: true, + language: "en", // TODO:: fill this information from props controlBar: { // Define and order control bar controls // See https://docs.videojs.com/tutorial-components.html for options of what diff --git a/src/components/MediaPlayer/MediaPlayer.test.js b/src/components/MediaPlayer/MediaPlayer.test.js index 82f92ffd..d026e702 100644 --- a/src/components/MediaPlayer/MediaPlayer.test.js +++ b/src/components/MediaPlayer/MediaPlayer.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen, waitFor } from '@testing-library/react'; +import { act, render, screen, waitFor } from '@testing-library/react'; import { withManifestAndPlayerProvider } from '../../services/testing-helpers'; import MediaPlayer from './MediaPlayer'; import audioManifest from '@TestData/transcript-canvas'; @@ -10,6 +10,16 @@ let manifestState = { playlist: { isPlaylist: false, markers: [], isEditing: false } }; describe('MediaPlayer component', () => { + let originalError; + beforeEach(() => { + originalError = console.error; + console.error = jest.fn(); + }); + + afterAll(() => { + console.error = originalError; + }); + describe('with audio manifest', () => { beforeEach(() => { const PlayerWithManifest = withManifestAndPlayerProvider(MediaPlayer, { @@ -67,7 +77,7 @@ describe('MediaPlayer component', () => { initialPlayerState: {}, enableFileDownload: true, }); - render(); + await act(async () => render()); expect(screen.queryByTestId('videojs-file-download')).toBeInTheDocument(); }); }); @@ -96,12 +106,12 @@ describe('MediaPlayer component', () => { }); describe('with multiple canvases', () => { - test('renders previous/next section buttons', () => { + test('renders previous/next section buttons', async () => { const PlayerWithManifest = withManifestAndPlayerProvider(MediaPlayer, { initialManifestState: { ...manifestState, manifest: videoManifest, canvasIndex: 0 }, initialPlayerState: {}, }); - render(); + await act(async () => render()); expect(screen.queryByTestId('videojs-next-button')).toBeInTheDocument(); expect(screen.queryByTestId('videojs-previous-button')).toBeInTheDocument(); }); @@ -126,7 +136,7 @@ describe('MediaPlayer component', () => { expect(screen.getByText('You do not have permission to playback this item.')).toBeInTheDocument(); }); - test('renders player for a accessible Canvas', () => { + test('renders player for a accessible Canvas', async () => { const PlayerWithManifest = withManifestAndPlayerProvider(MediaPlayer, { initialManifestState: { manifest: playlistManifest, @@ -135,7 +145,7 @@ describe('MediaPlayer component', () => { }, initialPlayerState: {}, }); - render(); + await act(async () => render()); expect(screen.queryByTestId('inaccessible-item')).not.toBeInTheDocument(); expect( screen.queryAllByTestId('videojs-video-element').length diff --git a/src/components/MediaPlayer/VideoJS/VideoJSPlayer.js b/src/components/MediaPlayer/VideoJS/VideoJSPlayer.js index 75d5a905..6d169e45 100644 --- a/src/components/MediaPlayer/VideoJS/VideoJSPlayer.js +++ b/src/components/MediaPlayer/VideoJS/VideoJSPlayer.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import videojs from 'video.js'; import 'videojs-hotkeys'; - import 'videojs-markers-plugin/dist/videojs-markers-plugin'; import 'videojs-markers-plugin/dist/videojs.markers.plugin.css'; @@ -26,6 +25,7 @@ import { } from '@Services/iiif-parser'; import { checkSrcRange, getMediaFragment } from '@Services/utility-helpers'; +/** VideoJS custom components */ import VideoJSProgress from './components/js/VideoJSProgress'; import VideoJSCurrentTime from './components/js/VideoJSCurrentTime'; import VideoJSFileDownload from './components/js/VideoJSFileDownload'; @@ -91,22 +91,45 @@ function VideoJSPlayer({ let currentNavItemRef = React.useRef(); currentNavItemRef.current = currentNavItem; + // Using dynamic imports to enforce code-splitting in webpack + // https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import + const loadResources = async (langKey) => { + try { + const resources = await import(`video.js/dist/lang/${langKey}.json`); + return resources; + } catch (e) { + console.error(`${langKey} is not available, defaulting to English`); + const resources = await import('video.js/dist/lang/en.json'); + return resources; + } + }; + /** * Initialize player when creating for the first time and cleanup * when unmounting after the player is being used */ - React.useEffect(() => { + React.useEffect(async () => { const options = { ...videoJSOptions, }; setCIndex(canvasIndex); + // Dynamically load the selected language from VideoJS's lang files + let selectedLang; + await loadResources(options.language) + .then((res) => { + selectedLang = JSON.stringify(res); + }); + let languageJSON = JSON.parse(selectedLang); + let newPlayer; if (playerRef.current != null) { + videojs.addLanguage(options.language, languageJSON); newPlayer = videojs(playerRef.current, options); } + /* Another way to add a component to the controlBar */ // newPlayer.getChild('controlBar').addChild('vjsYo', {});