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

Add option to override native audio and video to html5 tech #5074

Merged
merged 17 commits into from
Apr 19, 2018

Conversation

OshinKaramian
Copy link
Contributor

@OshinKaramian OshinKaramian commented Apr 4, 2018

Description

Adding an option to override native audio/video tracks. This is being added to ease enabling and disabling it within https://github.com/videojs/http-streaming. This is partly to make enabling/disabling native playback easier when integrating videojs/http-streaming into this project.

I'm in the process of adding tests. I'd like eyes on this while I'm doing that to ensure that the implementation makes sense/if I'm missing anything that might break playback that I'm unaware of.

Specific Changes proposed

Adds 2 flags on the Html5 tech, overrideNativeAudioTracks and overrideNativeVideoTracks that can be set at any time. The change will take effect any time the source is set.

One question I'm unclear on... what should the version compatibility be with video.js with this change? I can modify things to be backwards compatible (checking to see if the APIs exist and handling things one way or another). Do we care about this? Or are we okay removing this (since leaving it in for backwards compatibility purposes would add a little bit of tech debt).

Requirements Checklist

  • Feature implemented / Bug fixed
  • If necessary, more likely in a feature request than a bug fix
    • Change has been verified in an actual browser (Verified in Edge with VHS)
    • Unit Tests updated or fixed
    • Docs/guides updated
    • Example created (starter template on JSBin)
  • Reviewed by Two Core Contributors

@@ -200,6 +200,14 @@ class Html5 extends Tech {
});
}

overrideNativeAudioTracks(override) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs a jsDoc explaining the intent of these functions and how it will take affect on source change

@forbesjo
Copy link
Contributor

forbesjo commented Apr 9, 2018

We should make sure these options are compatible with the player options https://github.com/videojs/video.js/blob/master/docs/guides/options.md#html5

Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

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

not a huge fan of adding a bunch of new flags, also, have some follow up questions about this.

