From dba50c27635f7cf96b731e32ee4a4be62131248d Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 15:14:13 +0200 Subject: [PATCH 01/15] feat(bufferapi): add bufferApi types --- src/bufferConfig.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/bufferConfig.ts diff --git a/src/bufferConfig.ts b/src/bufferConfig.ts new file mode 100644 index 00000000..413dd334 --- /dev/null +++ b/src/bufferConfig.ts @@ -0,0 +1,50 @@ +/** Represents different types of media. */ +export enum MediaType { + /** Combined audio and video media type. */ + MEDIATYPE_AUDIO_AND_VIDEO, +} + +/** Represents different types of buffered data. */ +export enum BufferType { + /** Represents the buffered data starting at the current playback time. */ + FORWARD_DURATION, + /** Represents the buffered data up until the current playback time. */ + BACKWARD_DURATION, +} + +/** Holds different information about the buffer levels. */ +export interface BufferLevel { + /** The amount of currently buffered data, e.g. audio or video buffer level. */ + level?: number; + /** The target buffer level the player tries to maintain. */ + targetLevel?: number; + /** The media type the buffer data applies to. */ + media?: MediaType; + /** The buffer type the buffer data applies to. */ + type?: BufferType; +} + +/** + * Configures buffer target levels for different MediaTypes. + */ +export interface BufferMediaTypeConfig { + /** + * The amount of data in seconds the player tries to buffer in advance. If set to 0, the player will + * choose an appropriate forward buffer duration suitable for most use-cases. + * + * Default value is `0`. + * + * TODO: update docs here + */ + forwardDuration?: number; +} + +/** + * Player buffer config object to configure buffering behavior. + */ +export interface BufferConfig { + /** + * Configures various settings for the audio and video buffer. + */ + audioAndVideo?: BufferMediaTypeConfig; +} From 0f840eca59ef0a1bad993500694f87d8773a0d27 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 15:25:57 +0200 Subject: [PATCH 02/15] feat(bufferapi): extend PlayerConfig with bufferConfig --- src/player.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/player.ts b/src/player.ts index a4292b12..a3c94748 100644 --- a/src/player.ts +++ b/src/player.ts @@ -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; @@ -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; } /** From e0aa0c6dae9bf6524a3fb2cff42bb743fec460ce Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 15:26:42 +0200 Subject: [PATCH 03/15] feat(docs): add jsdoc links to mentioned objects inside PlayerConfig --- src/player.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/player.ts b/src/player.ts index a3c94748..dc73f5cc 100644 --- a/src/player.ts +++ b/src/player.ts @@ -40,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; /** From 8347db07c85d9e84cc08f7d12f6da53572403c34 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 16:42:43 +0200 Subject: [PATCH 04/15] feat(bufferapi): add BufferConfig and BufferMediaTypeConfig to kt converter --- .../reactnative/converter/JsonConverter.kt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt b/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt index 2372a74b..486c6bba 100644 --- a/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +++ b/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt @@ -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 @@ -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]. * From 94b08722617c31328f4593dff2b7cf83b35b7039 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 16:43:27 +0200 Subject: [PATCH 05/15] feat(bufferapi): update BufferConfig.ts with Android only properties --- src/bufferConfig.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/bufferConfig.ts b/src/bufferConfig.ts index 413dd334..9b9b0208 100644 --- a/src/bufferConfig.ts +++ b/src/bufferConfig.ts @@ -47,4 +47,22 @@ 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; } From 45ac7526fda8c63b3b24a8c71997c2d1cbe475d1 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 17:14:15 +0200 Subject: [PATCH 06/15] feat(bufferapi): add BufferConfig and BufferMediaTypeConfig to swift converter --- ios/RCTConvert+BitmovinPlayer.swift | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ios/RCTConvert+BitmovinPlayer.swift b/ios/RCTConvert+BitmovinPlayer.swift index 5e763c79..6ad84e87 100644 --- a/ios/RCTConvert+BitmovinPlayer.swift +++ b/ios/RCTConvert+BitmovinPlayer.swift @@ -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 @@ -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. From f90694cfe84247639e4c82f9db3041cf1640ee27 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Mon, 16 Oct 2023 17:34:22 +0200 Subject: [PATCH 07/15] feat(bufferapi): export bufferConfig --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 67e942a4..0c8fcba1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,3 +18,4 @@ export * from './bitmovinCastManager'; export * from './audioTrack'; export * from './media'; export * from './tweaksConfig'; +export * from './bufferConfig'; From 2190ffdc9e356c5ef3e9847e67b758c3f718223e Mon Sep 17 00:00:00 2001 From: Roland Kakonyi Date: Mon, 16 Oct 2023 22:30:35 +0200 Subject: [PATCH 08/15] feat(swiftlintci): run SwiftLint on CI to validate changes --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c160338..cab851ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,26 @@ concurrency: cancel-in-progress: true jobs: + code-style-typescript: + name: Code style Typescript + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@4 + + - name: Setup node and npm registry + uses: actions/setup-node@v3 + with: + node-version: '16' + registry-url: 'https://registry.npmjs.org/' + cache: 'yarn' + + - name: Install node_modules + run: yarn install --frozen-lockfile + + - name: Lint Typescript + run: yarn lint + code-style-android: name: Code style Android runs-on: ubuntu-latest @@ -37,6 +57,23 @@ jobs: run: ./gradlew ktlintCheck working-directory: android + code-style-ios: + name: Code style iOS + runs-on: macOS-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '14.1' + + - name: Install dependencies + run: brew bundle install + + - name: Check code style + run: swiftlint --strict + test-build-typescript: name: Build Typescript runs-on: ubuntu-latest From 794fe7b7faf1a3284163cbade2754de4418ce295 Mon Sep 17 00:00:00 2001 From: Roland Kakonyi Date: Mon, 16 Oct 2023 22:32:11 +0200 Subject: [PATCH 09/15] feat(swiftlintci): fix action path --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cab851ce..304284f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@4 + uses: actions/checkout@v4 - name: Setup node and npm registry uses: actions/setup-node@v3 From a12f2bb0373c7a64b81cca354c8ee77d657b03c0 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Tue, 17 Oct 2023 09:43:56 +0200 Subject: [PATCH 10/15] feat(CHANGELOG): add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14c5c864..9b28b5cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 +- `MediaType`, `BufferType`, `BufferLevel`, `BufferMediaTypeConfig`, `BufferConfig` to have types and interfaces necessary for incoming `BufferAPI` ### Changed From fd6f38c042a6deb5c0bf517b79bc5d57eaaebd13 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Tue, 17 Oct 2023 10:20:06 +0200 Subject: [PATCH 11/15] feat(bufferapi): update docs on `BufferMediaTypeConfig.forwardDuration` --- src/bufferConfig.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bufferConfig.ts b/src/bufferConfig.ts index 9b9b0208..99f9d30e 100644 --- a/src/bufferConfig.ts +++ b/src/bufferConfig.ts @@ -29,12 +29,12 @@ export interface BufferLevel { */ export interface BufferMediaTypeConfig { /** - * The amount of data in seconds the player tries to buffer in advance. If set to 0, the player will - * choose an appropriate forward buffer duration suitable for most use-cases. + * The amount of data in seconds the player tries to buffer in advance. * - * Default value is `0`. + * iOS only: If set to `0`, the player will choose an appropriate forward buffer duration suitable + * for most use-cases. * - * TODO: update docs here + * Default value is `0` on iOS, `50` on Android */ forwardDuration?: number; } From 33def97c1050707855fb6a34de0e430014fbc0b9 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <123.mpozzi@gmail.com> Date: Tue, 17 Oct 2023 10:26:42 +0200 Subject: [PATCH 12/15] feat(bufferapi): remove `MediaType`, `BufferType`, `BufferLevel` They will be put in next PR --- src/bufferConfig.ts | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/bufferConfig.ts b/src/bufferConfig.ts index 99f9d30e..e185bd41 100644 --- a/src/bufferConfig.ts +++ b/src/bufferConfig.ts @@ -1,29 +1,3 @@ -/** Represents different types of media. */ -export enum MediaType { - /** Combined audio and video media type. */ - MEDIATYPE_AUDIO_AND_VIDEO, -} - -/** Represents different types of buffered data. */ -export enum BufferType { - /** Represents the buffered data starting at the current playback time. */ - FORWARD_DURATION, - /** Represents the buffered data up until the current playback time. */ - BACKWARD_DURATION, -} - -/** Holds different information about the buffer levels. */ -export interface BufferLevel { - /** The amount of currently buffered data, e.g. audio or video buffer level. */ - level?: number; - /** The target buffer level the player tries to maintain. */ - targetLevel?: number; - /** The media type the buffer data applies to. */ - media?: MediaType; - /** The buffer type the buffer data applies to. */ - type?: BufferType; -} - /** * Configures buffer target levels for different MediaTypes. */ From 47c19d917f565d6cfbe156e00817644731fa972f Mon Sep 17 00:00:00 2001 From: Michele Pozzi <96702967+123mpozzi@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:32:05 +0200 Subject: [PATCH 13/15] feat(CHANGELOG): Update CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roland Kákonyi --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b28b5cd..7e4a0aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +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 -- `MediaType`, `BufferType`, `BufferLevel`, `BufferMediaTypeConfig`, `BufferConfig` to have types and interfaces necessary for incoming `BufferAPI` +- `BufferConfig` to control player buffer depth ### Changed From 6ef8afa7bb1e02b7a4cfbdb1184fb4e9814643e4 Mon Sep 17 00:00:00 2001 From: Michele Pozzi <96702967+123mpozzi@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:34:14 +0200 Subject: [PATCH 14/15] feat(bufferapi): update doc on `PlayerConfig.bufferConfig` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roland Kákonyi --- src/player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player.ts b/src/player.ts index dc73f5cc..7455342e 100644 --- a/src/player.ts +++ b/src/player.ts @@ -68,7 +68,7 @@ export interface PlayerConfig extends NativeInstanceConfig { */ remoteControlConfig?: RemoteControlConfig; /** - * Configures buffer settings. A default {@link BufferConfig} is set initially + * Configures buffer settings. A default {@link BufferConfig} is set initially. */ bufferConfig?: BufferConfig; } From de059bc045a9a832462b5ed2c96e0fa753b93855 Mon Sep 17 00:00:00 2001 From: Roland Kakonyi Date: Tue, 17 Oct 2023 11:22:46 +0200 Subject: [PATCH 15/15] feat(swiftlintci): run brew bundle install on CI --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 304284f2..3e64609e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -179,6 +179,9 @@ jobs: - name: Install node_modules (example/) run: yarn install --frozen-lockfile --cwd example + - name: Install dependencies + run: brew bundle install + - name: Restore Pods cache id: pods-cache-restore uses: actions/cache/restore@v3 @@ -238,6 +241,9 @@ jobs: - name: Install node_modules (example/) run: yarn install --frozen-lockfile --cwd example + - name: Install dependencies + run: brew bundle install + - name: Restore Pods cache id: pods-cache-restore uses: actions/cache/restore@v3