Skip to content

feat(OPTIP-303): bridge inBandMetadataTrackDispatchType to React Native#833

Open
devin-ai-integration[bot] wants to merge 4 commits into
developfrom
feature/OPTIP-303-bridge-inBandMetadataTrackDispatchType
Open

feat(OPTIP-303): bridge inBandMetadataTrackDispatchType to React Native#833
devin-ai-integration[bot] wants to merge 4 commits into
developfrom
feature/OPTIP-303-bridge-inBandMetadataTrackDispatchType

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Bridge the inBandMetadataTrackDispatchType property from the native THEOplayer SDK to the React Native TextTrack API across all platforms.

TypeScript/Web — Added readonly inBandMetadataTrackDispatchType: string to the TextTrack interface. Web needs no explicit bridging (pass-through).

Android — Serialize via textTrack.inBandMetadataTrackDispatchType?.let { putString(...) } in TrackListAdapter.fromTextTrack(), following the existing captionChannel pattern.

iOS — Serialize via entry[PROP_IN_BAND_METADATA_TRACK_DISPATCH_TYPE] = textTrack.inBandMetadataTrackDispatchType in aggregatedTextTrackInfo(), following the existing forced pattern.

No type conversion needed — string on all platforms.

Add inBandMetadataTrackDispatchType property to the TextTrack TypeScript
interface and bridge it from native Android and iOS SDKs.

- TypeScript: add readonly inBandMetadataTrackDispatchType: string to TextTrack
- Android: serialize via TrackListAdapter.fromTextTrack()
- iOS: serialize via THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo()

Co-Authored-By: daniel.dallos <daniel.dallos@dolby.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

entry[PROP_TYPE] = textTrack.type
entry[PROP_SRC] = textTrack.src
entry[PROP_FORCED] = textTrack.forced
entry[PROP_IN_BAND_METADATA_TRACK_DISPATCH_TYPE] = textTrack.inBandMetadataTrackDispatchType

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This class also aggregates TextTracks from sideloaded metadata (not supported on native iOS player) which are handled by the iOS bridge (function: aggregatedMetadataAndChapterTrackInfo())

Should we also add the property there?

The iOS API is not very clear on the usage:
/** The text track in-band metadata track dispatch type of the text track that the TextTrack object represents. */

It's just a string, so what could these be?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question. I'd say noaggregatedMetadataAndChapterTrackInfo() constructs entries from TextTrackDescription (sideloaded WebVTT files), which are out-of-band by definition. inBandMetadataTrackDispatchType is specifically about metadata embedded within the stream (DASH EventStream, HLS ID3, CMAF emsg, etc.), so it wouldn't apply to sideloaded tracks — and TextTrackDescription doesn't expose this property.

As for what the values can be: it originates from the W3C MSE spec. Typical values are scheme URIs or type identifiers that disambiguate in-band metadata tracks — e.g. an EventStream schemeIdUri in DASH, or an ID3 metadata type in HLS. The native SDK passes it through as an opaque string so consumers can identify which kind of in-band metadata a track carries.

Happy to add it there too if you disagree, but I think leaving sideloaded tracks without it is correct.

@wvanhaevre wvanhaevre Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just wanted to make sure the bridging of the property works fine. It's not optional on the Typescript side.
I'm adding it to the fromNativeTextTrack TrackUtil and will set the value explicitely to "" on the metadata track aggregation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch on the non-optional TS type. Since on Android we already guard with ?.let (so the key is omitted when null), and on iOS native it can also be nil, an alternative would be to make the TS property optional: readonly inBandMetadataTrackDispatchType?: string. That would match the native nullability and avoid needing to set "" explicitly for sideloaded tracks.

Happy to make that change here if you'd prefer, or leave it as-is if you'd rather default to "" on the sideloaded path. Let me know which approach you prefer.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@Danesz what do you prefer?

Note: I think we should at least add the property to fromNativeTextTrack in TrackUtils.ts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right about TrackUtils.ts — I missed adding it to fromNativeTextTrack. The destructuring on line 44 and the return object need inBandMetadataTrackDispatchType as well. I'll add it once you and @Danesz decide on optional vs non-optional.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

On the iOS SDK the property is not nullable?

public protocol TextTrack : THEOplayerSDK.Track {
    var inBandMetadataTrackDispatchType: String { get }

On web either?

interface TextTrack extends Track, EventDispatcher<TextTrackEventMap> {
    readonly inBandMetadataTrackDispatchType: string;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right — it's non-optional on both iOS and web native SDKs. My suggestion about making it optional was wrong. Keeping it as string (non-optional) is correct, and defaulting to "" for sideloaded tracks makes sense.

I'll go ahead and add it to fromNativeTextTrack in TrackUtils.ts now.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm missing the defaulting to "" for sideloaded tracks in the commit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in d55fafbtrack[PROP_IN_BAND_METADATA_TRACK_DISPATCH_TYPE] = "" in aggregatedMetadataAndChapterTrackInfo() for sideloaded tracks.

danieldallos-dolby and others added 2 commits June 5, 2026 11:35
…tTrack in TrackUtils

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ing for sideloaded tracks

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
textTrackPayload.putBoolean(PROP_FORCED, textTrack.isForced)

// THEOplayer v10.13+
textTrack.inBandMetadataTrackDispatchType?.let { textTrackPayload.putString(PROP_IN_BAND_METADATA_TRACK_DISPATCH_TYPE, it) }

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.

maybe I'm missing something in the flow, but if this is optional here, how will it arrive on the React Native side as non-optinal empty string?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're not missing anything — this is a bug. With ?.let, when the Android SDK returns null the key is simply omitted from the payload, so it arrives as undefined on the RN side despite the TS type being non-optional string.

Fix: default to "" when null:

textTrackPayload.putString(PROP_IN_BAND_METADATA_TRACK_DISPATCH_TYPE, textTrack.inBandMetadataTrackDispatchType ?: "")

This aligns with iOS/Web where the native SDK always returns a non-null String/string. I'll push this fix once you confirm the approach (you told me to hold on committing).

…ing on Android when null

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@Danesz Danesz marked this pull request as ready for review June 5, 2026 13:53
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.

3 participants