Skip to content

Clamp Adobe Edge playhead to the accepted [0, 86400]s range - #462

Open
tvanlaerhoven wants to merge 3 commits into
bugfix/adobe-edge-session-start-racefrom
bugfix/adobe-edge-playhead-clamp
Open

Clamp Adobe Edge playhead to the accepted [0, 86400]s range#462
tvanlaerhoven wants to merge 3 commits into
bugfix/adobe-edge-session-start-racefrom
bugfix/adobe-edge-playhead-clamp

Conversation

@tvanlaerhoven

@tvanlaerhoven tvanlaerhoven commented Aug 14, 2026

Copy link
Copy Markdown
Member

Problem

On Samsung Tizen CTV, live stream playhead values sent to the Adobe VA Edge API exceed the API's valid [0, 86400] second range, causing Adobe to reject adStart/adComplete beacon calls with a 400 error:

{
  "type": "https://ns.adobe.com/aep/errors/va-edge-0400-400",
  "status": 400,
  "detail": "Invalid request. Please check your input and try again.",
  "report": { "details": "Playhead must be in range [0, 86400] seconds" }
}

Root cause

sanitisePlayhead() only special-cases duration === Infinity (live → current second of the day). On Samsung Tizen, live HLS streams report a finite duration (DVR-window length) while currentTime is an absolute/epoch-based presentation timestamp (billions of seconds). The live branch is skipped and the raw absolute timestamp is passed through Math.trunc() unclamped, straight into the playhead field that queueOrSendEvent attaches to every media event on web.

Fix

Always clamp the sanitised playhead to the [0, 86400] range accepted by the Adobe VA Edge API, in all platform implementations:

  • adobe-edge/src/internal/web/Utils.ts
  • adobe-edge/android/.../Utils.kt
  • adobe-edge/ios/Connector/AdobeEdgeHandler.swift

Note: clamping yields a wrong-but-valid playhead for platforms with broken absolute-PTS reporting; proper normalisation needs a player-side currentTime fix. The clamp guarantees Adobe accepts the beacons instead of rejecting them.

Tests

  • Added adobe-edge/src/internal/web/__tests__/utils.test.ts covering: clamping of absolute-PTS playheads, negative playheads, normal VOD truncation, live second-of-day, NaN/undefined handling.
  • Ran locally: cd adobe-edge && npm test (28/28 pass) and npm run typescript (clean). These are not covered by CI, which only runs the docs check + e2e.
  • Android/iOS changes are one-line clamps verified by inspection; no unit test infrastructure exists for the native connectors.

Notes

  • Base branch is bugfix/adobe-edge-session-start-race as this change builds on top of that PR; rebase onto main once that lands.
  • Includes a patch changeset for @theoplayer/react-native-analytics-adobe-edge.

Open in Devin Review

tvanlaerhoven and others added 3 commits August 14, 2026 13:08
On Samsung Tizen, live streams report the playhead as an absolute
presentation timestamp with a finite (DVR window) duration, so the
"live" branch of sanitisePlayhead was skipped and a value of billions
of seconds was sent to the Adobe VA Edge API, which rejects adStart/
adComplete calls with a 400 Bad Request. Always clamp the playhead to
the [0, 86400] range accepted by the API, on web, Android and iOS.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: acd2a49

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@theoplayer/react-native-analytics-adobe-edge Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

return clampPlayhead(date.getSeconds() + 60 * (date.getMinutes() + 60 * date.getHours()));
}
return Math.trunc(playheadInSec);
return clampPlayhead(Math.trunc(playheadInSec));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Clamped playhead will pin every Tizen live event at 86400

For the reported Tizen case (finite duration, absolute-PTS currentTime) every event now reports playhead 86400 and never advances, and updatePlayhead (adobe-edge/src/internal/web/AdobeEdgeHandler.ts:237) will report a value far larger than the sanitised content length (sanitiseContentLength on the DVR window). Adobe accepts the beacon but the derived viewing-time/progress metrics will be wrong; the PR acknowledges this as a stopgap, so it may be worth confirming with Adobe that a playhead exceeding the declared content length is not itself rejected or dropped downstream.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't sound correct: THEOplayer's playhead is always in seconds. For live content, the duration would be Infinite, otherwise a finite value in seconds. Retrace & explain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant