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

Implement BufferAPI: BufferConfig #291

Merged
merged 12 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- `PictureInPictureConfig` to `PlayerView` to allow configuring the Picture in Picture behavior
- `PictureInPictureConfig.shouldEnterOnBackground` to start PiP automatically when the app transitions to background
- `onPictureInPictureAvailabilityChanged` event is now emitted on iOS and tvOS in addition to Android
- `BufferConfig` to control player buffer depth

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import com.bitmovin.player.api.advertising.AdQuartile
import com.bitmovin.player.api.advertising.AdSource
import com.bitmovin.player.api.advertising.AdSourceType
import com.bitmovin.player.api.advertising.AdvertisingConfig
import com.bitmovin.player.api.buffer.BufferConfig
import com.bitmovin.player.api.buffer.BufferMediaTypeConfig
import com.bitmovin.player.api.casting.RemoteControlConfig
import com.bitmovin.player.api.drm.WidevineConfig
import com.bitmovin.player.api.event.PlayerEvent
Expand Down Expand Up @@ -106,9 +108,56 @@ class JsonConverter {
playerConfig.remoteControlConfig = it
}
}
if (json.hasKey("bufferConfig")) {
toBufferConfig(json.getMap("bufferConfig"))?.let {
playerConfig.bufferConfig = it
}
}
return playerConfig
}

/**
* Converts any JS object into a `BufferMediaTypeConfig` object.
* @param json JS object representing the `BufferMediaTypeConfig`.
* @return The generated `BufferMediaTypeConfig` if successful, `null` otherwise.
*/
@JvmStatic
fun toBufferMediaTypeConfig(json: ReadableMap?): BufferMediaTypeConfig? {
if (json == null) {
return null
}
val bufferMediaTypeConfig = BufferMediaTypeConfig()
if (json.hasKey("forwardDuration")) {
bufferMediaTypeConfig.forwardDuration = json.getDouble("forwardDuration")
}
return bufferMediaTypeConfig
}

/**
* Converts any JS object into a `BufferConfig` object.
* @param json JS object representing the `BufferConfig`.
* @return The generated `BufferConfig` if successful, `null` otherwise.
*/
@JvmStatic
fun toBufferConfig(json: ReadableMap?): BufferConfig? {
if (json == null) {
return null
}
val bufferConfig = BufferConfig()
if (json.hasKey("audioAndVideo")) {
toBufferMediaTypeConfig(json.getMap("audioAndVideo"))?.let {
bufferConfig.audioAndVideo = it
}
}
if (json.hasKey("restartThreshold")) {
bufferConfig.restartThreshold = json.getDouble("restartThreshold")
}
if (json.hasKey("startupThreshold")) {
bufferConfig.startupThreshold = json.getDouble("startupThreshold")
}
return bufferConfig
}

/**
* Converts an arbitrary [ReadableMap] to a [RemoteControlConfig].
*
Expand Down
35 changes: 35 additions & 0 deletions ios/RCTConvert+BitmovinPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ extension RCTConvert {
if let adaptationConfig = RCTConvert.adaptationConfig(json["adaptationConfig"]) {
playerConfig.adaptationConfig = adaptationConfig
}
if let bufferConfig = RCTConvert.bufferConfig(json["bufferConfig"]) {
playerConfig.bufferConfig = bufferConfig
}
#if os(iOS)
if let remoteControlConfig = RCTConvert.remoteControlConfig(json["remoteControlConfig"]) {
playerConfig.remoteControlConfig = remoteControlConfig
Expand Down Expand Up @@ -155,6 +158,38 @@ extension RCTConvert {
return tweaksConfig
}

/**
Utility method to instantiate a `BufferMediaTypeConfig` from a JS object.
- Parameter json: JS object.
- Returns: The produced `BufferMediaTypeConfig` object.
*/
static func bufferMediaTypeConfig(_ json: Any?) -> BufferMediaTypeConfig? {
guard let json = json as? [String: Any?] else {
return nil
}
let bufferMediaTypeConfig = BufferMediaTypeConfig()
if let forwardDuration = json["forwardDuration"] as? NSNumber {
bufferMediaTypeConfig.forwardDuration = forwardDuration.doubleValue
}
return bufferMediaTypeConfig
}

