Skip to content

Commit

Permalink
feat(player): simplifies text track handling
Browse files Browse the repository at this point in the history
Resolves #35 by adding the `textTrack` function to simplify
text track retrieval and selection. This function allows to:

- retrieve the currently active text track
- activate a text track based on `language` and `kind` properties

Also, when selecting a text track, if the `kind` property is not satisfied,
the first text track satisfying the `language` condition will be returned,
or `undefined` if no condition is satisfied. During this process,
all text tracks in mode `showing` are `disabled`.

```javascript
// Get the current text track
player.textTrack();

// Activate a text track
player.textTrack({language:'en', kind:'captions'})

// Disable all text tracks
player.textTrack('off')
```

- add `textTrack` function
- export the registered component directly
- add test coverage
  • Loading branch information
amtins committed Oct 23, 2023
1 parent ef81d39 commit 865be77
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 3 deletions.
62 changes: 59 additions & 3 deletions src/components/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,65 @@ class Player extends videojs.getComponent('player') {

return audioTrack;
}

/**
* A getter/setter for the media's text track.
* Activates the text track according to the language and kind properties.
* Falls back on the first text track found if the kind property is not satisfied.
* Disables all subtitle tracks that are `showing` if the `trackSelector` is truthy but does not satisfy any condition.
*
* @param {TrackSelector} [trackSelector]
*
* @example
* // Get the current text track
* player.textTrack();
*
* @example
* // Disable all text tracks has a side effect
* player.textTrack('off');
* player.textTrack({});
*
* @example
* // Activate an text track based on language and kind properties
* player.textTrack({language:'en', kind:'captions'});
*
* @example
* // Activate first text track found corresponding to language
* player.textTrack({language:'fr'});
*
* @return { import('video.js/dist/types/tracks/audio-track').default|undefined }
*/
textTrack(trackSelector) {
const textTracks = Array.from(this.player().textTracks()).filter(
(textTrack) => !['chapters', 'metadata'].includes(textTrack.kind)
);

if (!trackSelector) {
return textTracks.find((textTrack) => textTrack.mode === 'showing');
}

textTracks.forEach((textTrack) => (textTrack.mode = 'disabled'));

const { kind, language } = trackSelector;
const textTrack =
textTracks.find((textTrack) => {
if (textTrack.language === language && textTrack.kind === kind) {
textTrack.mode = 'showing';
}

return textTrack.mode === 'showing';
}) ||
textTracks.find((textTrack) => {
if (textTrack.language === language) {
textTrack.mode = 'showing';
}

return textTrack.mode === 'showing';
});

return textTrack;
}
}

// Overrides the default video.js player component
videojs.registerComponent('player', Player);

export default Player;
export default videojs.registerComponent('player', Player);
59 changes: 59 additions & 0 deletions test/components/player.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,63 @@ describe('Player', () => {
expect(player.audioTrack({ language: 'fr' })).toBeUndefined();
});
});

describe('textTrack', () => {
const player = new Player(videoEl);

player.textTracks = jest.fn(() => ({
0: {
mode: 'showing',
id: '1',
kind: 'subtitles',
label: 'English',
language: 'en',
},
1: {
mode: 'disabled',
id: '2',
kind: 'descriptions',
label: 'English AD',
language: 'en',
},
length: 2,
}));

it('should return the currently active text track if the function parameter is undefined', () => {
expect(player.textTrack()).toMatchObject({
mode: 'showing',
id: '1',
kind: 'subtitles',
label: 'English',
language: 'en',
});
});
it('should enable and return the text track according to the language and kind properties', () => {
expect(
player.textTrack({ language: 'en', kind: 'descriptions' })
).toMatchObject({
mode: 'showing',
id: '2',
kind: 'descriptions',
label: 'English AD',
language: 'en',
});
});
it('should enable and return the text track according to the language property if the kind property does not satisfy the condition', () => {
expect(
player.textTrack({ language: 'en', kind: 'invalid' })
).toMatchObject({
mode: 'showing',
id: '1',
kind: 'subtitles',
label: 'English',
language: 'en',
});
});
it('should return undefined and disable every active text track if the language and kind properties do not satisfy the condition', () => {
expect(player.textTrack({ language: 'fr' })).toBeUndefined();
expect(player.textTracks.mock.results[0].value[0].mode).toBe('disabled');
expect(player.textTracks.mock.results[0].value[1].mode).toBe('disabled');
});
});
});

0 comments on commit 865be77

Please sign in to comment.