dash.js
dash.js copied to clipboard
Player re-requested the latest segment when changing bitrate
I'm not sure if it is a bug or not, but I guess it's worth noticing.
Environment
- [x] The MPD passes the DASH-IF Conformance Tool on https://conformance.dashif.org/
- [x] The stream has correct Access-Control-Allow-Origin headers (CORS)
- [x] There are no network errors such as 404s in the browser console when trying to play the stream
- [x] The issue observed is not mentioned on https://github.com/Dash-Industry-Forum/dash.js/wiki/FAQ
- [x] The issue occurs in the latest reference client on http://reference.dashif.org/dash.js/ and not just on my page
- Link to playable MPD file: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd
- Dash.js version: 4.x.x
- Browser name/version: Chrome 94.0.4606.81
- OS name/version: Ubuntu 20.04 LTS
Steps to reproduce
- Set
fastSwitchingEnabled
tofalse
, if necessary. - Load the MPD file and play the video
Observed behavior
Player re-requested the latest segment when changing bitrate
Console output
[673403][MediaPlayer] Streaming Initialized
[673405][MediaPlayer] Playback Initialized
[673452][DashParser] Parsing complete: ( xml2json: 7.50ms, objectiron: 0.400ms, total: 0.00790s)
[673453][StreamController] Manifest updated... updating data system wide.
[673454][ManifestUpdater] Manifest has been refreshed at Wed Oct 20 2021 14:39:13 GMT+0900 (Japan Standard Time)[1634708353.582]
[673457][StreamController] Switch to stream defaultId_0. Seektime is 0, current playback time is null. Seamless period switch is set to false
[673461][MediaSourceController] Set MediaSource duration:634.566
[673465][Stream] No text data.
[673465][Stream] No muxed data.
[673465][Stream] No image data.
[673466][AbrController] Stream ID: defaultId_0 [video] switch from 0 to 2/9 (buffer: 0) .
[673488][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_480x270_600k/bbb_30fps_480x270_600k_0.m4v
[673489][ScheduleController][video] [video] lastInitializedRepresentationInfo changed to 2
[673489][PlaybackController] Native video element event: play
[673490][PlaybackController] Native video element event: waiting
[673490][ScheduleController][video] Top quality video index has changed from NaN to 9
[673493][StreamProcessor][audio] OnFragmentLoadingCompleted for stream id defaultId_0 and media type audio - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_a64k/bbb_a64k_0.m4a
[673494][ScheduleController][audio] [audio] lastInitializedRepresentationInfo changed to 0
[673495][PlaybackController] Native video element event: loadedmetadata
[673495][ScheduleController][audio] Top quality audio index has changed from NaN to 0
[673505][StreamProcessor][audio] OnFragmentLoadingCompleted for stream id defaultId_0 and media type audio - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_a64k/bbb_a64k_1.m4a
**[673517][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_480x270_600k/bbb_30fps_480x270_600k_1.m4v**
[673520][AbrController] Stream ID: defaultId_0 [video] switch from 2 to 9/9 (buffer: 4) {"throughput":130048.2,"latency":12}
[673524][PlaybackController] Native video element event: loadeddata
[673525][PlaybackController] Native video element event: playing
[673534][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_3840x2160_12000k/bbb_30fps_3840x2160_12000k_0.m4v
[673534][ScheduleController][video] [video] lastInitializedRepresentationInfo changed to 9
**[673576][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_3840x2160_12000k/bbb_30fps_3840x2160_12000k_1.m4v**
[673667][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_3840x2160_12000k/bbb_30fps_3840x2160_12000k_2.m4v
[673761][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_3840x2160_12000k/bbb_30fps_3840x2160_12000k_3.m4v
[673836][StreamProcessor][video] OnFragmentLoadingCompleted for stream id defaultId_0 and media type video - Url: https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps_3840x2160_12000k/bbb_30fps_3840x2160_12000k_4.m4v
Expected behavior
Perhaps it is better that, unless fastSwitchingEnabled=true
, the player should respect whatever downloaded bitrate of the segments.
It turns out that the segment is always replaced whenever the player changes the bitrate. Assume that the latest downloaded segment is S(i), if the player decides a bitrate change, it downloads S(i) again with the newly decided bitrate.
So I guess this definitely is a bug. It happens with dash.js 4.x.x.
I think the problem here is related to small differences in the segment duration. As an example:
- Segment duration according to MPD is 4 seconds
- When checking the buffer, the segments are not exactly 4 seconds. As an example, the buffered range after 19 segments is 0 - 79.999
- When switching quality we check the buffer and then choose the appropriate segment to download. In this example we reload segment 19 because 79.999 is part of this segment.
I don't think we can simply increase the last index by one. This only works if all Representations have the same segment duration.
Hi, thank you for your suggestions on this issue! I have the same problem which is when I use my own custom ABR rule and the bitrate of video chunk is often changed, the player will download the chunk has been download before. For example, the last chunk's index downloaded by the player is 6 and the player will not download 7 next time but repeatedly download 6 many times and even download 2/3/4.... This problem has bothered me for a long time. I'have tried your method in 754b6be, I remove the code from line 1106 to 1109 in src/streaming/StreamProcessor.js but it doesn't seem to work. I don't know what to do, do you have any solution?
@ZERO-cong This sounds like a configuration issue in your case. Please check fastSwitchEnabled
in your settings. If you set fastSwitchEnabled
to true then:
When enabled, after an ABR up-switch in quality, instead of requesting and appending the next fragment at the end of the current buffer range it is requested and appended closer to the current time.
If you want to avoid this set fastSwitchEnabled
to false
Added an example to nightly: https://reference.dashif.org/dash.js/nightly/samples/abr/fastswitch.html
@chanh1964 Two things we might try here to improve the current behavior:
- Instead of using the buffered range of the MSE we can use the buffered range according to the MPD. That should avoid rounding errors as described before
- Do not use
setExplicitBufferingTime
in case the segments of the new Representation have the same duration as the one from the previous Representation. This is harder to check for SegmentTimeline.
@ZERO-cong This sounds like a configuration issue in your case. Please check
fastSwitchEnabled
in your settings. If you setfastSwitchEnabled
to true then:
When enabled, after an ABR up-switch in quality, instead of requesting and appending the next fragment at the end of the current buffer range it is requested and appended closer to the current time.
If you want to avoid this set
fastSwitchEnabled
tofalse
Thank you for your advice. I implement my ABR rule in dash-if-reference-player and no matter if I set fastSwitchEnabled to false in src\core\Settings.js or uncheck the fast switching ABR option in samples/dash-if-reference-player/index.html, the player still download chunks repeatedly. I have tried many times, but it dosen't seem to work. Only when the bit rate is constant,the player will downloads the first chunk twice firstly and then downloads the other chunks one by one.
@ZERO-cong Does this happen with the default ABR algorithm as well or only with the custom one? Also do you see this behavior with different content?
@ZERO-cong Does this happen with the default ABR algorithm as well or only with the custom one? Also do you see this behavior with different content?
I think it happen only with my custom ABR rule because I checked the "Use Custom ABR Rules" option in in samples/dash-if-reference-player/index.html and I checked the output of the browser console(google chrome) and found that the player did call my ABR before downloading each chunk. I tried two different contents which is https://dash.akamaized.net/envivio/EnvivioDash3/manifest-video-only.mpd and https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd but the result is the same
If you can share your code we might be able to take a look
If you can share your code we might be able to take a look
I have sent the code to your email, please check it.
I had the same problem (apparently only on chromium based browsers, firefox was fine) and fixed it with merging https://github.com/Dash-Industry-Forum/dash.js/pull/3797.
hi @dsilhavy when will this issue be addressed? It blocks my project. I test the solution in #3797 and it works.
What exactly is blocked by that? I saw some problems with the PR when requests are canceled. We might be able to include a modified version of the PR in 4.7.0
What exactly is blocked by that?
When the custom ABR algorithm (rewrite from dash.js/latest/samples/abr/custom-abr-rules.html) change the bitrate, the latest downloaded chunk will be downloaded again with the new bitrate. But we hope that the new bitrate only be used to download future chunks. I try to set 'fastSwitchingEnabled' to false, but it failed. The solution in #3797 seems to work, but i am not sure if it's correct.
I saw some problems with the PR when requests are canceled. We might be able to include a modified version of the PR in 4.7.0
It would be so great if we can include that fix in the new version! Hope that.
This is fixed in #4144, please comment if you see any more issues