Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duration is occasionally showing as double when upgrading from 1.2.0 to 1.2.1 #6191

Closed
5 tasks done
byumark opened this issue Feb 6, 2024 · 18 comments
Closed
5 tasks done
Labels
Bug Regression A bug introduced in a recent release Stream Issue
Milestone

Comments

@byumark
Copy link

byumark commented Feb 6, 2024

What version of Hls.js are you using?

1.2.1

What browser (including version) are you using?

Multiple

What OS (including version) are you using?

Multiple

Test stream

No response

Configuration

{ autoStartLoad: false }

Additional player setup steps

No response

Checklist

Steps to reproduce

  1. We have been unable to reproduce this issue on our end, but some of our users have experienced it
  2. The user plays a video

Expected behaviour

The duration on the video player shows accurately and the video plays correctly

What actually happened?

The duration shows about double the actual duration and when the player gets to the end of the actual duration (middle of the doubled duration), then it just starts to buffer. This issue doesn't affect every video for this subset of users.

This does not seem to occur in hls.js v1.2.0 and appears to have regressed in v1.2.1. @robwalch has a hunch that it is related to #4849

Console output

Unable to reproduce

Chrome media internals output

No response

@byumark byumark added Bug Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Feb 6, 2024
@robwalch robwalch added Need sample stream and removed Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Feb 6, 2024
@robwalch
Copy link
Collaborator

robwalch commented Feb 6, 2024

@nklhtv have you ever encountered this issue?

I suspect this issue is related to media where duration is only available in segment index boxes (sidx and no trun or missing tfhd sample duration). The segment index boxes either have overlapping sub-segments (earliest presentation time + duration), or the HLS playlist segments reference those sub-segments by byte-range and accounting for all sub-segment durations exceeds the byte-range addressed duration.

@robwalch
Copy link
Collaborator

robwalch commented Feb 6, 2024

I don't plan to reverse @nklhtv's change, but may put some guard rails on the segment duration hls.js is willing to accept from fmp4 parsing when compared to the playlist time. Even if we address the missing earliestPresentationTime parsing and identify overlap, from what I can tell total sidx duration will be the duration of the mp4 file which is not necessarily the segments duration with byte-range addressed segemnts.

