-
Notifications
You must be signed in to change notification settings - Fork 111
fix duplicate caption processing #156
fix duplicate caption processing #156
Conversation
I would setup the |
b257de6
to
1ed612b
Compare
How's this? I added the flash stuff, but I'm not sure what I did was appropriate. There's no handler for |
Ah, my Chrome keeps "aw, snap!"-ing, so I didn't know the tests were failing. Will look into it. |
Ok, nevermind, apparently all the tests are fine.... 🤔 |
Here's where I tell you I steered you in the wrong direction because flash is special haha. Since flash is not using real MSE and instead the swf is acting like a media source, I'm not entirely sure if it is actually firing |
src/html-media-source.js
Outdated
@@ -187,6 +199,7 @@ export default class HtmlMediaSource extends videojs.EventTarget { | |||
} | |||
|
|||
this.player_.on('mediachange', this.onPlayerMediachange_); | |||
this.player_.on('seeking', this.onPlayerSeeking_); |
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 seeking
instead of seeked
?
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 if it matters, but the captions should all be reset before it starts ingesting the video. Don't know if the seeked
event will fire and complete before data is push
ed through the transmuxer.
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.
Hmmm better safe than sorry I suppose
src/html-media-source.js
Outdated
if (sourceBuffer.transmuxer_) { | ||
let range = this.player_.buffered(); | ||
let current = this.player_.currentTime(); | ||
if (current >= range.end(0) || current <= range.start(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.
You should check range.length
before attempting to call start
or end
because if the buffer is empty you'll get an error
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.
Added range.length &&
to the if statement.
5bc71e8
to
b9fe08d
Compare
src/html-media-source.js
Outdated
let range = this.player_.buffered(); | ||
let current = this.player_.currentTime(); | ||
|
||
if (current >= range.end(0) || current <= range.start(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.
Since this won't change between buffers, we should do this check first and only do the forEach
if it passes.
You'll also want to check range.length
here.
I think this comparison will also run into problems if there are gaps in the buffer. (history for context) In the past, contrib-hls had pretty complicated logic surrounding segment loading, and part of that complication was gaps and multiple time ranges after seeks. We've since updated that so contrib-hls appends segments in a sequential order and clears the entire buffer when seeking outside the buffered range. What this gave us was the ability for contrib-hls to have the assumption that there is only ever 1 time range of buffered content, and any gaps within that range are inherit to the source and not because we seeked or skipped a segment. However, buffered()
would still reflect those gaps. For example buffered could look like [0 -> 10, 11->20]
after appending the first two segments. Seeking to 13 would not reset anything from contrib-hls point of view, but range.end(0)
would be 10
so this would cause the captions to be reset.
Specifically, contrib-hls will do its seek reset if this buffered.length === 0
. You'll notice the findRange function it calls also uses a fudge factor to account for rounding of the time range values, so you should probably do something similar here as well
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.
Hmm. Think maybe contrib-hls should dispatch the actual message, then? I mean, all this other scaffolding for handling the exact same case is there...
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.
Or would that break things for native HLS?
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.
Having contrib-hls handle the message would simplify this alot. I agree we should come up with a solution that can take advantage of the code and information contrib-hls has.
Historically we've tried to keep this project as a shim for MSE so that contrib-hls would not need knowledge of whether it was working with this project or native media source. (Even though contrib-hls is always using our shim). Eventually we would like to do away with this project and pull functionality into contrib-hls so we don't have to deal with these constraints that we keep running into. However, re-examining how the two projects interact, we are already breaking that principle by calling addSeekableRange_
from contrib-hls. We also communicate mediachange
between these projects through an event on the tech that contrib-media-sources listens to. I don't think we should add new apis for contrib-hls to call (even though we are doing it once). I think the event solution is reasonable and keeps with the spirit of being a native shim. If contrib-hls was working with a native mediasource, triggering an event on the tech would not break anything as there would just be nothing listening to it.
So instead of doing the reset on seek events, lets listen for a custom event on the player's tech (I think this should stay just on the tech unlike the mediachange event that is bubbled up to the player since it's not information that the player needs to know about) and do the reset when that event is triggered. Then all that would be needed is for contrib-hls to trigger the event at the right moment
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 this is all that would need to be done from contrib-hls mjneil/videojs-contrib-hls@6cfdb6b
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 like that approach!
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 there a "global" place in media-sources where I could receive that event, or will I have to set up the listener for HTML and Flash separately?
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 I don't think so. You'd have to do them separately like it is now
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.
Ok I pushed to squarebracket/videojs-contrib-media-sources@20230fa and added your commit to contrib-hls, seems to work. If it looks good to you, I'll force push to this branch.
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.
left a couple comments on that commit otherwise 👍
src/flash-source-buffer.js
Outdated
@@ -178,6 +178,7 @@ export default class FlashSourceBuffer extends videojs.EventTarget { | |||
// On a seek we remove all text track data since flash has no concept | |||
// of a buffered-range and everything else is reset on seek | |||
this.mediaSource_.player_.on('seeked', () => { | |||
this.resetCaptionsIfAppropriate(); |
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 realized that things are reset on every seek regardless of in buffer or not when Flash is being used, so you should just be able to postMessage
here without doing any checks
d4e8e58
to
aee6ee2
Compare
Alright, changed things to the event-based method. |
can we update the |
aee6ee2
to
a324adb
Compare
Done. I renamed the callbacks as well. |
src/flash-source-buffer.js
Outdated
@@ -182,11 +182,18 @@ export default class FlashSourceBuffer extends videojs.EventTarget { | |||
removeCuesFromTrack(0, Infinity, this.inbandTextTrack_); | |||
}); | |||
|
|||
this.mediaSource_.player_.tech_.on('hls-reset', this.resetHls); |
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.
For some reason when this.resetHls
is called after hearing this event, this
within resetHls
is not being bound correctly.
if you define the function above instead of using the es6 class syntax it works
this.resetHls = () => {
this.transmuxer_.postMessage({action: 'resetCaptions'});
};
this.mediaSource_.player.tech_.on('hls-reset', .......
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.
Looks like bind
is being used in a couple other places there, maybe it's best to do that to keep the style consistent.
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.
bind would work too. You'll just have to make sure to put it in a local var and use that for both the on
and off
otherwise the references passed to on
and off
will be to different functions
let onHlsReset = this.resetHls.bind(this);
...tech_.on('hls-reset', onHlsReset);
...tech_.off('hls-reset', onHlsReset);
c3777d9
to
ffcde7c
Compare
src/flash-source-buffer.js
Outdated
}); | ||
} | ||
|
||
resetHls() { |
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.
can we update this to onHlsReset_
for naming consistency
src/html-media-source.js
Outdated
@@ -159,6 +159,14 @@ export default class HtmlMediaSource extends videojs.EventTarget { | |||
}); | |||
}; | |||
|
|||
this.onResetHls_ = () => { |
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.
can we also update this to onHlsReset_
as well
ffcde7c
to
63304e9
Compare
@mjneil I think this is how I did it, but I don't recall for sure tbh.