Skip to content

Conversation

@FineFindus
Copy link
Collaborator

Implements support for streaming using SABR. This is achieved by leveraging a native rust binary that implements the fetching, parsing the UMP stream and extracting the actual media data.

The integration with exoplayer is still very early (read: it does not work yet), though Rust implementation is fully-capable. Help writing the exoplayer integration is appreciated :)

Open issues

  • due to the reliance on Tokio, the ends up being quite large (~100 MB for debug and currently ~5 for release)
  • this requires additional patches to NewPipeExtractor to extract the necessary metadata (I would like to avoid carrying these forward in our fork)

@Jeidnx
Copy link

Jeidnx commented Sep 18, 2025

This looks very interesting. I am particularly interested in the rust side, it seems the repository for that is private though?

@FineFindus
Copy link
Collaborator Author

This looks very interesting. I am particularly interested in the rust side, it seems the repository for that is private though?

Thanks for your interest. I left it as private, as I'm unsure what license to use for it (I was leaning towards GPLv3, but that would make it impossible to use by other non-GPLv3 Rust crates). In any case, the code has now been ported to Kotlin and is included here.

Implements the basic infrastrucutre needed to setup a new streaming protocol.
This involves creating a media source, which then creates a media periods,
which manages the individual streaming tracks.
Adds the required classes that are needed to create and handle chunked sample
streams.
Adds the necessary infrastructure and files to generate the protobuf classes
used for SABR streaming. This includes a dependency on protoc (the protobuf
compiler), as well as the libraries for Java/Kotlin protobuf interaction.
Ports the SABR streaming client from Rust to Kotlin.
This avoids a round-trip to the native layer for each request, as well as the
additional caching layer, at the cost of worse memory-management and usage.
This helps to ensure that there is ever only one instance of the client,
avoiding concurrency issues when accessing the object from multiple threads,
which the player does.
Disables using SABR if the media is currently being live-streamed, as the
current implementation does not support live-streams and the server still sends
DASH and HLS manifests.
Instead of handling multiple segments for each chunk, we only handle a single
segment. This avoids another memcopy of the data into a `ByteBuffer`.
Implements support for discontinuous playback, i.e. starting the media at
different time or seeking during playback.
The server only provides a certain number of segments in advance, so instead of
using the playback position, we pretend we're directly at the segment boundary
when requesting new segments. This may have some drawbacks, as the server may
send lower-quality segments.
Notifies the server about the time in milliseconds that has passed between two
requests.
The `poToken` is generated by the SabrClient, when needed.
Fixes an issue with playback of some formats, as the extracted xtags where not
passed from the extractor to the sabr client. This caused some streams to fail
with `sabr.no_audio_selected (0)` as the client did not set the correct
properties.
@Figim

This comment was marked as off-topic.

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