DASH live SSAI: audio stops fetching at a programme → ad Period boundary ("advancing to next segment null") while video continues
Have you read the FAQ and checked for duplicate open issues? Yes. The closest is #8799, "Shaka Player buffers indefinitely on IMA DAI live contents", which was closed for inactivity after being reported still present on 4.16.3. In that thread a maintainer asked for manifest dumps around the segment lookup misses; this report includes them. It's separate from #10604 (same stream, different failure).
If the problem is related to FairPlay, have you read the tutorial? N/A (Widevine).
What version of Shaka Player are you using? 4.16.49 (debug build).
Can you reproduce the issue with our latest release version? Not so far. 5.2.10 ran side by side on the same stream and didn't hit it in 9 break starts, but 4.16.49 only hit it once in those 9. At that break, the 5.2.10 session also had different ad lengths, so this doesn't show a fix. If it is fixed in 5.x, a backport to 4.16 would help.
Can you reproduce the issue with the latest code from main?
Not tested.
Are you using the demo app or your own custom app?
A minimal test page: plain Shaka, player.load() of the live MPD, no app code and no custom plugins. We have also seen what looks like the same problem in our app (see below).
If custom app, can you reproduce the issue using our demo app? The stream is a customer's DRM-protected live channel, so we can't use it in the demo app or share it. A sanitised V2 log and manifests are linked below, and we're happy to run patched builds against it.
What browser and OS are you using? Chrome 152 on macOS.
For embedded devices (smart TVs, etc.), what model and firmware version are you using? N/A for this capture. In our app, we have seen video requests stop shortly after an ad Period is added on desktop Chrome, a Chromecast with Google TV and a Samsung Tizen 4.0 TV. Those logs didn't record the audio side.
What are the manifest and license server URIs? We can't share them (a customer's live stream with Widevine DRM). The structure is below.
What configuration are you using?
{
abr: { enabled: true, useNetworkInformation: false, defaultBandwidthEstimate: 2000000,
restrictions: { minHeight: 360 }, advanced: { fastHalfLife: 4, slowHalfLife: 12 } },
manifest: { defaultPresentationDelay: 30, dash: { ignoreSuggestedPresentationDelay: true } },
streaming: { bufferBehind: 10, bufferingGoal: 20, rebufferingGoal: 3, lowLatencyMode: false },
drm: { preferredKeySystems: ['com.widevine.alpha'] /* + SW_SECURE_CRYPTO robustness */ }
}The one occurrence was with this configuration. With the default configuration (DRM settings only), 5 break starts on each version passed.
What did you do?
- Played a live DASH stream with server-side ad insertion (AWS MediaTailor) on the test page.
- Waited for an ad break to start: a new ad Period is added at the live edge.
What did you expect to happen? Both audio and video continue from the programme Period into the ad Period.
What actually happened? The ad Period was added at 05:56:31.363. Both streams then fetched their last programme segment, and when those appends finished:
05:56:31.363 L New manifest 150165.931 - Infinity (Creating TSI: ad Period 150165.931_1 added)
05:56:31.541 D (audio:6) fetchAndAppend_: ... reference.startTime=150163.22 reference.endTime=150166.42
05:56:31.550 D (video:2) fetchAndAppend_: ... reference.startTime=150163.21 reference.endTime=150166.41
05:56:33.007 L Calling switch_(), bandwidth=667 kbps
05:56:33.013 D (audio:6) advancing to next segment null <- audio: no next reference
05:56:33.557 D (video:2) advancing to next segment ref(150165.93-150167.93) <- video: continues into the ad Period
05:56:34.518 D (audio:6) timeNeeded=150166.42 ... updating in 1 seconds (from here on, every second)
05:56:53.945 D Player changing buffering state to true (presentationTime 150165.61, audio bufferedAhead 0.80)
05:56:54.549 D (audio:6) update_: presentationTime=150166.004667 bufferedAhead=0.405 updating in 1 seconds
... identical line every second until the test page reloaded at ~05:57:10 ...- Audio: it never fetched the ad Period's first audio segment (150165.931–150167.979), even though that segment covers
timeNeeded(150166.42). - Video: it fetched the ad segments, met its buffering goal (21 s ahead) and then made no further requests.
- Result: playback stalled at 150166.00, where the audio buffer ended, with
readyState4 and no error. Aplayer.load()of the same URI recovered it at once. - Buffered at the stall: audio 150133.6–150166.4, video 150155.2–150187.0.
The Period boundary (update of 05:56:55; times in seconds, computed from @start, PTO and S@t):
Period 149849.610 (programme, start 149849.610)
video ... 150160.011-150163.211, 150163.211-150166.411 (3.2 s segments)
audio ... 150160.000-150163.200, 150163.200-150166.400 (es main / en)
Period 150165.931_1 (ad, start 150165.931)
video 150165.931-150167.931, 150167.931-150169.931, ... (2.0 s segments)
audio 150165.931-150167.979, 150167.979-150169.984, ... (2.05 s segments, es main / en)
Period 150165.931_2 (ad, start 150180.964) ...
Period 150165.931 (filler, start 150195.998) ...The overlap alone doesn't trigger it. The programme's last segment runs past the ad Period's start at most break starts, and those passed:
| Break start (UTC) | Programme's last segment past the ad start | 4.16.49 | 5.2.10 |
|---|---|---|---|
| 05:19 | −0.33 s (a gap, which Shaka jumped) | ok | ok |
| 05:49 | +1.08 s | ok | ok |
| 05:56 | +0.47 s | audio stopped | ok (different ad lengths in its session) |
| 06:35, 06:58, 07:23, 07:30, 07:45 (default config) | 06:35: +1.08 s; others not measured | ok | ok |
Because of that, and because a switch_() ran 6 ms before audio came up empty, this looks timing-dependent rather than purely structural.
Attachments (secret gist; each file starts with an index; URLs, key IDs, PSSH and SCTE-35 data redacted): https://gist.github.com/indieboyalex/a3e72c271033d65bf9368e3f695ddd2c
shaka-issue-B-logs.txt: the V2 log (05:55:50–05:57:11) and the test page's event log.shaka-issue-B-manifests.txt: the manifests before the ad Period was added, then after each of the next three updates.
Other context
- MPD:
type="dynamic",timeShiftBufferDepth="PT180S",minimumUpdatePeriod="PT6S",SegmentTemplate+SegmentTimelinewith$Number$. - Programme Periods: CENC-encrypted, 2 video AdaptationSets, 2 audio (es, en), 1 text (wvtt), 3.2 s segments.
- Ad Periods: clear, 1 video AdaptationSet and 1 audio AdaptationSet, 2.0 s video and 2.05 s audio segments.
- Workaround we ship: an app-side watchdog reloads when playback is buffering and no video segment has been requested for 10 s. That catches this case, because video stops requesting once its buffer is full.
Source: shaka-project/shaka-player