-
Notifications
You must be signed in to change notification settings - Fork 35
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
feat: caption refactor + support cvaa & default audio/text tracks #118
Conversation
contains models for VTT cue and text track style settings and egine to port VTT cue model to DOM element which is a port of VTT.js project
allow application to create test style object to apply on player via API
* player handles synthetic VTT cue and displays them with a derived HTML Dom element that is created from this cue. * currently support cues from native video element which are created via the adapters. Adapters themselves parse the VTT from whatever source(VTT segmented file, VTT in header, DFXP etc) and use the native textTrack API to add them to video and sync them to timeline. html5 layer gets the cuechange event and creates a synthetic VTT cue to normalize the VTTCue and TextTrackCue models to VTTCue one(thanks Edge and IE11) so this means we don't support VTT attributes fully in those browsers yet * expose API to set text style and text cue display settings
Still needs to:
|
… into captionRefactor
use following options in descending importance to determine default text/audio language: 1. `playback.textLanguage` and `playback.audioLanguage` 2. default track from manifest
For browser that don't support native VTTCue create a VTTCue from the TextTrackCue. This meand that for Edge and IE11 we won't have full support for all VTTCue attributes.
If special config "auto" is set in config the player will try to deterimne the default language according to OS locale. language string are ISO-693-1
this can be used whenever, but will be used for supporting iOS native text tracks for example where we can't create our own div in the native player for captions display
@dan-ziv changing this to a controller is indeed the right way but it will require some changes that we will cover in other PR, that will handle adding some life cycle methods we currently lack. |
… into captionRefactor
src/engines/html5/html5.js
Outdated
* @type {Array<boolean>} | ||
* @private | ||
*/ | ||
_showTextTrackfirstTime: { [number]: boolean } = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is an object or map. no array as typed in jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, you have to clean this map in destroy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to clean it, after a text track is shown for first time it is reused, and no need for this hack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change media?
src/engines/html5/html5.js
Outdated
|
||
/** | ||
* Get currently selected text track | ||
* @returns {*} - returns the active text track element if available |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc supports {?TextTrack} http://usejsdoc.org/tags-type.html
src/engines/html5/html5.js
Outdated
const textTracks = this._el.textTracks; | ||
for (let track in textTracks) { | ||
if (textTracks.hasOwnProperty(track)) { | ||
if (textTracks[parseInt(track)] && textTracks[parseInt(track)].mode !== "disabled") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.mode !== "disabled"
could be "hidden"
also. i guess you rely on native adapter which makes the selected to 'hidden'. but track could be 'hidden' also from the browser and then is unselected.
note the the 'not showing' mode could be browser depended. e.g in safari by default is "disabled" while in chrome is "hidden".
maybe you have to change all 'hidden' to 'disabled' in advance.
also we have to change dash and hls adapters to hide track by 'disabled'. currently is 'hidden'.
best to implement hideTextTrack
in baseAdapter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to let track = textTracks[parseInt(track)]
once instead of calculate it 3 times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the mode, I added in the _setDefaultTracks
a call to hideTextTrack
so it will take care of setting them to disabled.
src/engines/html5/html5.js
Outdated
let textTrackEl: TextTrack = this._getSelectedTextTrack(); | ||
if (textTrackEl) { | ||
textTrackEl.oncuechange = null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just call this. _removeCueChangeListener()
src/engines/html5/html5.js
Outdated
@@ -194,13 +212,85 @@ export default class Html5 extends FakeEventTarget implements IEngine { | |||
|
|||
/** | |||
* Select a new text track. | |||
* @param {TextTrack} textTrack - The text track object to set. | |||
* @param {PKTextTrack} textTrack - The text track object to set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The playkit text track object to set.
src/engines/html5/html5.js
Outdated
|
||
/** | ||
* Add cuechange listener to active textTrack | ||
* @param {PKTextTrack} textTrack - player text track |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
playkit text track
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/engines/html5/html5.js
Outdated
|
||
/** | ||
* Remove cuechange listener to active textTrack | ||
* @param {PKTextTrack} textTrack - player text track |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
playkit text track
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooopps - I don't even use it so no ned to define it
@@ -440,15 +440,16 @@ export default class NativeAdapter extends BaseMediaSourceAdapter { | |||
/** | |||
* Select a text track | |||
* @function selectTextTrack | |||
* @param {TextTrack} textTrack - the track to select | |||
* @param {PKTextTrack} textTrack - the track to select |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the playkit text track to select
remove dist |
src/player.js
Outdated
* @type {string} | ||
* @const | ||
*/ | ||
const SUBTITLES_STYLE_NAME: string = 'playkit-subtitles-style'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SUBTITLES_STYLE_ID ?
src/player.js
Outdated
_playerId: string; | ||
/** | ||
* The player last updated text cues list | ||
* @type {any} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{Array<any>}
src/player.js
Outdated
@@ -227,6 +267,90 @@ export default class Player extends FakeEventTarget { | |||
} | |||
|
|||
/** | |||
* Sets style attributes for text tracks. | |||
* @param {Object} style - text styling settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{TextStyle}
src/player.js
Outdated
} | ||
|
||
if (this._config.playback.useNativeTextTrack) { | ||
sheet.insertRule(`video.${ENGINE_CLASS_NAME}::cue { ${style.toCSS()} }`, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it valid in ie11?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check if this._config.playback
and style
is exists and has toCSS()
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this._config. playback
will always exist cause we set it on constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not valid on ie11, but we use it only on iOS and the actual setup is done in application level that should check when it wants to use it and then just set useNativeTextTrack: true
, otherwise use the DIV with CSS styling
src/player.js
Outdated
* @type {any} | ||
* @private | ||
*/ | ||
_activeTextCues: Array<any> = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should clean on destroy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not only destroy, more like on change media 👍
setTextDisplaySettings(settings: Object): void { | ||
this._textDisplaySettings = settings; | ||
this._updateCueDisplaySettings(); | ||
for (let i = 0; i < this._activeTextCues.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to check _activeTextCues
existence. i know you init as [] in html5 _onCueChange
but still....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that if we init it and enforce FLOW typings then it is safe
* @type {HTMLDivElement} | ||
* @private | ||
*/ | ||
_textDisplayEl: HTMLDivElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should clean on destroy ? or can rely vid element destroy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need, we clean the content on reset and this is just the placeholder
src/player.js
Outdated
|
||
/** | ||
* handle text cue change | ||
* @param {Event} event - the cue change event payload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{FakeEvent}
src/player.js
Outdated
* @private | ||
* @returns {void} | ||
*/ | ||
_updateCueDisplaySettings(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
: void
src/player.js
Outdated
* @private | ||
* @returns {void} | ||
*/ | ||
_updateTextDisplay(cues: any): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be Array<Cue>
. also in jsdoc
Utils.Dom.addClassName(this._textDisplayEl, SUBTITLES_CLASS_NAME); | ||
Utils.Dom.appendChild(this._el, this._textDisplayEl); | ||
} | ||
processCues(window, cues, this._textDisplayEl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add try/catch around processCues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why? it's a managed method, the processCues has it's own protections internally
src/engines/html5/html5.js
Outdated
@@ -282,7 +288,7 @@ export default class Html5 extends FakeEventTarget implements IEngine { | |||
* @returns {?TextTrack} - returns the active text track element if available | |||
* @private | |||
*/ | |||
_getSelectedTextTrack(): ?TextTrack { | |||
_getSelectedTextTrackElement(): ?TextTrack { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not an element, but a DOM object.
if it was of the format then I would agree.
<video>
<track>...</track>
</video>
And even for the above, you can still get the element as an object via video.textTracks
and via DOM API selector.
textTrackEl
was a convention copy-pasted from the previous implementation so I just kept the naming.
added tests |
Description of the Changes
HTML5 layer gets the cuechange event and creates a synthetic VTT cue to normalize the VTTCue and TextTrackCue models to align with VTTCue one(thanks Edge and IE11) so this means we don't support VTT attributes fully in those browsers yet
CheckLists