-
Notifications
You must be signed in to change notification settings - Fork 793
MediaGroups: various bug fixes and refactor #1243
Conversation
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.
Still have to look at the tests, but wanted to submit an initial review. The refactor looks much cleaner and more straightforward than the old code 👍
src/master-playlist-controller.js
Outdated
@@ -381,14 +349,25 @@ export class MasterPlaylistController extends videojs.EventTarget { | |||
this.mainSegmentLoader_.load(); | |||
} | |||
|
|||
this.fillAudioTracks_(); | |||
this.setupAudio(); | |||
const mediaGroupSettings = { |
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.
Since it's only used in one place, probably can get rid of the var
src/master-playlist-controller.js
Outdated
this.audioSegmentLoader_.load(); | ||
} | ||
if (this.subtitlePlaylistLoader_) { |
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 this load no longer necessary?
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'm not sure what you are asking. load
is still called on the subtitleSegmentLoader_
it's just that the check for the playlist loader was changed to a different reference
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 there is confusion because git diff is matching the load call with one much lower from another function that was removed? (line 1159 for this file, line 636 in the new file)?
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.
Yup, it was the diff 👍
src/media-groups.js
Outdated
}; | ||
|
||
/** | ||
* Start loading for provided segment loader and playlist loader |
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.
s/for//
src/media-groups.js
Outdated
if (!masterGroups[type] || | ||
Object.keys(masterGroups[type]).length === 0 || | ||
mode !== 'html5') { | ||
masterGroups[type] = { main: { default: { defualt: true } } }; |
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.
default
src/media-groups.js
Outdated
AUDIO: (type, settings) => () => { | ||
const { mediaGroups: { [type]: { tracks } } } = settings; | ||
|
||
for (let id in tracks) { |
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.
Preference, but this can probably be return tracks.filter((track) => track.enabled)[0] || 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.
Object :/
src/media-groups.js
Outdated
}; | ||
|
||
/** | ||
* Returns a function used to get the active group of type provided |
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 provided type
src/media-groups.js
Outdated
* Object containing required information for media groups | ||
* @return {Function} | ||
* Function that returns the active media group for the provided type. Takes an | ||
* optional paramter {TextTrack} track. If no track is provided, a list of all |
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.
parameter
src/media-groups.js
Outdated
return null; | ||
} | ||
|
||
let result = 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.
Maybe this should be called variants
?
src/media-groups.js
Outdated
return null; | ||
} | ||
|
||
return result.reduce((final, props) => props.id === track.id ? props : final, 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.
Preference, but might be clearer as result.filter((props) => props.id === track.id)[0] || null
src/media-groups.js
Outdated
} = settings; | ||
|
||
// setup active group and track getters and change event handlers | ||
|
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.
Extra space?
@@ -573,8 +577,8 @@ QUnit.test('updates the enabled track when switching audio groups', function(ass | |||
'0.ts\n' + | |||
'#EXT-X-ENDLIST\n'); | |||
|
|||
assert.ok(mpc.activeAudioGroup().filter((track) => track.enabled)[0], | |||
'enabled a track in the new audio group'); | |||
assert.notOk(mpc.mediaTypes_.AUDIO.activePlaylistLoader, |
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.
Shouldn't this still have an activePlaylistLoader?
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 is switching from unmuxed to muxed audio. When we are in the muxed audio case, there is no active audio playlist loader because the audio content is coming from the video stream
@@ -863,40 +867,6 @@ function(assert) { | |||
assert.equal(this.player.tech_.hls.stats.bandwidth, 1, 'bandwidth we set above'); | |||
}); | |||
|
|||
QUnit.test('blacklists the current playlist when audio changes in Firefox 48 & below', |
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.
Are we foregoing this?
'no active subtitle group'); | ||
|
||
// media | ||
this.standardXHRResponse(this.requests.shift()); | ||
|
||
assert.ok(masterPlaylistController.activeSubtitleGroup_(), 'active subtitle group'); | ||
assert.ok(masterPlaylistController.mediaTypes_.SUBTITLES.activeGroup(), |
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.
Does this test make sense in this file?
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 left these tests in here as integration tests. I'm in favor of (re?)moving them if you think they would be better placed in the media-groups.test.js or if they are already covered by another test
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'm in favor of either of those, since this test won't directly touch the segment loader.
@@ -2296,7 +2272,7 @@ QUnit.test('can get active subtitle track', function(assert) { | |||
|
|||
const masterPlaylistController = this.player.tech_.hls.masterPlaylistController_; | |||
|
|||
assert.notOk(masterPlaylistController.activeSubtitleTrack_(), | |||
assert.notOk(masterPlaylistController.mediaTypes_.SUBTITLES.activeTrack(), |
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.
Does this test belong in this file?
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 left these tests in here as integration tests. I'm in favor of (re?)moving them if you think they would be better placed in the media-groups.test.js or if they are already covered by another test
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.
Any of those options sound good 👍
test/media-groups.test.js
Outdated
const result = MediaGroups.createMediaTypes(); | ||
|
||
assert.ok(result.AUDIO, 'created AUDIO media group object'); | ||
assert.equal(JSON.stringify(result.AUDIO.groups), '{}', |
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.
Will deep equal not work for empty objects?
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 might, I didn't think to try that for some reason. I was trying strictEqual
but that was not working
edit: it does :)
test/media-groups.test.js
Outdated
assert.equal(mainSegmentLoaderResetCalls, 1, | ||
'no main reset changing to group with playlist loader'); | ||
assert.equal(segmentLoaderResetCalls, 0, | ||
'no reset when active group hasnt changed'); |
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.
Nice try, but we need the \'
test/media-groups.test.js
Outdated
onError(); | ||
|
||
assert.equal(blacklistCurrentPlaylistCalls, 0, 'did not blacklist current playlist'); | ||
assert.equal(onTrackChangedCalls, 1, 'called onTrackChanged after chaging to default'); |
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.
changing
this.env.log.warn.callCount = 0; | ||
}); | ||
|
||
QUnit.test('setupListeners adds correct playlist loader listeners', function(assert) { |
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'm surprised this test passes
test/media-groups.test.js
Outdated
{ main: { default: { default: true } } }, 'forced default audio group'); | ||
assert.deepEqual(this.mediaTypes[type].groups, | ||
{ main: [ { id: 'default', playlistLoader: null, default: true } ] }, | ||
'creates group properites and no playlist loader'); |
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.
properties
test/media-groups.test.js
Outdated
assert.ok(this.mediaTypes[type].tracks.fr, 'created text track'); | ||
}); | ||
|
||
QUnit.test('initialize closed-captions correctly generates tracks and NO laoders', |
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.
loaders
Description
This PR is a WIP. Tests still need to be written.
There are some issues with the way we currently handle media groups. A big issue is that when switching to a new track, the
PlaylistLoader
is disposed of and a fresh one is created. The problem there is that thePlaylistLoader
also holds onto the playlist object reference. When we dispose of the loader, we lose any sync information we have learned about that stream, so returning to it is basically starting fresh.Alternate audio was also using incorrect sync information causing delayed switches, and sometimes desync of audio and video.
This also removes the Firefox 48 check for for supporting a change in audio info
Specific Changes proposed
MasterPlaylistController
and into its own module.