Improved reliability of captions

Addressed issue #41 by working around Safari bug where captions are not displayed if the track is added after the video has loaded (thanks to @choco for discovering this).
This commit is contained in:
amarcu5
2019-09-07 22:44:35 +01:00
parent d8b3cfdc16
commit 653433d0e2
6 changed files with 22 additions and 11 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+17 -9
View File
@@ -41,7 +41,7 @@ export const enableCaptions = function(ignoreNowPlayingCheck) {
const video = /** @type {?HTMLVideoElement} */ (getResource().videoElement(true));
if (!video) return;
showingCaptions = videoPlayingPictureInPicture(video);
prepareCaptions(video);
track = getCaptionTrack(video);
processCaptions();
};
@@ -55,27 +55,35 @@ export const shouldProcessCaptions = function() {
};
/**
* Prepares video for captions
* Gets caption track for video (creates or returns existing track as needed)
*
* @param {HTMLVideoElement} video - video element that will display captions
* @return {TextTrack}
*/
const prepareCaptions = function(video) {
const getCaptionTrack = function(video) {
// Find existing caption track
track = null;
const allTracks = video.textTracks;
for (let trackId = allTracks.length; trackId--;) {
if (allTracks[trackId].label === TRACK_ID) {
track = allTracks[trackId];
info('Existing caption track found');
break;
return allTracks[trackId];
}
}
if (track) return;
// Otherwise create new caption track
info('Caption track created');
track = video.addTextTrack('captions', TRACK_ID, 'en');
return video.addTextTrack('captions', TRACK_ID, 'en');
};
/**
* Adds caption tracks to all video elements
*/
export const addVideoCaptionTracks = function() {
const elements = document.getElementsByTagName('video');
for (let index = 0, element; element = elements[index]; index++) {
getCaptionTrack(/** @type {?HTMLVideoElement} */ (element));
}
};
/**
@@ -88,7 +96,7 @@ const pictureInPictureEventListener = function(video, isPlayingPictureInPicture)
// Toggle display of the captions and prepare video if needed
showingCaptions = isPlayingPictureInPicture;
if (showingCaptions) prepareCaptions(video);
if (showingCaptions) track = getCaptionTrack(video);
lastUnprocessedCaption = '';
processCaptions();
+4 -1
View File
@@ -3,7 +3,7 @@ import { Browser, getBrowser, getResource, setResource } from './common.js'
import { addVideoElementListeners } from './video.js'
import { resources } from './resources/index.js';
import { checkButton, addButton } from './button.js'
import { shouldProcessCaptions, enableCaptions, processCaptions } from './captions.js'
import { shouldProcessCaptions, enableCaptions, processCaptions, addVideoCaptionTracks } from './captions.js'
import { initialiseCaches } from './cache.js'
/**
@@ -17,6 +17,9 @@ const mutationObserver = function() {
// Workaround Chrome's lack of an entering Picture in Picture mode event by monitoring all video elements
if (getBrowser() == Browser.CHROME) addVideoElementListeners();
// Workaround Safari bug; captions are not displayed if the track is added after the video has loaded
if (getBrowser() == Browser.SAFARI) addVideoCaptionTracks();
// Try adding the button to the page if needed
if (checkButton()) return;
const currentResource = getResource();
+1 -1
View File
@@ -10,7 +10,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0.3</string>
<key>CFBundleVersion</key>
<string>213</string>
<string>214</string>
<key>Developer Identifier</key>
<string>BQ6Q24MF9X</string>
<key>URL</key>