/**
Utility method to instantiate a `BufferConfig` from a JS object.
- Parameter json: JS object.
- Returns: The produced `BufferConfig` object.
*/
static func bufferConfig(_ json: Any?) -> BufferConfig? {
guard let json = json as? [String: Any?] else {
return nil
}
let bufferConfig = BufferConfig()
if let bufferMediaTypeConfig = bufferMediaTypeConfig(json["audioAndVideo"]) {
bufferConfig.audioAndVideo = bufferMediaTypeConfig
}
return bufferConfig
}

/**
Utility method to instantiate an `AdvertisingConfig` from a JS object.
- Parameter json: JS object.
Expand Down
42 changes: 42 additions & 0 deletions src/bufferConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Configures buffer target levels for different MediaTypes.
*/
export interface BufferMediaTypeConfig {
/**
* The amount of data in seconds the player tries to buffer in advance.
*
* iOS only: If set to `0`, the player will choose an appropriate forward buffer duration suitable
* for most use-cases.
*
* Default value is `0` on iOS, `50` on Android
*/
forwardDuration?: number;
}

/**
* Player buffer config object to configure buffering behavior.
*/
export interface BufferConfig {
/**
* Configures various settings for the audio and video buffer.
*/
audioAndVideo?: BufferMediaTypeConfig;
/**
* Amount of seconds the player buffers before playback starts again after a stall. This value is
* restricted to the maximum value of the buffer minus 0.5 seconds.
*
* Default is `5` seconds.
*
* @platform Android
*/
restartThreshold?: number;
/**
* Amount of seconds the player buffers before playback starts. This value is restricted to the
* maximum value of the buffer minus 0.5 seconds.
*
* Default is `2.5` seconds.
*
* @platform Android
*/
startupThreshold?: number;
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from './bitmovinCastManager';
export * from './audioTrack';
export * from './media';
export * from './tweaksConfig';
export * from './bufferConfig';
13 changes: 9 additions & 4 deletions src/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { OfflineContentManager, OfflineSourceOptions } from './offline';
import { Thumbnail } from './thumbnail';
import { AnalyticsApi } from './analytics/player';
import { RemoteControlConfig } from './remoteControlConfig';
import { BufferConfig } from './bufferConfig';

const PlayerModule = NativeModules.PlayerModule;

Expand Down Expand Up @@ -39,19 +40,19 @@ export interface PlayerConfig extends NativeInstanceConfig {
*/
licenseKey?: string;
/**
* Configures playback behaviour. A default PlaybackConfig is set initially.
* Configures playback behaviour. A default {@link PlaybackConfig} is set initially.
*/
playbackConfig?: PlaybackConfig;
/**
* Configures the visual presentation and behaviour of the player UI. A default StyleConfig is set initially.
* Configures the visual presentation and behaviour of the player UI. A default {@link StyleConfig} is set initially.
*/
styleConfig?: StyleConfig;
/**
* Configures advertising functionality. A default AdvertisingConfig is set initially.
* Configures advertising functionality. A default {@link AdvertisingConfig} is set initially.
*/
advertisingConfig?: AdvertisingConfig;
/**
* Configures experimental features. A default TweaksConfig is set initially.
* Configures experimental features. A default {@link TweaksConfig} is set initially.
*/
tweaksConfig?: TweaksConfig;
/**
Expand All @@ -66,6 +67,10 @@ export interface PlayerConfig extends NativeInstanceConfig {
* Configures remote playback functionality.
*/
remoteControlConfig?: RemoteControlConfig;
/**
* Configures buffer settings. A default {@link BufferConfig} is set initially.
*/
bufferConfig?: BufferConfig;
}

/**
Expand Down