@@ -605,6 +639,9 @@ class Html5 extends Tech {
* @deprecated Since version 5.
*/
src(src) {
this.forceNativeAudioOverride_ = this.forceNativeAudioOverride;
Copy link
Member

Choose a reason for hiding this comment

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

why the two separate flags?

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 seemed more flexible to have two flags over one flag to rule them all. I can merge them together if that's preferred.

};

listeners.addtrack = (e) => {
if (this[`forceNative${props.capitalName}Override_`] && elTracks.addTrack) {
Copy link
Member

Choose a reason for hiding this comment

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

why would elTracks not have an addTrack 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.

I'm not sure, it seemed safer to check to see if a method existed on something before using it.

@gkatsev
Copy link
Member

gkatsev commented Apr 9, 2018

So, the idea here is that VHS would call overrideNativeVideoTracks and overrideNativeVideoTracks with true to tell the the tech not to use native stuff?
If I'm remembering proxyNativeTracks_ correctly, would the best solution be to just remove the listeners when we disable native track support? Though, that may require a larger refactor.

Also, the override methods should probably be added to tech.js as empty methods.


listeners.removetrack = (e) => {
if (this[`forceNative${props.capitalName}Override_`] && elTracks.addTrack) {
elTracks.removeTrack(e.track);
Copy link
Member

Choose a reason for hiding this comment

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

so, I think we don't want to do this part of the if statement for addTrack and removeTrack, since the event comes from the native elTracks object already.
I think best case scenario is that we should be removing the listeners when we disable native support.

* otherwise native video will potentially be used.
*/
overrideNativeAudioTracks(override) {
this.forceNativeAudioOverride = override;
Copy link
Member

Choose a reason for hiding this comment

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

should we just override featuresNativeAudioTracks and featuresNativeVideoTracks? While a lot of the docs language around it says it's around "support" it also means whether the tech will be using that feature or not.

Copy link
Member

Choose a reason for hiding this comment

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

we may also need to do something like call proxyNativeTracks_ after the fact if this is called with false so that that process kicks in, especially if we originally start with them disabled.

@OshinKaramian
Copy link
Contributor Author

Unfortunately I can't comment on single comments, so re: removing listeners:

I explored this initially but had also determined it would be a pretty large refactor, I was attempting to go in with less work/more of a scalpel. I can go down this route, but I have a feeling this is going to be a bit more work to ensure things do not break.

Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

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

Thanks, I think this is better reflects what should happen.

@@ -217,22 +251,26 @@ class Html5 extends Tech {
!elTracks.addEventListener) {
return;
}
const listeners = {
Copy link
Member

Choose a reason for hiding this comment

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

would be good to revert this object's change to make the PR more streamlined.

@@ -613,6 +661,10 @@ class Html5 extends Tech {
this.setSrc(src);
}

setSrc(src) {
Copy link
Member

Choose a reason for hiding this comment

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

this shouldn't be necessary

this.trackListeners[props.capitalName] = [];
}

this.trackListeners[props.capitalName].push({ eventName, listener });
Copy link
Member

Choose a reason for hiding this comment

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

what about instead of making an array of stuff, do something like the following outside of this Object.keys().forEach:

this[props.getterName + 'Listeners_'] = listeners;

then to remove these, outside of this method we can do something like:

Object.keys(this.audioTracksListeners_).forEach((eventName) => {
  elTracks.removeEventListener(eventName, this.audioTracksListeners_[eventName]
});
Object.keys(this.videoTracksListeners_).forEach((eventName) => {
  elTracks.removeEventListener(eventName, this.videoTracksListeners_[eventName]
});

* @param {Boolean} override - If set to true native video will be overridden,
* otherwise native video will potentially be used.
*/
overrideNativeTracks(override) {
Copy link
Member

Choose a reason for hiding this comment

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

might be good to make this a no-op if we aren't changing the override.

this.trackListeners.Video = [];
this.trackListeners.Audio = [];

this.proxyNativeTracks_();
Copy link
Member

Choose a reason for hiding this comment

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

so basically, everything above will remove listeners and then we call proxyNativeTracks_ so that if we turn native back on it'll run but if we turned it off, proxyNativeTracks_ will exit early and not run?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds right to me.

* Attempt to force override of native video tracks.
*
* @param {Boolean} override - If set to true native video will be overridden,
* otherwise native video will potentially be used.
Copy link
Member

Choose a reason for hiding this comment

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

would be good to update this to mention that this is just for audio and video tracks

* @param {Boolean} override - If set to true native video will be overridden,
* otherwise native video will potentially be used.
*/
overrideNativeTracks(override) {
Copy link
Member

Choose a reason for hiding this comment

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

we should add either an empty method or a default implementation in tech.js for this.

@@ -260,6 +301,9 @@ class Html5 extends Tech {
const listener = listeners[eventName];

elTracks.addEventListener(eventName, listener);

this[props.getterName + 'Listeners_'] = listeners;
Copy link
Member

Choose a reason for hiding this comment

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

this can move outside of the forEach (line 300).

*/
overrideNativeTracks(override) {
// If there is no behavioral change don't add/remove listeners
if (override === this.override_) {
Copy link
Member

Choose a reason for hiding this comment

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

could we compare this against the values of featuresNativeVideoTracks and featuresNativeAudioTracks instead? that way we don't have another flag to worry about.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given a brief chat with @gkatsev I'll set this to check against featuresNativeVideoTracks && featuresNativeAudioTracks.

*/
overrideNativeTracks(override) {
// If there is no behavioral change don't add/remove listeners
if (override !== (this.featuresNativeAudioTracks && this.featuresNativeAudioTracks)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

copy/paste

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That took me a minute to spot, good 👀 s

this.featuresNativeVideoTracks = !override;
this.featuresNativeAudioTracks = !override;

this.audioTracksListeners_ = [];
Copy link
Member

Choose a reason for hiding this comment

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

should be set to null probably.

@@ -200,6 +200,43 @@ class Html5 extends Tech {
});
}

/**
* Attempt to force override of native audiio/video tracks.
Copy link
Contributor

Choose a reason for hiding this comment

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

audiio -> audio

*/
overrideNativeTracks(override) {
// If there is no behavioral change don't add/remove listeners
if (override !== (this.featuresNativeAudioTracks && this.featuresNativeVideoTracks)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

should audio and video tracks be overridden in a separate check?

Copy link
Member

Choose a reason for hiding this comment

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

at this time, we're assuming they'll always match, we can always change it later if necessary.

@gkatsev gkatsev added the needs: LGTM Needs one or more additional approvals label Apr 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants