This appears to be a bug. Could you please describe what you were doing at the time or post example code if you were using a custom app. Also, what browser are you running on?
Noticed this happening on our streams as well:
This line breaks:
let ref = mediaState.segmentIterator.seek(lookupTime);
in streaming_engine.js
Dash/Widevine on Chrome/MacbookPro.
Will try to recreate on demo.
Hello @JeffrinManovaPrabahar @bcupac ,
Could you please provide us with a test manifest, so that we can work on a fix?
You can send it to [email protected] if the content is private.
Thank you!
I believe we're seeing the same exception (in shaka.media.StreamingEngine.prototype.getSegmentReferenceNeeded_).
I think in our case segmentIterator gets set to null in switchInternal_ after it checks for mediaState.stream.segmentIndex being set.
Happens on MacOS Chrome Version 84.0.4147.135 (Official Build) (64-bit). Shaka Player v3.0.4-debug.
Have you been able to reproduce from other users' data?


It is happening for clear content also(Non-DRM) in mac/chrome-85
@TheModMaker @joeyparrish @michellezhuogg any update on this? I am not able to reproduce this issue but many of our users are facing this issue.
It is a random issue, but for some users it happens frequently. We have done screen-share with one of our users and for him it is happening frequently. it happens 2-3 times in 5 min period. He is using mobile data so the internet is slow and unstable.
We are using latest code from master. This happens for many video streams. Not limited to particular video stream
@TheModMaker @michellezhuogg @joeyparrish This issue is not there in 2.5.x branch. We have taken the latest code from this branch and we have tested with our users. Users are not facing this issue in 2.5.x. But this issue happens frequently for some users in 3.0.4 version
We see that there is a bug, but we don't have a consistent way to reproduce it. This means we don't have a way to find the root cause or fix it.
I have tried analyzing the code to find the flaw in our logic, but I haven't found it that way. I've also tried playing various piece of public and private content, tried various network emulation settings in Chrome, tried playing with the resolution and caption controls, and none of that has reproduced the issue so far.
If you have any sample content you can share that will help us reproduce the issue more consistently, that would help. And if anyone else has identified the root cause, we would love to review a PR to fix it. Thanks!
@joeyparrish in our case it's intermittent. Today I was able to reproduce it ~5 times in a matter of hours, but in many (and today even most) cases the exact same actions resulted in correct behaviour. This would lead me to speculate this looks like a "race condition" or it being network/bandwidth-dependent. I may be able to arrange private access to one such manifest (can't guarantee yet), but it may still be challenging (or even impossible, e.g. if it's network-dependent) to reproduce.
That being said, here's what I was able to observe so far (not sure if it's helpful or obvious). I added a couple of log statements to switchInternal_ like this:
if (mediaState.stream.segmentIndex) {
console.log('SEGMENT ITERATOR -> OK', mediaState.stream.segmentIndex, mediaState.stream);
mediaState.segmentIterator =
mediaState.stream.segmentIndex[Symbol.iterator]();
} else {
console.log('SEGMENT ITERATOR -> NULL', mediaState.stream.segmentIndex, mediaState.stream);
mediaState.segmentIterator = null;
}
When the issue occurs, here's the output:
SEGMENT ITERATOR -> NULL null {id: 6, originalId: "3", segmentIndex: null, mimeType: "video/mp4", createSegmentIndex: ƒ, …}
However, when I expand the mediaState.stream using the little triangle on this line, the segmentIndex now shows this:
segmentIndex: shaka.media.SegmentIndex {references: Array(2610), timer_: null, numEvicted: 0}
Which, as I understsand, is the value of this object at the time of me expanding it. Which means it was null at the time of console.log, but it got set to a non-null value at some later point.
Let me know if this is at all helpful and if there's anything else you think I should investigate.
Here's some more context:
Starting attach...
Starting unload...
Starting load of https://...mpd
Found variant with audio and video content, so filtering out audio-only content.
codecs vp09-mp4a avg bandwidth 1190467
codecs avc1-mp4a avg bandwidth 1186418
codecs vp09-opus avg bandwidth 1158040
codecs avc1-opus avg bandwidth 1153991
Dropping Variant (better codec available) {id: 0, language: "und", primary: false, audio: {…}, video: {…}, …}
<26 SIMILAR LINES...>
Dropping Variant (better codec available) {id: 27, language: "und", primary: false, audio: {…}, video: {…}, …}
init: completed initial Stream setup
Calling switch_(), bandwidth=1332 kbps
switch_
SEGMENT ITERATOR -> NULL null {id: 6, originalId: "3", segmentIndex: null, mimeType: "video/mp4", createSegmentIndex: ƒ, …}
switch: switching to Stream (video:6)
switch: Stream (audio:12) already active
Calling switch_(), bandwidth=1440 kbps
switch_
SEGMENT ITERATOR -> NULL null {id: 7, originalId: "5", segmentIndex: null, mimeType: "video/mp4", createSegmentIndex: ƒ, …}
switch: switching to Stream (video:7)
switch: Stream (audio:12) already active
Assertion failed: Wrong error type!
shaka.util.FakeEvent {detail: TypeError: Cannot read property 'seek' of null
at shaka.media.StreamingEngine.getSegmentReferen…, bubbles: false, cancelable: false, defaultPrevented: false, timeStamp: 16454.674999928102, …}
@joeyparrish I am able to reproduce the issue 2 times by changing the bandwidth to fast/slow 3G(In chrome dev tools). For me it is difficult to reproduce. But some of our users frequently faces this issue.
I was unable to reproduce this when I was trying, but I managed it accidentally while working on #2670, while the player was in a background tab. I have no idea what did it. I wasn't interacting with the player at the time.
I've reproduced it several more times now with the tab in the foreground, without interacting. It seems pretty random.
There must be a race condition around createSegmentIndex() (an async operation) and the creation of the corresponding iterator (synchronous) afterward. I have some ideas I'd like to try to fix the issue, but I still can't consistently reproduce it.
It's so rare and unreliable that I won't have any way to be confident in any fix I try. Even if it's not 100% reproducible, if it were reproducing with specific steps at some measurable percentage, I could at least slowly verify my fix to a certain confidence level.
If we could find a better way to trigger the issue, I feel certain we could fix it. Does anyone have any suggestions?
I added lots of extra assertions and traces to all the code paths that might affect segmentIterator and segmentIndex and got lucky triggering the issue again. I believe I've found the cause now!
In StreamingEngine's onUpdate_, there is a possibility that mediaState.stream.segmentIndex is non-null, but mediaState.segmentIterator is still null. When this happens, segmentIterator does not get correctly created.
The mistake seems to be the coupling of segmentIndex and segmentIterator in the logic. Since segmentIndex is created asynchronously, it's always possible for that to be interrupted. Therefore we need to first check for segmentIndex, then check for an interruption if we have to create it, then separately check for segmentIterator.
As part of this, we can also clean up the logic on who is responsible for creating them and when. For example, we should reset segmentIterator to null when the stream changes, and only create it before it is used (in update_ and makeAbortDecision_).
Hi @joeyparrish, when will be this fix released?
In our next release, v3.0.5. I don't have a date set yet, but it should be soon.
Same problem on firefox
@Ballevill, the fix is already in the master and v3.0.x branches and will be in the v3.0.5 release very soon.
@joeyparrish FWIW, thanks a bunch for fixing this! I just had 2 days hunting this very issue (on 3.0.4), hehe
Most helpful comment
In StreamingEngine's
onUpdate_, there is a possibility thatmediaState.stream.segmentIndexis non-null, butmediaState.segmentIteratoris still null. When this happens,segmentIteratordoes not get correctly created.The mistake seems to be the coupling of
segmentIndexandsegmentIteratorin the logic. SincesegmentIndexis created asynchronously, it's always possible for that to be interrupted. Therefore we need to first check forsegmentIndex, then check for an interruption if we have to create it, then separately check forsegmentIterator.As part of this, we can also clean up the logic on who is responsible for creating them and when. For example, we should reset
segmentIteratorto null when the stream changes, and only create it before it is used (inupdate_andmakeAbortDecision_).