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

feat: caption refactor + support cvaa & default audio/text tracks #118

Merged
merged 40 commits into from
Oct 2, 2017

Conversation

OrenMe
Copy link
Contributor

@OrenMe OrenMe commented Sep 19, 2017

Description of the Changes

  • player handles synthetic VTT cue and displays them with a derived HTML Dom element that is created from this cue
  • currently player 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 align with 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

CheckLists

  • changes have been done against master branch, and PR does not conflict
  • new unit / functional tests have been added (whenever applicable)
  • test are passing in local environment
  • Travis tests are passing (or test results are not worse than on master branch :))
  • Docs have been updated

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
@OrenMe
Copy link
Contributor Author

OrenMe commented Sep 19, 2017

Still needs to:

  • handle default text tracks from manifest
  • handle auto textLanguage option from config
  • external VTT files
  • support VTT attributes from VTT file on edge and IE11
  • use default texttrack API on iOS for native playback
  • tests
  • sync with UI elements, e.g. the control bar and possibly ads - need to change the text position when they appear

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
@OrenMe
Copy link
Contributor Author

OrenMe commented Sep 27, 2017

@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.

* @type {Array<boolean>}
* @private
*/
_showTextTrackfirstTime: { [number]: boolean } = {};
Copy link
Contributor

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

Copy link
Contributor

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

Copy link
Contributor Author

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change media?


/**
* Get currently selected text track
* @returns {*} - returns the active text track element if available
Copy link
Contributor

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

const textTracks = this._el.textTracks;
for (let track in textTracks) {
if (textTracks.hasOwnProperty(track)) {
if (textTracks[parseInt(track)] && textTracks[parseInt(track)].mode !== "disabled") {
Copy link
Contributor

@yairans yairans Sep 27, 2017

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

Copy link
Contributor

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.

Copy link
Contributor Author

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.

let textTrackEl: TextTrack = this._getSelectedTextTrack();
if (textTrackEl) {
textTrackEl.oncuechange = null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just call this. _removeCueChangeListener()

@@ -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.
Copy link
Contributor

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.


/**
* Add cuechange listener to active textTrack
* @param {PKTextTrack} textTrack - player text track
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

playkit text track

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


/**
* Remove cuechange listener to active textTrack
* @param {PKTextTrack} textTrack - player text track
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

playkit text track

Copy link
Contributor Author

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
Copy link
Contributor

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

@yairans
Copy link
Contributor

yairans commented Sep 27, 2017

remove dist

src/player.js Outdated
* @type {string}
* @const
*/
const SUBTITLES_STYLE_NAME: string = 'playkit-subtitles-style';
Copy link
Contributor

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}
Copy link
Contributor

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
Copy link
Contributor

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);
Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor Author

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> = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should clean on destroy

Copy link
Contributor Author

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++) {
Copy link
Contributor

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....

Copy link
Contributor Author

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;
Copy link
Contributor

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?

Copy link
Contributor Author

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
Copy link
Contributor

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(){
Copy link
Contributor

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 {
Copy link
Contributor

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);
Copy link
Contributor

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

Copy link
Contributor Author

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

@OrenMe
Copy link
Contributor Author

OrenMe commented Sep 29, 2017

@dan-ziv @yairans please review following review fixes

@dan-ziv dan-ziv dismissed stale reviews from yairans and themself October 1, 2017 10:35

approved

@@ -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 {
Copy link
Contributor Author

@OrenMe OrenMe Oct 2, 2017

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.

@OrenMe
Copy link
Contributor Author

OrenMe commented Oct 2, 2017

added tests

@dan-ziv dan-ziv changed the title feat: caption refactor feat: caption refactor suppot cvaa & default audio/text tracks) Oct 2, 2017
@dan-ziv dan-ziv changed the title feat: caption refactor suppot cvaa & default audio/text tracks) feat: caption refactor support cvaa & default audio/text tracks Oct 2, 2017
@dan-ziv dan-ziv changed the title feat: caption refactor support cvaa & default audio/text tracks feat: caption refactor + support cvaa & default audio/text tracks Oct 2, 2017
@dan-ziv dan-ziv merged commit 187cf78 into master Oct 2, 2017
@dan-ziv dan-ziv deleted the captionRefactor branch October 2, 2017 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants