Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove HLS caption handling #443

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/components/MediaPlayer/MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
const [isMultiCanvased, setIsMultiCanvased] = React.useState(false);
const [lastCanvasIndex, setLastCanvasIndex] = React.useState(0);
const [isVideo, setIsVideo] = React.useState();
const [isStream, setIsStream] = React.useState();

const {
canvasIndex,
Expand Down Expand Up @@ -132,14 +131,12 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
mediaType,
canvas,
error,
isHLS
} = getMediaInfo({
manifest,
canvasIndex: canvasId,
srcIndex,
});
setIsVideo(mediaType === 'video');
setIsStream(isHLS);
manifestDispatch({ canvasTargets, type: 'canvasTargets' });
manifestDispatch({
canvasDuration: canvas.duration,
Expand Down Expand Up @@ -343,9 +340,9 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
sources: isMultiSource
? playerConfig.sources[srcIndex]
: playerConfig.sources,
// Enable native text track functionality in iPhones and iPads when not using HLS streams
// Enable native text track functionality in iPhones and iPads
html5: {
nativeTextTracks: IS_MOBILE && !isStream && !IS_ANDROID
nativeTextTracks: IS_MOBILE && !IS_ANDROID
},
// Setting this option helps to override VideoJS's default 'keydown' event handler, whenever
// the focus is on a native VideoJS control icon (e.g. play toggle).
Expand Down
56 changes: 47 additions & 9 deletions src/components/MediaPlayer/VideoJS/VideoJSPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,28 @@ function VideoJSPlayer({
playerDispatch({ isEnded: false, type: 'setIsEnded' });

let textTracks = player.textTracks();
// Filter the duplicated tracks by HLS manifest, these doesn't have a src attribute
let duplicatedTracks = textTracks.tracks_.filter(rt => rt.src === undefined);
// Remove the duplicated tracks from the captions/subtitles menu
if (tracks.length != textTracks.length && duplicatedTracks?.length > 0) {
for (let i = 0; i < duplicatedTracks.length; i++) {
player.textTracks().removeTrack(duplicatedTracks[i]);
}
/*
Filter the text track Video.js adds with an empty label and language
when nativeTextTracks are enabled for iPhones and iPads.
Related links, Video.js => https://github.com/videojs/video.js/issues/2808 and
in Apple => https://developer.apple.com/library/archive/qa/qa1801/_index.html
*/
if (IS_MOBILE && !IS_ANDROID) {
textTracks.on('addtrack', () => {
for (let i = 0; i < textTracks.length; i++) {
if (textTracks[i].language === '' && textTracks[i].label === '') {
player.textTracks().removeTrack(textTracks[i]);
/*
Turn off the consecutive `textTrack.change` event,
which turns off default captions in the controls
*/
textTracks.off('change');
}
if (i == 0) { textTracks[i].mode = 'showing'; }
}
});
}

// Turn captions on indicator via CSS on first load, when captions are ON by default
player.textTracks().tracks_?.map((t) => {
if (t.mode == 'showing') {
Expand Down Expand Up @@ -609,6 +623,30 @@ function VideoJSPlayer({
} else {
videoClass = "video-js vjs-big-play-centered";
};
const buildTrack = (t, index) => {
if (index == 0) {
return (
<track
key={t.key}
src={t.src}
kind={t.kind}
label={t.label}
srcLang={t.srclang}
default
/>
);
} else {
return (
<track
key={t.key}
src={t.src}
kind={t.kind}
label={t.label}
srcLang={t.srclang}
/>
);
}
};

return (
<React.Fragment>
Expand All @@ -623,14 +661,14 @@ function VideoJSPlayer({
onTouchEnd={mobilePlayToggle}
>
{tracks?.length > 0 && (
tracks.map(t =>
tracks.map((t, index) =>
<track
key={t.key}
src={t.src}
kind={t.kind}
label={t.label}
srcLang={t.srclang}
default
default={index === 0 ? 'true' : 'false'}
/>
)
)}
Expand Down
11 changes: 1 addition & 10 deletions src/services/iiif-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function getCanvasIndex(manifest, canvasId) {
* @param {Object} obj.manifest IIIF Manifest
* @param {Number} obj.canvasIndex Index of the current canvas in manifest
* @param {Number} obj.srcIndex Index of the resource in active canvas
* @returns {Object} { soures, tracks, targets, isMultiSource, error, canvas, mediaType, isHLs }
* @returns {Object} { soures, tracks, targets, isMultiSource, error, canvas, mediaType }
*/
export function getMediaInfo({ manifest, canvasIndex, srcIndex = 0 }) {
let canvas = [];
Expand Down Expand Up @@ -169,14 +169,6 @@ export function getMediaInfo({ manifest, canvasIndex, srcIndex = 0 }) {
// Set default src to auto
sources = setDefaultSrc(resources, isMultiSource, srcIndex);

/*
Identify the media is streaming or not by testing whether the src includes .m3u8
OR media format includes HLS mime types => application/x-mpegURL or vnd.apple.mpegURL
*/
const isHLS = sources
.map(s => (/m3u8/i).test(s.src) || (/(application\/x-mpegURL)|(vnd.apple.mpegURL)/i).test(s.type))
.every(f => f === true);

// Read supplementing resources fom annotations
const supplementingRes = readAnnotations({
manifest,
Expand Down Expand Up @@ -210,7 +202,6 @@ export function getMediaInfo({ manifest, canvasIndex, srcIndex = 0 }) {
...mediaInfo,
error: null,
mediaType,
isHLS,
};
}
} catch (error) {
Expand Down
44 changes: 0 additions & 44 deletions src/services/iiif-parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,50 +176,6 @@ describe('iiif-parser', () => {
expect(sources[2].selected).toBeTruthy();
});

describe('identifies media as stream', () => {
it('with src ending .m3u8', () => {
const { isHLS } = iiifParser.getMediaInfo({
manifest: singleSrcManifest,
canvasIndex: 1,
});
expect(isHLS).toBeTruthy();
});

it('with src media fragment with .m3u8', () => {
const { isHLS } = iiifParser.getMediaInfo({
manifest: playlistManifest,
canvasIndex: 1,
});
expect(isHLS).toBeTruthy();
});

it('with media format as vnd.apple.mpegURL', () => {
const { isHLS } = iiifParser.getMediaInfo({
manifest: singleSrcManifest,
canvasIndex: 0,
});
expect(isHLS).toBeTruthy();
});
});

describe('identifies media as non-stream', () => {
it('with src ending .mp4', () => {
const { isHLS } = iiifParser.getMediaInfo({
manifest: lunchroomManifest,
canvasIndex: 0,
});
expect(isHLS).toBeFalsy();
});

it('with media fragment with .mp4', () => {
const { isHLS } = iiifParser.getMediaInfo({
manifest: playlistManifest,
canvasIndex: 2,
});
expect(isHLS).toBeFalsy();
});
});

it("selects the first source when quality 'auto' is not present", () => {
const { sources } = iiifParser.getMediaInfo({
manifest: lunchroomManifest,
Expand Down
2 changes: 1 addition & 1 deletion src/services/utility-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ function getResourceInfo(item, motivation) {
};
if (motivation === 'supplementing') {
// Set language for captions/subtitles
s.srclang = item.getProperty('language') || 'en';
s.srclang = item.getProperty('language') || 'eng';
// Specify kind to subtitles for VTT annotations. Without this VideoJS
// resolves the kind to metadata for subtitles file, resulting in empty
// subtitles lists in iOS devices' native palyers
Expand Down