Skip to content

Commit

Permalink
Merge pull request #421 from bitmovin/release/v0.20.0
Browse files Browse the repository at this point in the history
Release 0.20.0
  • Loading branch information
dweinber authored Mar 29, 2024
2 parents 9fa82be + 4261c26 commit 6cd6cdd
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 777 deletions.
4 changes: 0 additions & 4 deletions .husky/commit-msg

This file was deleted.

11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [0.20.0]

### Added

- `preferSoftwareDecodingForAds` in `TweaksConfig` to use software decoding for ads, which can be useful for low-end Android devices
- `hideFirstFrame` in `PlayerViewConfig` to ensure no frame of the main content is shown before pre-roll ads

### Changed

- Update Bitmovin's native Android SDK version to `3.64.0`

## [0.19.0] (2024-03-22)

### Added
Expand Down
13 changes: 0 additions & 13 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,6 @@ export default (spec: TestScope) => {
};
```

## Commit message convention

We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages:

- `fix`: bug fixes, e.g. fix crash due to deprecated method.
- `feat`: new features, e.g. add new method to the module.
- `refactor`: code refactor, e.g. migrate from class components to hooks.
- `docs`: changes into documentation, e.g. add usage example for the module..
- `test`: adding or updating tests, e.g. add integration tests using detox.
- `chore`: tooling changes, e.g. change CI config.

Our pre-commit hooks verify that your commit message matches this format when committing.

## Scripts

The `package.json` file contains various scripts for common tasks:
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,5 @@ dependencies {
// Bitmovin
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.31.0'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.bitmovin.player:player:3.63.0+jason'
implementation 'com.bitmovin.player:player:3.64.0+jason'
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ fun ReadableMap.toTweaksConfig(): TweaksConfig = TweaksConfig().apply {
withBoolean("useDrmSessionForClearPeriods") { useDrmSessionForClearPeriods = it }
withBoolean("useDrmSessionForClearSources") { useDrmSessionForClearSources = it }
withBoolean("useFiletypeExtractorFallbackForHls") { useFiletypeExtractorFallbackForHls = it }
withBoolean("preferSoftwareDecodingForAds") { preferSoftwareDecodingForAds = it }
}

/**
Expand Down Expand Up @@ -750,6 +751,7 @@ fun toPlayerViewConfig(json: ReadableMap) = PlayerViewConfig(
?.getBooleanOrNull("playbackSpeedSelectionEnabled")
?: true,
),
hideFirstFrame = json.getBooleanOrNull("hideFirstFrame") ?: false,
)

private fun ReadableMap.toUserInterfaceTypeFromPlayerConfig(): UserInterfaceType? =
Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ PODS:
- React-jsi (= 0.73.4-0)
- React-logger (= 0.73.4-0)
- React-perflogger (= 0.73.4-0)
- RNBitmovinPlayer (0.19.0):
- RNBitmovinPlayer (0.20.0):
- BitmovinPlayer (= 3.57.2)
- GoogleAds-IMA-iOS-SDK (= 3.18.4)
- GoogleAds-IMA-tvOS-SDK (= 4.8.2)
Expand Down Expand Up @@ -1305,7 +1305,7 @@ SPEC CHECKSUMS:
React-runtimescheduler: 20b2202e3396589a71069d12ae9f328949c7c7b8
React-utils: 0307d396f233e47a167b5aaf045b0e4e1dc19d74
ReactCommon: 17891ca337bfa5a7263649b09f27a8c664537bf2
RNBitmovinPlayer: e071744c1452eaa7b70fd119aece83014d83e897
RNBitmovinPlayer: 18f672d24fb8cc967f46a3dec36f034dbe0efe5b
RNCPicker: b18aaf30df596e9b1738e7c1f9ee55402a229dca
RNScreens: b582cb834dc4133307562e930e8fa914b8c04ef2
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Expand Down
6 changes: 6 additions & 0 deletions example/src/screens/BasicAds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
SourceType,
AdSourceType,
AdSkippedEvent,
PlayerViewConfig,
} from 'bitmovin-player-react-native';
import { useTVGestures } from '../hooks';

Expand Down Expand Up @@ -58,6 +59,10 @@ const remoteControlConfig = {
isCastEnabled: false,
};

const playerViewConfig: PlayerViewConfig = {
hideFirstFrame: true,
};

export default function BasicAds() {
useTVGestures();

Expand Down Expand Up @@ -126,6 +131,7 @@ export default function BasicAds() {
<PlayerView
player={player}
style={styles.player}
config={playerViewConfig}
onAdBreakFinished={onEvent}
onAdBreakStarted={onEvent}
onAdClicked={onEvent}
Expand Down
12 changes: 11 additions & 1 deletion ios/RCTConvert+BitmovinPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,8 @@ extension RCTConvert {

return RNPlayerViewConfig(
uiConfig: rnUiConfig(json["uiConfig"]),
pictureInPictureConfig: pictureInPictureConfig(json["pictureInPictureConfig"])
pictureInPictureConfig: pictureInPictureConfig(json["pictureInPictureConfig"]),
hideFirstFrame: json["hideFirstFrame"] as? Bool
)
}

Expand Down Expand Up @@ -1256,6 +1257,15 @@ internal struct RNPlayerViewConfig {
}
return config
}

/**
* When set to `true` the first frame of the main content will not be rendered before playback starts.
* Default is `false`.
*
* To reliably hide the first frame before a pre-roll ad, please ensure that you are using the
* `AdvertisingConfig` to schedule ads and not the `scheduleAd` API call.
*/
var hideFirstFrame: Bool?
}

/**
Expand Down
64 changes: 46 additions & 18 deletions ios/RNPlayerViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,13 @@ public class RNPlayerViewManager: RCTViewManager {
return
}
let playerViewConfig = RCTConvert.rnPlayerViewConfig(view.config)
#if os(iOS)
if player.config.styleConfig.userInterfaceType == .bitmovin {
let bitmovinUserInterfaceConfig = player
.config
.styleConfig
.userInterfaceConfig as? BitmovinUserInterfaceConfig ?? BitmovinUserInterfaceConfig()
player.config.styleConfig.userInterfaceConfig = bitmovinUserInterfaceConfig
if let uiConfig = playerViewConfig?.uiConfig {
bitmovinUserInterfaceConfig
.playbackSpeedSelectionEnabled = uiConfig.playbackSpeedSelectionEnabled
}

if let customMessageHandlerBridgeId = self.customMessageHandlerBridgeId,
let customMessageHandlerBridge = self.bridge[CustomMessageHandlerModule.self]?
.retrieve(customMessageHandlerBridgeId) {
bitmovinUserInterfaceConfig.customMessageHandler = customMessageHandlerBridge.customMessageHandler
}

if let userInterfaceConfig = maybeCreateUserInterfaceConfig(
styleConfig: player.config.styleConfig,
playerViewConfig: playerViewConfig
) {
player.config.styleConfig.userInterfaceConfig = userInterfaceConfig
}
#endif

let previousPictureInPictureAvailableValue: Bool
if let playerView = view.playerView {
Expand All @@ -74,6 +62,46 @@ public class RNPlayerViewManager: RCTViewManager {
}
}

private func maybeCreateUserInterfaceConfig(
styleConfig: StyleConfig,
playerViewConfig: RNPlayerViewConfig?
) -> UserInterfaceConfig? {
#if os(iOS)
if styleConfig.userInterfaceType == .bitmovin {
let bitmovinUserInterfaceConfig = styleConfig
.userInterfaceConfig as? BitmovinUserInterfaceConfig ?? BitmovinUserInterfaceConfig()

if let uiConfig = playerViewConfig?.uiConfig {
bitmovinUserInterfaceConfig
.playbackSpeedSelectionEnabled = uiConfig.playbackSpeedSelectionEnabled
}
if let hideFirstFrame = playerViewConfig?.hideFirstFrame {
bitmovinUserInterfaceConfig.hideFirstFrame = hideFirstFrame
}

if let customMessageHandlerBridgeId = self.customMessageHandlerBridgeId,
let customMessageHandlerBridge = self.bridge[CustomMessageHandlerModule.self]?
.retrieve(customMessageHandlerBridgeId) {
bitmovinUserInterfaceConfig.customMessageHandler = customMessageHandlerBridge.customMessageHandler
}

return bitmovinUserInterfaceConfig
}
#endif
if styleConfig.userInterfaceType == .system {
let systemUserInterfaceConfig = styleConfig
.userInterfaceConfig as? SystemUserInterfaceConfig ?? SystemUserInterfaceConfig()

if let hideFirstFrame = playerViewConfig?.hideFirstFrame {
systemUserInterfaceConfig.hideFirstFrame = hideFirstFrame
}

return systemUserInterfaceConfig
}

return nil
}

@objc
func attachFullscreenBridge(_ viewId: NSNumber, fullscreenBridgeId: NativeId) {
bridge.uiManager.addUIBlock { [weak self] _, views in
Expand Down
9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bitmovin-player-react-native",
"version": "0.19.0",
"version": "0.20.0",
"description": "Official React Native bindings for Bitmovin's mobile Player SDKs.",
"main": "lib/index.js",
"module": "lib/index.mjs",
Expand Down Expand Up @@ -59,14 +59,12 @@
"@babel/core": "7.22.10",
"@babel/preset-env": "7.22.10",
"@babel/runtime": "7.22.10",
"@commitlint/config-conventional": "17.7.0",
"@react-native-community/eslint-config": "3.1.0",
"@react-native/babel-preset": "0.73.18",
"@types/jest": "^28.1.2",
"@types/lodash.omit": "4.5.0",
"@types/react": "~18.2.26",
"babel-plugin-module-resolver": "5.0.0",
"commitlint": "17.7.1",
"eslint": "8.24.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "4.2.1",
Expand All @@ -92,11 +90,6 @@
"react": ">=17",
"react-native": ">=0.65"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"lint-staged": {
"*.(ts|tsx)": "eslint",
"*.(ts|tsx|js|jsx|md|json|yml|yaml)": "prettier --write"
Expand Down
8 changes: 8 additions & 0 deletions src/components/PlayerView/playerViewConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ export interface PlayerViewConfig {
* Provides options to configure Picture in Picture playback.
*/
pictureInPictureConfig?: PictureInPictureConfig;

/**
* When set to `true`, the first frame of the main content will not be rendered before playback starts. Default is `false`.
* This configuration has no effect for the {@link UserInterfaceType.Subtitle} on iOS/tvOS.
*
* To reliably hide the first frame before a pre-roll ad, please ensure that you are using the {@link AdvertisingConfig} to schedule ads and not the {@link Player.scheduleAd} API call.
*/
hideFirstFrame?: boolean;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/tweaksConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,11 @@ export interface TweaksConfig {
* @platform Android
*/
useFiletypeExtractorFallbackForHls?: boolean;
/**
* Specifies whether the player should prefer software decoding over hardware decoding for ad playback.
* This only affects ads playback, the player will still prefer hardware decoding for the main content.
*
* @platform Android
*/
preferSoftwareDecodingForAds?: boolean;
}
Loading

0 comments on commit 6cd6cdd

Please sign in to comment.