Repository navigation
feat: optional access key - #71
Merged
Merged
Conversation
jakubboguski
approved these changes
Oct 16, 2026
Public playback needs no API credentials: initialize('', libraryId)
selects playback-only mode, while management, upload, and broadcast
calls report not-initialized errors until a real key is provided.
On iOS a blank key reaches the SDK as nil, so public playback sends no
AccessKey header. On Android the bridge no longer rejects blank keys;
upstream BunnyStreamConfig still requires a non-blank key, tracked by a
TODO in BunnyStreamPlayerModule.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The example now initializes with just a library ID — an empty access key selects playback-only mode. Home gates features accordingly: direct play and resume positions need only the library ID, while library lists, uploads, and broadcasting stay gated on the API key. Settings lets the key be left empty and explains the difference. 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>
Bump the Android baseline to pull/83/head (3bd37c9), staged locally as net.bunny:*:4.2.0-pr83. The nullable BunnyStreamConfig.accessKey there means playback-only initialization now works on Android: the bridge maps a blank key to null and the upstream SDK restricts keyless instances to the public /play endpoints, failing management calls with a terminal InvalidState before any network I/O. publishToMavenLocal requires GPG signing upstream, so scripts/publish-android-sdk.mjs now builds the modules and stages unsigned AAR+POM+module metadata into ~/.m2/repository directly (including :recording, which the old script skipped). mavenLocal() is registered last in android/build.gradle so released versions still resolve from Maven Central; -PbunnyStreamSdkVersion overrides the pin. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…here
Direct live play mirrors the upstream Android demo play-a-stream-by-id
flow: a new modal on the Home screen accepts a stream ID (defaulting to
the configured library) and opens the live player without listing, which
keeps it usable in playback-only mode — public live streams resolve via
the SDK /live/{id}/play endpoint.
Also fixes token-auth signing keys leaking from .env directly: Player,
VideoList, and LiveStreams screens now sign playback tokens with the
configured (stored) access key, so a key entered via Settings is honored.
The live player getLiveStream enrichment is skipped entirely in
playback-only mode instead of logging a missing-key failure, and the
unconfigured empty-state message now says listing needs an API key.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
DirectVideoPlayModal and DirectLivePlayModal were near-identical (load last-used values, field + library inputs, cancel/confirm row). Extract the common UI and state into DirectPlayModal; the wrappers now only supply the labels, env defaults, and their own storage keys. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The key field placeholder now says it can be left empty, and the hint below it reflects the current mode: full access with a key, playback-only without one. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
key={row[0]} produced an undefined key — and the React "unique key"
warning — whenever the speeds list was short enough to leave an empty
second row.
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>
src/__tests__/example.playbackErrors.test.ts imports ACCESS_DENIED_MESSAGE and NOT_FOUND_MESSAGE via requireActual; unexporting them broke the suite. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
TenGosc007
force-pushed
the
feat/optional-access-key
branch
from
October 16, 2026 11:45
369d260 to
e071052
Compare
Bumps mavenVersion to a mavenLocal build of main@641565e (merge of #87), which composes the User-Agent as platform UA + bunny-stream-android/<ver> (<device type>) + integrator. The wrapper already forwards its version as the integrator, so requests now carry e.g. Dalvik/2.1.0 (...) bunny-stream-android/4.2.1-pr87 (mobile) bunny-stream-react-native/<ver>. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Intersect setVideoQuality overrides with the SDK's L3 rendition cap so a quality request cannot exceed what the license allows — "auto" previously wiped the cap entirely. Surface the SDK's pre-load security-level refusal as a structured onError (nativeCode ERROR_CODE_DRM_SYSTEM_ERROR) instead of only a message string, so JS can classify it as terminal. The example maps the media3 DRM error family to a "can't be played on this device" state with no retry — the hardware level cannot change. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Document the new drm/ package in ARCHITECTURE.md, describe the Widevine L3 cap and security-level refusal in the secure-playback and handle-errors guides, and note the cap intersection on the public VideoQualityPreference type. Renames the view helper to drmMaxVideoSize to mirror the SDK's naming. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
4.2.1 is now published to Maven Central (tag 08bff6a) and already contains the PR #87 User-Agent format and PR #88 Widevine L3 handling, so the local 4.2.1-pr88 mavenLocal pin is no longer needed. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
initialize(accessKey, libraryId)no longer requires a non-empty API accesskey — public playback needs no credentials. Passing a blank key (or
null/undefined) selects playback-only mode on both platforms:management, upload, and broadcast calls report not-initialized errors until
a real key is provided.
On iOS a blank key reaches the SDK as
nil, so public playback sends noAccessKeyheader. On Android the bridge no longer rejects blank keys —upstream
BunnyStreamConfigstill requires a non-blank key (tracked by aTODO in
BunnyStreamPlayerModule), so Android keyless playback unblocksautomatically with a future native SDK release.
The example app gates features accordingly: Direct video play and resume
positions work with just a library ID, while library lists, uploads, and
broadcasting stay gated on the API key. Docs updated to describe the
playback-only mode.
Type of Change
Affected Areas
Testing
yarn typecheckyarn lintyarn test— 261 tests incl. new keyless-initialization andplayback-only example tests
yarn androidinexample/) —:bunny.net_stream-react-native:assembleReleaseyarn iosinexample/)swiftc -parseon changed files andupstream SDK source review; manual playback verification pending on
device.
Library User Impact
Public API change:
initializeacceptsstring | null | undefinedforaccessKey(previouslystring, blank values threw). A blank key selectsplayback-only mode —
BunnyStreamApi,BunnyStreamUpload, andBunnyStreamBroadcasterreport not-initialized errors until a real key isprovided. Fully backward compatible: existing callers with a real key see
no behavior change.
Platform note: iOS keyless playback works today; Android keyless playback
is unblocked at the bridge but still requires an upstream
bunny-stream-androidchange (BunnyStreamConfigrejects blank keys) —documented via a TODO in
BunnyStreamPlayerModule.kt.AI Assistance
Checklist
native-sdk-baselines.jsonpoints to a public, merged native SDK commit or tag when native APIs are required.