@robwalch robwalch added this to the 1.5.4 milestone Feb 6, 2024
@robwalch robwalch added the Regression A bug introduced in a recent release label Feb 7, 2024
robwalch added a commit that referenced this issue Feb 7, 2024
robwalch added a commit that referenced this issue Feb 7, 2024
robwalch added a commit that referenced this issue Feb 7, 2024
* patch/v1.5.x:
  Account for overlapping sidx subsegment durations by parsing earlierstPresentationTime Fixes #6191
  Fix regression that removed (unofficial) support for `startLevel` above max level index Fixes #6172
  Use main playlist details to determine start position of audio and subtitle streaming controllers Fixes #6126
  Fix regression in hls.light.js selection (#6155)
  Use average for level sorting and abandon rules check (#6135)
@robwalch robwalch modified the milestones: 1.5.4, 1.5.6 Feb 17, 2024
@robwalch robwalch reopened this Feb 17, 2024
@robwalch robwalch mentioned this issue Feb 17, 2024
2 tasks
eowino added a commit to DiceTechnology/hls.js that referenced this issue Apr 5, 2024
* chore(deps): update typescript-eslint monorepo to v6.17.0

* chore(deps): update babel monorepo to v7.23.7

* chore(deps): update dependency rollup to v4.9.2

* chore(deps): update dependency rollup to v4.9.4

* Fix codec parsing for AVC streams (video-dev#6077)

* Force auto level on emergency switch down (video-dev#6082)

Update estimates on frag load timeout
Do not abort request in _abandonRulesCheck
Remove two segment forward buffer length limit in _abandonRulesCheck
Reset estimate when candidate bitrate is lower than adjusted estimate
Resolves video-dev#6079

* chore(deps): update dependency wrangler to v3.22.2

* chore(deps): update dependency wrangler to v3.22.4

* chore(deps): update dependency @microsoft/api-documenter to v7.23.16

* chore(deps): update dependency @microsoft/api-extractor to v7.39.1

* Null CMCD callbacks on destroy (video-dev#6098)

* Fix regression where subtitle options with AUTOSELECT and FORCED are enabled at start (video-dev#6094)

* Do not enable subtitle options with AUTOSELECT=YES attribute
* Update and add initial selection tests for subtitle-controller
* Only pick forced subtitle option if it is the only one
Add default field to audio and subtitle selection options and forced field to subtitle selection option
* Address TextTrack change event overriding subtitle preference
Fix _TRACKS_UPDATED and _TRACK_SWITCH event order when preference is selected
* Do not auto select subtitle options with FORCED=YES attribute

* Update artifact actions (video-dev#6099)

* Update functional tests to run on Safari using MacOS 13 (video-dev#6101)

* Update functional tests to run on Safari using MacOS 13

* Skip smooth switch test in Safari on streams with overlapping appends

* Omit VOD "ended" event tests with overlapping appends from Safari

* chore(deps): update dependency chai to v4.4.0

* chore(deps): update dependency chai to v4.4.1

* chore(deps): update typescript-eslint monorepo to v6.18.0

* chore(deps): update typescript-eslint monorepo to v6.18.1

* Use AAC SBR (HE-AAC) workaround on Pale Moon (video-dev#6111)

* Patch/v1.4.0 doris (#79)

* Patch/v1.3.3 doris (#76)

* MPEG-TS probe improvement (video-dev#5186)

Fixes video-dev#5183

* Support AES-128 Encrypted Low-Latency HLS Parts (video-dev#5214)

* Log error and detach if MediaSource 'sourceopen' is interrupted (video-dev#5206)

* fix: merge DiceTechnology/hls.js changes.

* fix: Transition from Clear to DRM content

* fix:Sometimes play AES-128 stream failed

* test: modify test case

---------

Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>

* 1.3.4

* docs: modify api doc.

* chore: Modify version.

---------

Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>
Co-authored-by: Hongfei Huang <hongfei.huang@endeavorstreaming.com>

* Patch/v1.4.1 doris (#80)

* reference v1 jsdelivr url in v1 api doc

people should be using that over latest so that things don't break when we release v2 with potentially breaking changes. Main readme already used v1 url

* chore(deps): update dependency @rollup/plugin-alias to v4.0.4

* chore(deps): update dependency @microsoft/api-documenter to v7.21.7

* chore(deps): update dependency @rollup/plugin-typescript to v11.1.0

* chore(deps): update dependency @rollup/plugin-node-resolve to v15.0.2

* chore(deps): update dependency wrangler to v2.15.0

* chore(deps): update dependency @rollup/plugin-alias to v5

* Fix readme logos & add Mux logo (video-dev#5390)

* docs: replace broken logo with Mux

* docs: fix TED logo

* docs: replace broken logos

* chore(deps): update dependency lint-staged to v13.2.1

* chore(deps): update dependency typescript to v5.0.4

* chore(deps): update dependency eslint to v8.38.0

* chore(deps): update dependency es-check to v7.1.1

* chore(deps): update dependency @rollup/plugin-terser to v0.4.1

* chore(deps): update typescript-eslint monorepo to v5.58.0

* chore(deps): update dependency semver to v7.4.0

* chore(deps): update dependency @rollup/plugin-commonjs to v24.1.0

* chore(deps): update dependency semver to v7.5.0

* chore(deps): update typescript-eslint monorepo to v5.59.0

* Setup npm provenance statements (video-dev#5406)

* give publish job permissions for npm provenance

* add `—provenance` flag to `npm publish`

* remove unneeded `contents` permission

* chore(deps): update dependency chromedriver to v112 (video-dev#5393)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tjenkinson@users.noreply.github.com>

* set `internalChecksAsSuccess` renovate option

* chore(deps): update dependency wrangler to v2.15.1

* set renovate `prNotPendingHours` to 0

* chore(deps): update dependency wrangler to v2.16.0

* chore(deps): update dependency rollup to v3.20.3

* chore(deps): update dependency rollup to v3.20.7

* chore(deps): update dependency rollup to v3.21.0

* chore(deps): update tjenkinson/gh-action-auto-merge-dependency-updates digest to 01b22a9 (video-dev#5324)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* tweak renovate options again

see renovatebot/renovate#21720

* reset remainderData in resetContiguity (video-dev#5410)

* docs: add Media Chrome for custom UI (video-dev#5391)

* Perform playlist retries before redundant failover and level switch (video-dev#5420)

(Pathway switch is still prioritized over retries when available)
Fixes video-dev#5419

* chore(deps): update dependency sinon to v15.0.4

* chore(deps): update dependency karma-chrome-launcher to v3.2.0

* chore(deps): update dependency selenium-webdriver to v4.9.0

* Update audio-track-controller.ts (video-dev#5431)

Sometimes STABLE-RENDITION_ID of tracks is undefined. Adding a guard for it, otherwise audio track doesn't switch.

* chore(deps): update dependency eslint to v8.39.0

* chore(deps): update dependency karma to v6.4.2

* chore(deps): update dependency prettier to v2.8.8

* Fix incorrect HEVC main profile codec id (video-dev#5438)

* fix: move `types` condition to the front (video-dev#5439)

* chore(deps): update dependency wrangler to v2.17.0

* chore(deps): update typescript-eslint monorepo to v5.59.1

* chore(deps): update typescript-eslint monorepo to v5.59.2

* Fix Low-Latency part and fragment tracking (video-dev#5423)

* Fix Low-Latency part and fragment tracking regression introduced in video-dev#5102

* Fix issues with reuse of player instance when loading additional assets
Fixes video-dev#5425

* Reset SourceBuffers in `loadSource()` when the asset URL has changed, or buffer-controller setup has begun

* Remove old parts from the fragment tracker on frag buffered

* Remove old parts from the fragment tracker on frag buffered

* Reset eme-controller key format promise on manifest loading

* chore(deps): update dependency lint-staged to v13.2.2

* Always use MediaSource returned by utils module (video-dev#5448)

* chore(deps): update dependency @microsoft/api-documenter to v7.22.0

* chore(deps): update dependency @microsoft/api-documenter to v7.22.4

* chore: Modify version

* chore: remove package-lock.json

---------

Co-authored-by: Tom Jenkinson <tjenkinson@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: hlsjs-ci <40664919+hlsjs-ci@users.noreply.github.com>
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
Co-authored-by: Billy Chiu <billychiu98@gmail.com>
Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>
Co-authored-by: Agajan J <agajan.tm@gmail.com>
Co-authored-by: Sta Zhu <zhusidayoyo@hotmail.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: yajin2021 <gene.jin@endeavorstreaming.com>

* Update DiceTechnology/hls.js to v1.4.3(#81)

* Patch/v1.4.4 doris (#82)

* reference v1 jsdelivr url in v1 api doc

people should be using that over latest so that things don't break when we release v2 with potentially breaking changes. Main readme already used v1 url

* chore(deps): update dependency @rollup/plugin-alias to v4.0.4

* chore(deps): update dependency @microsoft/api-documenter to v7.21.7

* chore(deps): update dependency @rollup/plugin-typescript to v11.1.0

* chore(deps): update dependency @rollup/plugin-node-resolve to v15.0.2

* chore(deps): update dependency wrangler to v2.15.0

* chore(deps): update dependency @rollup/plugin-alias to v5

* Fix readme logos & add Mux logo (video-dev#5390)

* docs: replace broken logo with Mux

* docs: fix TED logo

* docs: replace broken logos

* chore(deps): update dependency lint-staged to v13.2.1

* chore(deps): update dependency typescript to v5.0.4

* chore(deps): update dependency eslint to v8.38.0

* chore(deps): update dependency es-check to v7.1.1

* chore(deps): update dependency @rollup/plugin-terser to v0.4.1

* chore(deps): update typescript-eslint monorepo to v5.58.0

* chore(deps): update dependency semver to v7.4.0

* chore(deps): update dependency @rollup/plugin-commonjs to v24.1.0

* chore(deps): update dependency semver to v7.5.0

* chore(deps): update typescript-eslint monorepo to v5.59.0

* Setup npm provenance statements (video-dev#5406)

* give publish job permissions for npm provenance

* add `—provenance` flag to `npm publish`

* remove unneeded `contents` permission

* chore(deps): update dependency chromedriver to v112 (video-dev#5393)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tjenkinson@users.noreply.github.com>

* set `internalChecksAsSuccess` renovate option

* chore(deps): update dependency wrangler to v2.15.1

* set renovate `prNotPendingHours` to 0

* chore(deps): update dependency wrangler to v2.16.0

* chore(deps): update dependency rollup to v3.20.3

* chore(deps): update dependency rollup to v3.20.7

* chore(deps): update dependency rollup to v3.21.0

* chore(deps): update tjenkinson/gh-action-auto-merge-dependency-updates digest to 01b22a9 (video-dev#5324)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* tweak renovate options again

see renovatebot/renovate#21720

* reset remainderData in resetContiguity (video-dev#5410)

* docs: add Media Chrome for custom UI (video-dev#5391)

* Perform playlist retries before redundant failover and level switch (video-dev#5420)

(Pathway switch is still prioritized over retries when available)
Fixes video-dev#5419

* chore(deps): update dependency sinon to v15.0.4

* chore(deps): update dependency karma-chrome-launcher to v3.2.0

* chore(deps): update dependency selenium-webdriver to v4.9.0

* Update audio-track-controller.ts (video-dev#5431)

Sometimes STABLE-RENDITION_ID of tracks is undefined. Adding a guard for it, otherwise audio track doesn't switch.

* chore(deps): update dependency eslint to v8.39.0

* chore(deps): update dependency karma to v6.4.2

* chore(deps): update dependency prettier to v2.8.8

* Fix incorrect HEVC main profile codec id (video-dev#5438)

* fix: move `types` condition to the front (video-dev#5439)

* chore(deps): update dependency wrangler to v2.17.0

* chore(deps): update typescript-eslint monorepo to v5.59.1

* chore(deps): update typescript-eslint monorepo to v5.59.2

* Fix Low-Latency part and fragment tracking (video-dev#5423)

* Fix Low-Latency part and fragment tracking regression introduced in video-dev#5102

* Fix issues with reuse of player instance when loading additional assets
Fixes video-dev#5425

* Reset SourceBuffers in `loadSource()` when the asset URL has changed, or buffer-controller setup has begun

* Remove old parts from the fragment tracker on frag buffered

* Remove old parts from the fragment tracker on frag buffered

* Reset eme-controller key format promise on manifest loading

* chore(deps): update dependency lint-staged to v13.2.2

* Always use MediaSource returned by utils module (video-dev#5448)

* chore(deps): update dependency @microsoft/api-documenter to v7.22.0

* chore(deps): update dependency @microsoft/api-documenter to v7.22.4

* chore(deps): update babel monorepo to v7.21.5

* chore(deps): update dependency @microsoft/api-extractor to v7.34.5

* chore(deps): update dependency @babel/core to v7.21.8

* chore(deps): update dependency @microsoft/api-extractor to v7.34.6

* chore(deps): update dependency @microsoft/api-extractor to v7.34.8

* chore(deps): update dependency @types/chai to v4.3.5

* chore(deps): update dependency rollup to v3.21.1

* chore(deps): update dependency rollup to v3.21.5

* chore(deps): update dependency eventemitter3 to v5.0.1

* fix: partial audiovideo fragments not being treated as partial (video-dev#5460)

Fragments which contain both audio and video also need to be checked if
they are partial. We check for them individually, but there are cases
when only the one flag is set.

* Fix AV desync regression in v1.4.0 when mp4 audio track timestamps start before video track timestamps (video-dev#5471)

Fixes video-dev#5452

* chore(deps): update dependency wrangler to v2.18.0

* chore(deps): update dependency chromedriver to v112.0.1

* chore(deps): update dependency wrangler to v2.20.0

* Allow live level loading to recover from net::ERR_NETWORK_IO_SUSPENDED errors (video-dev#5473)

* Remove startLoad() as recovery method from API.md doc (video-dev#5478)

video-dev#5476

* Fix first fragment ejection tracking (video-dev#5480)

Fixes video-dev#5482

* Provide light ESM dist file (video-dev#5486)

* Playlist loading errors are fatal after all levels and retries exhausted (video-dev#5498)

Fixes video-dev#5488

* Adjust parsed TS AVC samples when start PTS overlaps with last DTS (video-dev#5500)

Resolves video-dev#5477

* Fix TS probing false positives by requiring 2-3 packet start bytes to be matched or more if first byte does not match sync word (video-dev#5503)

Fixes video-dev#5501

* Use input timescale when normalizing metadata cue timestamps (video-dev#5505)

Fixes video-dev#5504

* chore: change package.json

---------

Co-authored-by: Tom Jenkinson <tjenkinson@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: hlsjs-ci <40664919+hlsjs-ci@users.noreply.github.com>
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
Co-authored-by: Billy Chiu <billychiu98@gmail.com>
Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>
Co-authored-by: Agajan J <agajan.tm@gmail.com>
Co-authored-by: Sta Zhu <zhusidayoyo@hotmail.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Troy <troybensonsa@gmail.com>
Co-authored-by: Chocobozzz <chocobozzz@cpy.re>

* 1.5.1

* chore(deps): update dependency rollup to v4.9.5

* chore(deps): update dependency @rollup/plugin-typescript to v11.1.6

* chore(deps): update dependency @babel/preset-env to v7.23.8

* chore(deps): update typescript-eslint monorepo to v6.19.0

* chore(deps): update typescript-eslint monorepo to v6.19.1

* Use WebCrypto by default and only use software as a fallback if enabled (video-dev#6015)

Fixes use of  `enableSoftwareAES` to match the docs and the intended behavior when added in #99

* Null inline class JavaScript Event callback properties on destroy (video-dev#6102)

* chore(deps): update dependency @microsoft/api-documenter to v7.23.17

* chore(deps): update dependency @microsoft/api-documenter to v7.23.18

* chore(deps): update dependency @microsoft/api-documenter to v7.23.19

* chore(deps): update dependency wrangler to v3.22.5

* chore(deps): update dependency wrangler to v3.24.0

* Remove user-agent check from "mp4a.40.34" to "mp3" and "audio/mpeg" fallback (video-dev#6130)

Fixes video-dev#6125

* Adding AES-256 and AES-256-CTR encryption modes

* fix: generate silent aac frame based on original codec (video-dev#6123)

* Lazy init CEA608 parsers (2) (video-dev#6127)

* Use average for level sorting and abandon rules check (video-dev#6135)

Fixes video-dev#6122

* User unique logger configurations across instances of Hls(js)
Resolves video-dev#2461

* chore(deps): update dependency @svta/common-media-library to v0.6.2

* Use average for level sorting and abandon rules check (video-dev#6135) (video-dev#6146)

Fixes video-dev#6122

* Add MEDIA_ENDED event (forwards "ended" event, or emits when stalling begins near end of VOD) (video-dev#6141)

* chore(deps): update dependency chromedriver to v120.0.2

* chore(deps): update dependency rollup to v4.9.6

* feat: add support for CMCD nor (video-dev#6091)

* feat: add support for CMCD nor
* deps: update @svta/common-media-library to version 0.6.2
Resolves video-dev#6088

* fix(Remuxer): Safari segment overlap ensure PTS order (video-dev#6132)

* fix(Remuxer): Safari segment overlap ensure PTS alignment

* Fix regression in hls.light.js selection (video-dev#6155)

Fixes video-dev#6151

* chore(deps): update dependency selenium-webdriver to v4.17.0

* chore(deps): update dependency @microsoft/api-extractor to v7.39.2

* chore(deps): update dependency @microsoft/api-extractor to v7.39.4

* Fix regression in hls.light.js selection (video-dev#6157)

Fixes video-dev#6151

* chore(deps): update dependency husky to v9 (video-dev#6165)

* chore(deps): update dependency husky to v9

* Make changes for new husky

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tom@tjenkinson.me>

* chore(deps): update actions/cache action to v4 (video-dev#6143)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency prettier to v3.2.4 (video-dev#6124)

* chore(deps): update dependency prettier to v3.2.4

* Run prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tom@tjenkinson.me>

* Disable `AppleAdvancedHevcAvcHls` stream for now due to cors errors (video-dev#6176)

* chore(deps): update babel monorepo to v7.23.9

* chore(deps): update dependency @microsoft/api-documenter to v7.23.20

* chore(deps): update dependency wrangler to v3.25.0

* chore(deps): update dependency chromedriver to v121 (video-dev#6162)

* chore(deps): update dependency wrangler to v3.26.0

* chore(deps): replace dependency npm-run-all with npm-run-all2 5.0.0 (video-dev#6153)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency npm-run-all2 to v5.0.2

* chore(deps): update dependency husky to v9.0.7

* chore(deps): update dependency husky to v9.0.10

* chore(deps): update typescript-eslint monorepo to v6.20.0

* chore(deps): update typescript-eslint monorepo to v6.21.0

* Revert "Disable `AppleAdvancedHevcAvcHls` stream for now due to cors errors (…" (video-dev#6187)

This reverts commit e3f4d4d.

* Use main playlist details to determine start position of audio and subtitle streaming controllers
Fixes video-dev#6126

* Fix regression that removed (unofficial) support for `startLevel` above max level index
Fixes video-dev#6172

* Account for overlapping sidx subsegment durations by parsing earlierstPresentationTime
Fixes video-dev#6191

* Use main playlist details to determine start position of audio and subtitle streaming controllers
Fixes video-dev#6126

(cherry picked from commit 35c773d)

* Fix regression that removed (unofficial) support for `startLevel` above max level index
Fixes video-dev#6172

(cherry picked from commit 88d54a9)

* Account for overlapping sidx subsegment durations by parsing earlierstPresentationTime
Fixes video-dev#6191

(cherry picked from commit aadb239)

* Handle ManagedMediaSource endStreaming events without aborting requests

* Feature/mpeg ts hevc (video-dev#5847)

* Modify video parser and ts-demuxer to support NALu streams other than AVC
* Process HEVC in mpeg-ts container
---------
Co-authored-by: vladimir.vyatkin <vladimir.vyatkin@portal59.ru>

* Do not include HEVC in TS support in hls.light (compiled out by __USE_M2TS_ADVANCED_CODECS__)

* chore(deps): update dependency lint-staged to v15.2.1

* chore(deps): update dependency lint-staged to v15.2.2

* Update API.md for CMCD `includeKeys`

* Global exported logger uses the log methods from last call to `enableLogs`
Follow up to video-dev#6131

* Skip segment and part directives when last LL-HLS response is older than three target durations
Fix Media Playlist 'advanced' state when no Multivariant Playlist is provided
Related to video-dev#6076

* Switch between part and fragment loading at start and on segment boundary appends

* Fix subtitle stream controller buffered TimeRanges

* chore(deps): update dependency semver to v7.6.0

* chore(deps): update dependency @microsoft/api-documenter to v7.23.21

* chore(deps): update dependency @microsoft/api-documenter to v7.23.23

* chore(deps): update dependency @microsoft/api-extractor to v7.39.5

* chore(deps): update dependency @microsoft/api-extractor to v7.40.1

* Fix subtitle stream controller buffered TimeRanges

* chore(deps): update dependency wrangler to v3.27.0

* chore(deps): update dependency wrangler to v3.28.2

* chore(deps): update dependency mocha to v10.3.0

* Fix issues with detached and destroyed level selection (video-dev#6216)

* Fix issues with detached and destroyed level selection (video-dev#6216)

* chore(deps): update dependency rollup to v4.10.0

* chore(deps): update dependency rollup to v4.12.0

* fix index offset in sidx parsing (video-dev#6221)

* fix index offset in sidx parsing (video-dev#6221)

(cherry picked from commit e18d394)

* Add no-op comment to empty statement (fix lint error)

* Block audio append queue to keep AV appends in lock-step

* Reduce length of ESDS box guard statement

* rutube logo for they use section

* chore(deps): update dependency husky to v9.0.11

* Don't flush buffer on cap-level change when in manual selection mode (video-dev#6223)

* Don't switch level if current already greater or equal
* Don't switch level if autoLevel disabled
---------
Co-authored-by: Vladimir Polomanov <vpolomanov@rutube.ru>

* Fix audio/subtitles stream controllers restarting on switch after stopped
Update stream controller access specifiers

* Cleanup buffer-helper functions and remove nested try-catch statements

* Fix pauseBuffering() dev regression

* chore(deps): update dependency chromedriver to v121.0.1

* chore(deps): update dependency eslint-plugin-mocha to v10.3.0

* chore(deps): update dependency chromedriver to v121.0.2

* chore(deps): update dependency wrangler to v3.28.3

* chore(deps): update dependency @microsoft/api-documenter to v7.23.24

* chore(deps): update dependency @microsoft/api-extractor to v7.40.2

* chore(deps): update dependency @microsoft/api-extractor to v7.40.6

* chore(deps): update dependency wrangler to v3.29.0

* chore(deps): update dependency @microsoft/api-documenter to v7.23.30

* Fix compatibility of ManagedMediaSource implementation with Edge 18
Fixes video-dev#6243

* chore(deps): update dependency selenium-webdriver to v4.18.1

* Clean up base-stream-controller

* Don't pass log functions with player id to global logger

* Clear media from cap-level-controller on detach

* remove iphone compatibility note since its supported through mms

* added more info for iOS 17.1+ support

* Run Prettier to address lint error

* chore(deps): update dependency @types/chai to v4.3.12

* Ensure media element references are removed after calling detachMedia

* chore(deps): update dependency eslint to v8.57.0

* chore(deps): update dependency karma to v6.4.3

* chore(deps): update dependency @microsoft/api-extractor to v7.41.0

* chore(deps): update dependency @microsoft/api-extractor to v7.42.2

* chore(deps): update dependency @microsoft/api-documenter to v7.23.31

* chore(deps): update dependency @microsoft/api-documenter to v7.23.35

* chore(deps): update dependency wrangler to v3.30.0

* chore(deps): update dependency wrangler to v3.31.0

* chore(deps): update babel monorepo to v7.24.0

* chore(deps): update dependency @svta/common-media-library to v0.6.3

* chore(deps): update dependency @svta/common-media-library to v0.6.4

* chore(deps): update dependency chromedriver to v122 (video-dev#6250)

* chore(deps): update typescript-eslint monorepo to v7 (video-dev#6225)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency npm-run-all2 to v6 (video-dev#6179)

* chore(deps): update dependency @microsoft/api-documenter to v7.23.36

* chore(deps): update dependency @microsoft/api-documenter to v7.23.37

* chore(deps): update dependency @microsoft/api-extractor to v7.42.3

* chore(deps): update typescript-eslint monorepo to v7.1.1

* chore(deps): update typescript-eslint monorepo to v7.2.0

* chore(deps): update dependency rollup to v4.12.1

* chore(deps): update dependency rollup to v4.13.0

* chore(deps): update dependency typescript to v5.4.2

* chore(deps): update dependency eslint-plugin-mocha to v10.4.0

* chore(deps): update dependency eslint-plugin-mocha to v10.4.1

* chore(deps): update dependency wrangler to v3.32.0

* chore(deps): update dependency wrangler to v3.34.2

* chore(deps): update dependency chromedriver to v122.0.5

* chore(deps): update dependency chromedriver to v122.0.6

* 1.5.7

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: hlsjs-ci <40664919+hlsjs-ci@users.noreply.github.com>
Co-authored-by: Jakub Perżyło <qizot1405@gmail.com>
Co-authored-by: Rob Walch <robwalch@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tjenkinson@users.noreply.github.com>
Co-authored-by: Pat Nafarrete <pnaf@users.noreply.github.com>
Co-authored-by: yajin2021 <83813017+yajin2021@users.noreply.github.com>
Co-authored-by: Hongfei Huang <hongfei.huang@endeavorstreaming.com>
Co-authored-by: Hongfei Huang <83795629+hongfeih-es@users.noreply.github.com>
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
Co-authored-by: Billy Chiu <billychiu98@gmail.com>
Co-authored-by: Agajan J <agajan.tm@gmail.com>
Co-authored-by: Sta Zhu <zhusidayoyo@hotmail.com>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: yajin2021 <gene.jin@endeavorstreaming.com>
Co-authored-by: Troy <troybensonsa@gmail.com>
Co-authored-by: Chocobozzz <chocobozzz@cpy.re>
Co-authored-by: root <root@jvarydeb>
Co-authored-by: FredTsang <zengzhifeng@cvte.com>
Co-authored-by: Rob Walch <rwalch@apple.com>
Co-authored-by: Casey Occhialini <1508707+littlespex@users.noreply.github.com>
Co-authored-by: Asen-O-Nikolov <98342935+Asen-O-Nikolov@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tom@tjenkinson.me>
Co-authored-by: Vladmir Vyatkin <voldemarpro@hotmail.com>
Co-authored-by: Nikola Hristov <nklhtv@gmail.com>
Co-authored-by: Pavel Fomin <pfomin@rutube.ru>
Co-authored-by: Vladimir Polomanov <67444538+corndev27@users.noreply.github.com>
Co-authored-by: Felix Groove <felix.groove@lhind.dlh.de>
Co-authored-by: Rob Walch <rob@jwplayer.com>
@byumark
Copy link
Author

byumark commented Jul 1, 2024

Hi @robwalch , we're looking into this issue on our end again. As you may recall, we thought that this might be related to sidx, but I recall that the fix you made didn't appear to help. Our content is HLS, so I'm not sure that it has sidx data. I was looking over the code changes from 1.2.0 to 1.2.1 and saw other changes that seemed like they could affect duration.

In the file src/demux/base-audio-demuxer.ts there are the following changes:

Original:

  resetTimeStamp() {}

  resetContiguity(): void {}

Modified:

  resetTimeStamp(deaultTimestamp) {
    this.initPTS = deaultTimestamp;
    this.resetContiguity();
  }

  resetContiguity(): void {
    this.basePTS = null;
    this.frameIndex = 0;
  }

Original:

export const initPTSFn = (
  timestamp: number | undefined,
  timeOffset: number
): number => {
  return Number.isFinite(timestamp as number)
    ? timestamp! * 90
    : timeOffset * 90000;
};

Modified:

export const initPTSFn = (
  timestamp: number | undefined,
  timeOffset: number,
  initPTS: number | null
): number => {
  if (Number.isFinite(timestamp as number)) {
    return timestamp! * 90;
  }
  return timeOffset * 90000 + (initPTS || 0);
};

There's also this change in src/loader/playlist-loader.ts, but it only seems to be related to files with sidx data:

Original:

      if (frag.initSegment) {
        frag.initSegment.setByteRange(String(sidxInfo.moovEndOffset) + '@0');
      }

Modified:

      if (frag.initSegment) {
        const moovBox = findBox(data, ['moov'])[0];
        const moovEndOffset = moovBox ? moovBox.length : null;
        frag.initSegment.setByteRange(String(moovEndOffset) + '@0');
      }

Could any of these changes, mixed with something weird going on with the browser, affect the video duration being displayed on the player? This is only affecting a small group of our users and they all seem to be Windows. We have not been able to reproduce the issue on our end.

@nklhtv
Copy link
Contributor

nklhtv commented Jul 1, 2024

@robwalch That is exactly the use-case i have, i have hls streams where duration is only available in segment index boxes (sidx and no trun or missing tfhd sample duration)
@byumark hls stream that uses mp4 segments could contain sidx atoms. Is it possible to give us an example m3u8 playlist that causes the issue?

@robwalch
Copy link
Collaborator

robwalch commented Jul 1, 2024

Please file a new issue with sample content that reproduces a bug. There are no known issues with fragment duration calculation. This issue is closed.

@nklhtv
Copy link
Contributor

nklhtv commented Jul 1, 2024

The segments used by @byumark are ts, which should mean that parsing sidx is not involved here.

@byumark
Copy link
Author

byumark commented Jul 1, 2024

@robwalch Unfortunately, we have never been able to reproduce it on our own. We have been able to see the double duration in Mux Data for users that claim to be seeing it. If we are able to have a user reproduce it for us, is there anything we can do on their computer to get valuable information that would help us understand it better or even help us reproduce it ourselves?

@robwalch
Copy link
Collaborator

robwalch commented Jul 1, 2024

On the latest release (v1.5.12), if you can reproduce the issue, examine the level details and fragment list HLS is currently using and compare it to both video.duration and the HLS Playlist content.

Do the EXTINF durations in the playlist add up to hls.levels[hls.currentLevel].details.totalduration?

How do they compare to the durations of parsed segments (hls.levels[hls.currentLevel].details.fragments)?

You might need to examine all loaded level details not just hls.currentLevel.

Does the issue happen only after a switch? Are the timestamps consistent between variants?

Enable debug logs to save the output and share it here. Init PTS is logged and there are warnings for a variety of media parsing issues.

@robwalch
Copy link
Collaborator

robwalch commented Jul 1, 2024

The segments used by @byumark are ts, which should mean that parsing sidx is not involved here.

There's nothing that I can identify in TS handling that would produce the issue described. The only logical and reproducible regression between 1.2.0 and 1.2.1 for such an outcome is what was found and fixed in #6192. That is not to say you aren't facing a real issue. It sounds like a browser or library issue or perhaps something odd about the media (although if it was the media we'd expect the problem to present on all platforms). Once you have something that I can reproduce, I can look into root cause and a fix.

@byumark
Copy link
Author

byumark commented Jul 10, 2024

We were able to get logs from one of the users experiencing this issue:

[log] > Debug logs enabled for "Hls instance" in hls.js version 1.5.12
[log] > stopLoad
[log] > loadSource:https://***/master.m3u8
[log] > [stream-controller]: Trigger BUFFER_RESET
[log] > attachMedia
[log] > [buffer-controller] created media source: MediaSource
[error] > Media element src was set while attaching MediaSource (blob:https://***/0b009bfe-4085-429b-ab56-ec9261215b9d > https://***/video/delivery/api/v1/storyboards/5e8f8fba-8bf2-4722-b07e-f04c6b2b3091/7c5960c1-4f22-4c81-b2a0-1b6da5ad98b6)
[log] > [buffer-controller] Media source opened
[log] > [level-controller]: manifest loaded, 7 level(s) found, first bitrate: 1331623
[log] > setting initial bwe to 1331623
[log] > [buffer-controller] 2 bufferCodec event(s) expected
[log] > startLoad(414.287246)
[log] > [abr] picked start tier {"codecSet":"avc1,mp4a","videoRanges":["SDR"],"preferHDR":false,"minFramerate":23.976,"minBitrate":392276}
[info] > [abr] switch candidate:4->4 adjustedbw(1331623)-bitrate=0 ttfb:0.1 avgDuration:0.0 maxFetchDuration:4.0 fetchDuration:0.1 firstSelection:true codecSet:avc1,mp4a videoRange:SDR hls.loadLevel:-1
[log] > [level-controller]: Switching to level 4 (540p SDR avc1,mp4a @1331623) from level -1
[log] > [audio-track-controller]: Updating audio tracks, 1 track(s) found in group(s): program_audio
[log] > [audio-track-controller]: Switching to audio-track 0 "Alternate Audio" lang:eng group:program_audio channels:undefined
[log] > [audio-stream-controller]: Reset loading state
[log] > [audio-stream-controller]: STOPPED->IDLE
[log] > [audio-stream-controller]: IDLE->WAITING_TRACK
[log] > [level-controller]: Loading level index 4 with https://***/hls_960x540.m3u8
[log] > [stream-controller]: STOPPED->IDLE
[log] > [audio-track-controller]: loading audio-track playlist 0 "Alternate Audio" lang:eng group:program_audio
[log] > [audio-stream-controller]: WAITING_TRACK->STOPPED
[log] > [audio-stream-controller]: STOPPED->WAITING_TRACK
[log] > [subtitle-stream-controller]: STOPPED->IDLE
[log] > [audio-track-controller]: Audio track 0 "Alternate Audio" lang:eng group:program_audio loaded [1-58]
[log] > [stream-controller]: Level 4 loaded [1,58][part-58--1], cc [0, 0] duration:287
[log] > [buffer-controller] Updating Media Source duration to 287.000
[log] > [stream-controller]: Loading fragment 58 cc: 0 of [1-58] level: 4, target: 414.287
[log] > [stream-controller]: IDLE->FRAG_LOADING
[log] > [audio-track-controller]: Audio track 0 "Alternate Audio" lang:eng group:program_audio loaded [1-58]
[log] > [audio-stream-controller]: Audio track 0 loaded [1,58][part-58--1],duration:287
[log] > [audio-stream-controller]: WAITING_TRACK->IDLE
[log] > [audio-stream-controller]: Loading fragment 58 cc: 0 of [1-58] track: 0, target: 414.287
[log] > [audio-stream-controller]: IDLE->FRAG_LOADING
[log] > [audio-stream-controller]: Unknown video PTS for cc 0, waiting for video PTS before demuxing audio frag 58 of [1 ,58],track 0
[log] > [audio-stream-controller]: FRAG_LOADING->WAITING_INIT_PTS
[log] > [audio-stream-controller]: Loaded fragment 58 of level 0
[log] > [transmuxer-interface, main]: Starting new transmux session for sn: 58 p: -1 level: 4 id: 1
[log] > [mp4-remuxer]: ISGenerated flag reset
[log] > [mp4-remuxer]: initPTS & initDTS reset
[log] > [mp4-remuxer]: reset next timestamp
[log] > 25998292/25994538:unknown NAL 11 
[log] > [stream-controller]: FRAG_LOADING->PARSING
[log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.4d401f/avc1.4d401f]
[log] > [buffer-controller] 1 bufferCodec event(s) expected video
[log] > [audio-stream-controller]: InitPTS for cc: 0 found from main: -25466247
[log] > [audio-stream-controller]: WAITING_INIT_PTS->FRAG_LOADING
[log] > [transmuxer-interface, audio]: Starting new transmux session for sn: 58 p: -1 level: 0 id: 1
[log] > ADTS sync word found !
[log] > [mp4-remuxer]: ISGenerated flag reset
[log] > [mp4-remuxer]: initPTS & initDTS reset
[log] > [mp4-remuxer]: reset next timestamp
[log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:3
[log] > parsed codec:mp4a.40.5, rate:48000, channels:2
[log] > [audio-stream-controller]: FRAG_LOADING->PARSING
[log] > [audio-stream-controller]: Init audio buffer, container:audio/mp4, codecs[level/parsed]=[mp4a.40.2/mp4a.40.5]
[log] > [buffer-controller] 0 bufferCodec event(s) expected audio
[log] > [buffer-controller] creating sourceBuffer(video/mp4;codecs=avc1.4d401f)
[log] > [buffer-controller] creating sourceBuffer(audio/mp4;codecs=mp4a.40.2)
[log] > [stream-controller]: Alternate track found, use video.buffered to schedule main fragment loading
[log] > [transmuxer.ts]: Flushed fragment 58 of level 0
[log] > [audio-stream-controller]: PARSING->PARSED
[log] > [stream-controller]: Loaded fragment 58 of level 4
[log] > [transmuxer.ts]: Flushed fragment 58 of level 4
[log] > [stream-controller]: PARSING->PARSED
[log] > [stream-controller]: media seeking to 287.000, state: PARSED
[log] > [audio-stream-controller]: media seeking to 287.000, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 287.000, state: IDLE
[log] > [stream-controller]: media seeking to 287.783, state: PARSED
[log] > [audio-stream-controller]: media seeking to 287.783, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 287.783, state: IDLE
[log] > [stream-controller]: media seeking to 299.026, state: PARSED
[log] > [audio-stream-controller]: media seeking to 299.026, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 299.026, state: IDLE
[log] > [stream-controller]: media seeking to 310.269, state: PARSED
[log] > [audio-stream-controller]: media seeking to 310.269, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 310.269, state: IDLE
[log] > [stream-controller]: media seeking to 321.490, state: PARSED
[log] > [audio-stream-controller]: media seeking to 321.490, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 321.490, state: IDLE
[log] > [stream-controller]: media seeking to 332.711, state: PARSED
[log] > [audio-stream-controller]: media seeking to 332.711, state: PARSED
[log] > [subtitle-stream-controller]: media seeking to 332.711, state: IDLE

This is Windows 10, Google Chrome Version 126.0.6478.127.

@robwalch
Copy link
Collaborator

robwalch commented Jul 10, 2024

Hi @byumark,

Here's a breakdown of what we can see in these logs related to duration. I don't see anything pointing to an issue with hls.js. If anything the start position at the beginning and seeking at the end suggest that the application using hls.js expects the duration of the content to be longer than it actually is.

Loading begins with the intent to seek to 414s:

[log] > startLoad(414.287246)

The HLS media playlists (main and alt-audio) have segment durations that each add up to 287s:

[log] > [stream-controller]: Level 4 loaded [1,58][part-58--1], cc [0, 0] duration:287
[log] > [audio-stream-controller]: Audio track 0 loaded [1,58][part-58--1],duration:287

The MediaSource duration is set to 287 (there are no other logs of duration being set):

[log] > [buffer-controller] Updating Media Source duration to 287.000

The last segment of each playlist (no.58 of 1-58) is loaded (the closest to the unaccessible start position of 414):

[log] > [stream-controller]: Loading fragment 58 cc: 0 of [1-58] level: 4, target: 414.287
[log] > [audio-stream-controller]: Loading fragment 58 cc: 0 of [1-58] track: 0, target: 414.287

In the MPEGTS tranmsuxer an unknown NAL unit type is encountered (25994538/90000 = 288.82). NAL unit type 11 signals end of stream and is not expected/handled/needed by hls.js which relies on an EXT-X-ENDLIST tag in the Playlists to signal EOS:

[log] > 25998292/25994538:unknown NAL 11 

The last segment no.58 starts has a starting PTS of 25466247 (25466247/90000 = 282.95)

[log] > [audio-stream-controller]: InitPTS for cc: 0 found from main: -25466247

The remaining logs show attempts to seek (HTMLMediaElement "seeking" events) past the last stated duration of the media. These are not resolves and there is no other activity from hls.js. If these seeks were issued by hls.js there would be log messages explaining why. They were not.

[log] > [stream-controller]: media seeking to 287.000, state: PARSED
...
[log] > [stream-controller]: media seeking to 332.711, state: PARSED

So it seems you have an application using hls.js that expects the duration to be greater than what is available in the media and that attempts to seek past the end. Perhaps it is also responsible for displaying the incorrect duration (and not hls.js)?

@byumark
Copy link
Author

byumark commented Jul 10, 2024

@robwalch thanks for the thorough explanation. I think what's happening with the initial seek is that we store the playhead location in local storage so that users can pick up where they left off when they come back to the video. My hunch is that the user found a video with the double duration problem, manually seeked into the time of the video that doesn't really exist, and hit refresh on the page. That could explain why the logs show that the player is immediately seeking into a time on the video that doesn't really exist.

I'll try to see if the user can test the master manifest in the hls.js demo page and see if the results are any different.

@robwalch
Copy link
Collaborator

robwalch commented Jul 10, 2024

The logs are missing fragBufferedComplete logs. After media is parsed (PARSING->PARSED), it is expected to be appended if it indeed contained any audio and/or video. For a VOD stream, these would be followed by EOS handling and the stream controllers switching to the ENDED state.

"[stream-controller]:" – "Buffered main sn: 0 of level 3 (frag:[0.000-10.023] > buffer:[0.023-10.008])"

When I attempt to seek in Chrome by setting currentTime to a value greater than duration, the seeking and seeked events do not report a currentTime greater than that of the last sample time appended to the media. Is it possible that your last TS segments has some sample with rogue media timestamps following the one with the EOS NAL unit?

@robwalch robwalch reopened this Jul 10, 2024
@robwalch
Copy link
Collaborator

robwalch commented Jul 10, 2024

We should add a log line in onFragParsed with the frag times matching the logs from fragBufferedComplete. This will help troubleshoot issues with parsed media timestamps that never make it thought the appending process.

@byumark if you could provide just those segments (last audio and video) it would help to isolate the issue.

@robwalch robwalch modified the milestones: 1.5.6, 1.6.0 Jul 10, 2024
@byumark
Copy link
Author

byumark commented Jul 10, 2024

@robwalch I can for sure provide those segments. Is there a good way to do that without sharing them publicly?

Also, we just got off of the phone with our user and the problem did occur on the hlsjs demo page. Here are the logs from it.

Using Hls.js config: Object
[log] > Debug logs enabled for "Hls instance" in hls.js version 1.5.13
[log] > stopLoad
[log] > loadSource:https://***/master.m3u8
[log] > [stream-controller]: Trigger BUFFER_RESET
[log] > attachMedia
[log] > [buffer-controller] created media source: MediaSource
[log] > [buffer-controller] Media source opened
[log] > [level-controller]: manifest loaded, 7 level(s) found, first bitrate: 1331623
[log] > setting initial bwe to 1331623
[log] > [buffer-controller] 2 bufferCodec event(s) expected
[log] > [abr] picked start tier {"codecSet":"avc1,mp4a","videoRanges":["SDR"],"preferHDR":false,"minFramerate":23.976,"minBitrate":392276}
[info] > [abr] switch candidate:4->4 adjustedbw(1331623)-bitrate=0 ttfb:0.1 avgDuration:0.0 maxFetchDuration:4.0 fetchDuration:0.1 firstSelection:true codecSet:avc1,mp4a videoRange:SDR hls.loadLevel:-1
[log] > startLoad(-1)
[log] > [level-controller]: Switching to level 4 (540p SDR avc1,mp4a @1331623) from level -1
[log] > [audio-track-controller]: Updating audio tracks, 1 track(s) found in group(s): program_audio
[log] > [audio-track-controller]: Switching to audio-track 0 "Alternate Audio" lang:eng group:program_audio channels:undefined
[log] > [audio-stream-controller]: Reset loading state
[log] > [audio-stream-controller]: STOPPED->IDLE
[log] > [audio-stream-controller]: IDLE->WAITING_TRACK
[log] > [level-controller]: Loading level index 4 with https://***/hls_960x540.m3u8
[log] > [stream-controller]: STOPPED->IDLE
[log] > [audio-track-controller]: loading audio-track playlist 0 "Alternate Audio" lang:eng group:program_audio
[log] > [audio-stream-controller]: WAITING_TRACK->STOPPED
[log] > [audio-stream-controller]: STOPPED->WAITING_TRACK
[log] > [subtitle-stream-controller]: STOPPED->IDLE
[log] > [stream-controller]: Level 4 loaded [1,58][part-58--1], cc [0, 0] duration:287
[log] > [buffer-controller] Updating Media Source duration to 287.000
[log] > [stream-controller]: Loading fragment 1 cc: 0 of [1-58] level: 4, target: 0
[log] > [stream-controller]: IDLE->FRAG_LOADING
[log] > [audio-track-controller]: Audio track 0 "Alternate Audio" lang:eng group:program_audio loaded [1-58]
[log] > [audio-stream-controller]: Audio track 0 loaded [1,58][part-58--1],duration:287
[log] > [audio-stream-controller]: WAITING_TRACK->IDLE
[log] > [audio-stream-controller]: Loading fragment 1 cc: 0 of [1-58] track: 0, target: 0
[log] > [audio-stream-controller]: IDLE->FRAG_LOADING
[log] > injecting Web Worker for "audio"
[log] > [audio-stream-controller]: Unknown video PTS for cc 0, waiting for video PTS before demuxing audio frag 1 of [1 ,58],track 0
[log] > [audio-stream-controller]: FRAG_LOADING->WAITING_INIT_PTS
[log] > [audio-stream-controller]: Loaded fragment 1 of level 0
[log] > Debug logs enabled for "audio" in hls.js version 1.5.13
[log] > injecting Web Worker for "main"
[log] > [transmuxer-interface, main]: Starting new transmux session for sn: 1 p: -1 level: 4 id: 1
        discontinuity: true
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 0
        initSegmentChange: true
[log] > [stream-controller]: Loaded fragment 1 of level 4
[log] > Debug logs enabled for "main" in hls.js version 1.5.13
[log] > [mp4-remuxer]: ISGenerated flag reset
[log] > [mp4-remuxer]: initPTS & initDTS reset
[log] > [mp4-remuxer]: reset next timestamp
[log] > 25998292/25994538:unknown NAL 11 
[log] > [stream-controller]: FRAG_LOADING->PARSING
[log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.4d401f/avc1.4d401f]
[log] > [buffer-controller] 1 bufferCodec event(s) expected video
[log] > [audio-stream-controller]: InitPTS for cc: 0 found from main: 183753
[log] > [audio-stream-controller]: WAITING_INIT_PTS->FRAG_LOADING
[log] > [transmuxer-interface, audio]: Starting new transmux session for sn: 1 p: -1 level: 0 id: 1
        discontinuity: true
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: false
        timeOffset: 0
        initSegmentChange: true
[log] > [transmuxer.ts]: Flushed fragment 1 of level 4
[log] > [stream-controller]: PARSING->PARSED
[log] > ADTS sync word found !
[log] > [mp4-remuxer]: ISGenerated flag reset
[log] > [mp4-remuxer]: initPTS & initDTS reset
[log] > [mp4-remuxer]: reset next timestamp
[log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:3
[log] > parsed codec:mp4a.40.5, rate:48000, channels:2
[log] > [audio-stream-controller]: FRAG_LOADING->PARSING
[log] > [audio-stream-controller]: Init audio buffer, container:audio/mp4, codecs[level/parsed]=[mp4a.40.2/mp4a.40.5]
[log] > [buffer-controller] 0 bufferCodec event(s) expected audio
[log] > [buffer-controller] creating sourceBuffer(video/mp4;codecs=avc1.4d401f)
[log] > [buffer-controller] creating sourceBuffer(audio/mp4;codecs=mp4a.40.2)
[log] > [stream-controller]: Alternate track found, use video.buffered to schedule main fragment loading
[log] > [transmuxer.ts]: Flushed fragment 1 of level 0
[log] > [audio-stream-controller]: PARSING->PARSED
[log] > [audio-stream-controller]: Buffered audio sn: 1 of track 0 (frag:[0.000-286.848] > buffer:[0.000-286.848])
[log] > [audio-stream-controller]: PARSED->IDLE
[log] > [stream-controller]: Buffered main sn: 1 of level 4 (frag:[0.000-286.870] > buffer:[0.000-286.870])
[log] > [stream-controller]: PARSED->IDLE
[info] > [abr] switch candidate:4->6 adjustedbw(16200323)-bitrate=12628819 ttfb:0.6 avgDuration:286.9 maxFetchDuration:286.9 fetchDuration:64.1 firstSelection:false codecSet:avc1,mp4a videoRange:SDR hls.loadLevel:4
[log] > [stream-controller]: Adapting to level 6 from level 4
[log] > [level-controller]: Switching to level 6 (1080p SDR avc1,mp4a @3571504) from level 4
[log] > [level-controller]: Loading level index 6 with https://***/hls_1920x1080.m3u8
[log] > [stream-controller]: IDLE->WAITING_LEVEL
[log] > [audio-stream-controller]: Loading fragment 2 cc: 0 of [1-58] track: 0, target: 286.848
[log] > [audio-stream-controller]: IDLE->FRAG_LOADING
[log] > [stream-controller]: Level 6 loaded [1,58][part-58--1], cc [0, 0] duration:287
[log] > [stream-controller]: WAITING_LEVEL->IDLE
[log] > [audio-stream-controller]: Loaded fragment 2 of level 0
[log] > [audio-stream-controller]: FRAG_LOADING->PARSING
[log] > [transmuxer.ts]: Flushed fragment 2 of level 0
[log] > [audio-stream-controller]: PARSING->PARSED
[log] > [audio-stream-controller]: Buffered audio sn: 2 of track 0 (frag:[286.848-573.739] > buffer:[0.000-573.739])
[log] > [audio-stream-controller]: PARSED->IDLE

The video initially plays with the player showing 4:47 as the duration. At about the 2 second mark it updated to 9:33. Based on these new logs, maybe it is not be related to the last segment?

@robwalch
Copy link
Collaborator

robwalch commented Jul 10, 2024

Could there be an issue with the byte-ranges or byte-range responses on the audio? Each one appears to take up the entire duration of the media. This suggests that the client received all the audio data instead of the range pertaining to the segment requested:

[audio-stream-controller]: Buffered audio sn: 1 of track 0 (frag:[0.000-286.848] > buffer:[0.000-286.848])
[audio-stream-controller]: Buffered audio sn: 2 of track 0 (frag:[286.848-573.739] > buffer:[0.000-573.739])

@robwalch
Copy link
Collaborator

robwalch commented Jul 10, 2024

It looks like each audio segment request is coming back with a response containing the entire audio program. In v1.2 this might have just appended over itself. In v1.2.1 hls.js tries to make contiguous appends for what should be contiguous audio segments. That might be why this is seen as a regression, but it does not appear to be the fault of hls.js that the response does not contain the byte-range requested (based on offline examination of playlist and HAR files showing the byte-range requests are being made correctly).

I'll be adding some logs with #6549 to show parsed times before appending (that would have helped with logs in #6191 (comment)). I also made a branch with additional logging for byte-ranges and bytes loaded and warning when there is a discrepancy in c7e9875. I do not intend to merge or ship that as that information is available in the network tab and can be captured in HAR files. The timestamps we already have ([0.000-286.848] for a single segment) make it obvious enough that there is an issue with the media delivered.

@byumark
Copy link
Author

byumark commented Aug 1, 2024

We have concluded that this issue is not related to hls.js. When hls.js requests segments of media it uses a Range header to get the desired segments. The response should include a Content-Range header that has the same requested range. In the case of this issue, users have security software that seems to remove the Range header from audio requests.

The users seeing this double duration issue are requesting audio as expected with a Range header of a range of bytes. In their case, however, the Content-Range header on the response does not exist. The Content-Length header on the response has a value which equals the length of the entire audio file, rather than a chunk of it. HLS.js then makes that request for audio one more time and gets the same response, which causes the duration to think it is twice the duration because it is loading two full audio files.

When the security software is disabled, the issue goes away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Regression A bug introduced in a recent release Stream Issue
Projects
None yet
Development

No branches or pull requests

3 participants