diff --git a/.github/workflows/ci-ios-tvos.yml b/.github/workflows/ci-ios-tvos.yml index ad9ba65e..8016f762 100644 --- a/.github/workflows/ci-ios-tvos.yml +++ b/.github/workflows/ci-ios-tvos.yml @@ -78,9 +78,7 @@ jobs: restore-keys: pods- - name: Install pods - run: | - pod repo add bitmovin https://github.com/bitmovin/cocoapod-specs.git || pod repo update bitmovin - yarn pods + run: yarn pods env: CP_HOME_DIR: ${{ github.workspace }}/.cocoapods-cache @@ -131,9 +129,7 @@ jobs: restore-keys: pods- - name: Install pods - run: | - pod repo add bitmovin https://github.com/bitmovin/cocoapod-specs.git || pod repo update bitmovin - yarn example pods + run: yarn example pods env: CP_HOME_DIR: ${{ github.workspace }}/.cocoapods-cache diff --git a/.github/workflows/create-sdk-update-pr.yml b/.github/workflows/create-sdk-update-pr.yml index 0aac4863..bfd3e9d8 100644 --- a/.github/workflows/create-sdk-update-pr.yml +++ b/.github/workflows/create-sdk-update-pr.yml @@ -66,7 +66,6 @@ jobs: if: ${{ inputs.sdk_name == 'ios' }} run: | sed -i '' 's/s.dependency "BitmovinPlayer", ".*/s.dependency "BitmovinPlayer", "${{ inputs.version_number }}"/g' RNBitmovinPlayer.podspec - pod repo add bitmovin https://github.com/bitmovin/cocoapod-specs.git yarn bootstrap - name: Save Pods cache diff --git a/.github/workflows/start-release-train.yml b/.github/workflows/start-release-train.yml index d4d66d13..45ba362b 100644 --- a/.github/workflows/start-release-train.yml +++ b/.github/workflows/start-release-train.yml @@ -77,13 +77,6 @@ jobs: run: | yarn version --new-version ${{ inputs.version_number }} --no-git-tag-version - - name: Set up CocoaPods - run: | - pod repo add bitmovin https://github.com/bitmovin/cocoapod-specs.git || pod repo update bitmovin - working-directory: example/ios - env: - CP_HOME_DIR: ${{ github.workspace }}/.cocoapods-cache - - name: Install pods to update Podfile.lock run: | yarn bootstrap diff --git a/CHANGELOG.md b/CHANGELOG.md index e9023c68..62a4ed8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [0.30.0] - 2024-10-31 ### Added @@ -9,7 +9,16 @@ ### Changed -- Update Bitmovin's native Android SDK version to `3.84.0` +- Update Bitmovin's native Android SDK version to `3.90.0` +- Update Bitmovin's native iOS SDK version to `3.77.0` + +### Added + +- `WebUiConfig.variant` to set the UI variant that should be used by the Bitmovin Web UI + +### Fixed + +- Spatial navigation in the Web UI does not work properly ### Deprecated diff --git a/RNBitmovinPlayer.podspec b/RNBitmovinPlayer.podspec index c2dd1410..e95c6c06 100644 --- a/RNBitmovinPlayer.podspec +++ b/RNBitmovinPlayer.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.swift_version = "5.10" s.dependency "React-Core" - s.dependency "BitmovinPlayer", "3.74.0" + s.dependency "BitmovinPlayer", "3.77.0" s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.23.0" s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.13.0" end 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 1a0f6a89..78438e5c 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 @@ -752,18 +752,33 @@ fun ReadableMap.toPictureInPictureConfig(): PictureInPictureConfig = PictureInPi isEnabled = getBooleanOrNull("isEnabled") ?: false, ) -/** - * Converts the [json] to a `RNUiConfig` object. - */ -fun toPlayerViewConfig(json: ReadableMap) = PlayerViewConfig( - uiConfig = UiConfig.WebUi( - playbackSpeedSelectionEnabled = json.getMap("uiConfig") - ?.getBooleanOrNull("playbackSpeedSelectionEnabled") - ?: true, - ), - hideFirstFrame = json.getBooleanOrNull("hideFirstFrame") ?: false, +fun ReadableMap.toPlayerViewConfig(): PlayerViewConfig = PlayerViewConfig( + uiConfig = getMap("uiConfig")?.toUiConfig() ?: UiConfig.WebUi(), + hideFirstFrame = getBooleanOrNull("hideFirstFrame") ?: false, ) +private fun ReadableMap.toUiConfig(): UiConfig { + val variant = toVariant() ?: UiConfig.WebUi.Variant.SmallScreenUi + val focusUiOnInitialization = getBooleanOrNull("focusUiOnInitialization") + val defaultFocusUiOnInitialization = variant == UiConfig.WebUi.Variant.TvUi + + return UiConfig.WebUi( + playbackSpeedSelectionEnabled = getBooleanOrNull("playbackSpeedSelectionEnabled") ?: true, + variant = variant, + focusUiOnInitialization = focusUiOnInitialization ?: defaultFocusUiOnInitialization, + ) +} + +private fun ReadableMap.toVariant(): UiConfig.WebUi.Variant? { + val uiManagerFactoryFunction = getMap("variant")?.getString("uiManagerFactoryFunction") ?: return null + + return when (uiManagerFactoryFunction) { + "bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI" -> UiConfig.WebUi.Variant.SmallScreenUi + "bitmovin.playerui.UIFactory.buildDefaultTvUI" -> UiConfig.WebUi.Variant.TvUi + else -> UiConfig.WebUi.Variant.Custom(uiManagerFactoryFunction) + } +} + private fun ReadableMap.toUserInterfaceTypeFromPlayerConfig(): UserInterfaceType? = when (getMap("styleConfig")?.getString("userInterfaceType")) { "Subtitle" -> UserInterfaceType.Subtitle @@ -775,7 +790,7 @@ private fun ReadableMap.toUserInterfaceTypeFromPlayerConfig(): UserInterfaceType * Converts the [this@toRNPlayerViewConfigWrapper] to a `RNPlayerViewConfig` object. */ fun ReadableMap.toRNPlayerViewConfigWrapper() = RNPlayerViewConfigWrapper( - playerViewConfig = toPlayerViewConfig(this), + playerViewConfig = toPlayerViewConfig(), pictureInPictureConfig = getMap("pictureInPictureConfig")?.toPictureInPictureConfig(), ) diff --git a/example/ios/Podfile b/example/ios/Podfile index 8839b4f7..1f1edce6 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -2,7 +2,6 @@ require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' source 'https://cdn.cocoapods.org' -source 'https://github.com/bitmovin/cocoapod-specs.git' source 'https://github.com/react-native-tvos/react-native-tvos-podspecs.git' prepare_react_native_project! diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 2c0b26e7..bea8380b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,12 +1,12 @@ PODS: - - BitmovinAnalyticsCollector/BitmovinPlayer (3.8.1): + - BitmovinAnalyticsCollector/BitmovinPlayer (3.9.0): - BitmovinAnalyticsCollector/Core - BitmovinPlayerCore (~> 3.48) - - BitmovinAnalyticsCollector/Core (3.8.1) - - BitmovinPlayer (3.74.0): + - BitmovinAnalyticsCollector/Core (3.9.0) + - BitmovinPlayer (3.77.0): - BitmovinAnalyticsCollector/BitmovinPlayer (~> 3.0) - - BitmovinPlayerCore (= 3.74.0) - - BitmovinPlayerCore (3.74.0) + - BitmovinPlayerCore (= 3.77.0) + - BitmovinPlayerCore (3.77.0) - boost (1.83.0) - DoubleConversion (1.1.6) - FBLazyVector (0.73.4-0) @@ -1048,8 +1048,8 @@ PODS: - React-jsi (= 0.73.4-0) - React-logger (= 0.73.4-0) - React-perflogger (= 0.73.4-0) - - RNBitmovinPlayer (0.29.0): - - BitmovinPlayer (= 3.74.0) + - RNBitmovinPlayer (0.30.0): + - BitmovinPlayer (= 3.77.0) - GoogleAds-IMA-iOS-SDK (= 3.23.0) - GoogleAds-IMA-tvOS-SDK (= 4.13.0) - React-Core @@ -1122,13 +1122,12 @@ DEPENDENCIES: - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - https://github.com/bitmovin/cocoapod-specs.git: - - BitmovinPlayer - - BitmovinPlayerCore https://github.com/react-native-tvos/react-native-tvos-podspecs.git: - libevent trunk: - BitmovinAnalyticsCollector + - BitmovinPlayer + - BitmovinPlayerCore - google-cast-sdk - GoogleAds-IMA-iOS-SDK - GoogleAds-IMA-tvOS-SDK @@ -1245,9 +1244,9 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - BitmovinAnalyticsCollector: 972e52381ef61210fbf9397e5fbf22db462ac94a - BitmovinPlayer: 4a7f76d0d904f61ed66adde34741e051a5b955ef - BitmovinPlayerCore: d171e1f6b9d64a2eb2cc9c168d6bdcf00af313e4 + BitmovinAnalyticsCollector: d08e0b13bcc32973370e0d71f2faa739561bac0a + BitmovinPlayer: 65866e13f7a8246ccbc7378607d6ca789f0f459e + BitmovinPlayerCore: 158b4a5b81b12b819f0f51b7b89711ca47e11583 boost: 88202336c3ba1e7a264a83c0c888784b0f360c28 DoubleConversion: 74cb0ce4de271b23e772567504735c87134edf0a FBLazyVector: 33a271a7e8de0bd321e47356d8bc3b2d5fb9ddba @@ -1302,12 +1301,12 @@ SPEC CHECKSUMS: React-runtimescheduler: 20b2202e3396589a71069d12ae9f328949c7c7b8 React-utils: 0307d396f233e47a167b5aaf045b0e4e1dc19d74 ReactCommon: 17891ca337bfa5a7263649b09f27a8c664537bf2 - RNBitmovinPlayer: 2f8aa7c280fe632550dcb872738610632d87440f + RNBitmovinPlayer: 5df76edfd71a5887aa20210108bdf9ac7227048b RNCPicker: b18aaf30df596e9b1738e7c1f9ee55402a229dca RNScreens: b582cb834dc4133307562e930e8fa914b8c04ef2 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Yoga: ab50eb8f7fcf1b36aad1801b5687b66b2c0aa000 + Yoga: e7f2a2256464d4ef7b3825d216bd22aac3b449c1 -PODFILE CHECKSUM: e89ebfe6215567e7e15880586d123e5ea122588c +PODFILE CHECKSUM: 11ac6cb62c1978622f6d687b574d9de3441a2680 COCOAPODS: 1.15.2 diff --git a/example/package.json b/example/package.json index 6373c883..2bb68c46 100644 --- a/example/package.json +++ b/example/package.json @@ -9,8 +9,8 @@ "ios": "react-native run-ios", "start": "react-native start", "pods": "yarn pods-install || yarn pods-update", - "pods-install": "NO_FLIPPER=1 yarn pod-install", - "pods-update": "cd ios && NO_FLIPPER=1 pod update --silent" + "pods-install": "[ \"$(uname)\" != Darwin ] || NO_FLIPPER=1 yarn pod-install", + "pods-update": "[ \"$(uname)\" != Darwin ] || cd ios && NO_FLIPPER=1 pod update --silent" }, "dependencies": { "@react-native-picker/picker": "2.6.1", diff --git a/example/src/App.tsx b/example/src/App.tsx index a8b3ea33..2e10c807 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -8,6 +8,7 @@ import ExamplesList from './screens/ExamplesList'; import BasicAds from './screens/BasicAds'; import BasicAnalytics from './screens/BasicAnalytics'; import BasicPlayback from './screens/BasicPlayback'; +import BasicTvPlayback from './screens/BasicTvPlayback'; import BasicDrmPlayback from './screens/BasicDrmPlayback'; import SubtitlePlayback from './screens/SubtitlePlayback'; import ProgrammaticTrackSelection from './screens/ProgrammaticTrackSelection'; @@ -32,6 +33,7 @@ export type RootStackParamsList = { BasicAds: undefined; BasicAnalytics: undefined; BasicPlayback: undefined; + BasicTvPlayback: undefined; BasicDrmPlayback: undefined; BasicPictureInPicture: { navigation: NativeStackNavigationProp; @@ -65,6 +67,7 @@ export type RootStackParamsList = { const RootStack = createNativeStackNavigator(); const isTVOS = Platform.OS === 'ios' && Platform.isTV; +const isAndroidTV = Platform.OS === 'android' && Platform.isTV; export default function App() { useEffect(() => { @@ -118,6 +121,13 @@ export default function App() { ], }; + if (isAndroidTV) { + stackParams.data.unshift({ + title: 'Basic TV playback', + routeName: 'BasicTvPlayback', + }); + } + if (!isTVOS) { stackParams.data.push({ title: 'Custom HTML UI', @@ -192,6 +202,13 @@ export default function App() { component={BasicPlayback} options={{ title: 'Basic playback' }} /> + {isAndroidTV && ( + + )} { + player.load({ + url: + Platform.OS === 'ios' + ? 'https://bitmovin-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8' + : 'https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd', + type: Platform.OS === 'ios' ? SourceType.HLS : SourceType.DASH, + title: 'Art of Motion', + poster: + 'https://bitmovin-a.akamaihd.net/content/MI201109210084_1/poster.jpg', + thumbnailTrack: + 'https://cdn.bitmovin.com/content/assets/art-of-motion-dash-hls-progressive/thumbnails/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.vtt', + metadata: { platform: Platform.OS }, + }); + return () => { + player.destroy(); + }; + }, [player]) + ); + + const onReady = useCallback((event: Event) => { + prettyPrint(`EVENT [${event.name}]`, event); + }, []); + + const onEvent = useCallback((event: Event) => { + prettyPrint(`EVENT [${event.name}]`, event); + }, []); + + return ( + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'black', + }, + player: { + flex: 1, + }, +}); diff --git a/example/yarn.lock b/example/yarn.lock index 2e65059c..b2fbd2fd 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2368,6 +2368,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + envinfo@^7.10.0: version "7.13.0" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" @@ -3409,9 +3414,9 @@ metro@0.80.9, metro@^0.80.3: yargs "^17.6.2" micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" - integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: braces "^3.0.3" picomatch "^2.3.1" @@ -4174,10 +4179,10 @@ semver@^7.5.2, semver@^7.5.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -4199,14 +4204,14 @@ serialize-error@^2.1.0: integrity sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw== serve-static@^1.13.1: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "0.19.0" set-blocking@^2.0.0: version "2.0.0" diff --git a/integration_test/ios/Podfile b/integration_test/ios/Podfile index 2c17c613..097a6334 100644 --- a/integration_test/ios/Podfile +++ b/integration_test/ios/Podfile @@ -2,7 +2,6 @@ require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' source 'https://cdn.cocoapods.org' -source 'https://github.com/bitmovin/cocoapod-specs.git' source 'https://github.com/react-native-tvos/react-native-tvos-podspecs.git' prepare_react_native_project! diff --git a/integration_test/ios/Podfile.lock b/integration_test/ios/Podfile.lock index b0e5f574..f58b7b94 100644 --- a/integration_test/ios/Podfile.lock +++ b/integration_test/ios/Podfile.lock @@ -1,12 +1,12 @@ PODS: - - BitmovinAnalyticsCollector/BitmovinPlayer (3.8.1): + - BitmovinAnalyticsCollector/BitmovinPlayer (3.9.0): - BitmovinAnalyticsCollector/Core - BitmovinPlayerCore (~> 3.48) - - BitmovinAnalyticsCollector/Core (3.8.1) - - BitmovinPlayer (3.74.0): + - BitmovinAnalyticsCollector/Core (3.9.0) + - BitmovinPlayer (3.77.0): - BitmovinAnalyticsCollector/BitmovinPlayer (~> 3.0) - - BitmovinPlayerCore (= 3.74.0) - - BitmovinPlayerCore (3.74.0) + - BitmovinPlayerCore (= 3.77.0) + - BitmovinPlayerCore (3.77.0) - boost (1.83.0) - DoubleConversion (1.1.6) - FBLazyVector (0.73.4-0) @@ -1040,8 +1040,8 @@ PODS: - React-jsi (= 0.73.4-0) - React-logger (= 0.73.4-0) - React-perflogger (= 0.73.4-0) - - RNBitmovinPlayer (0.29.0): - - BitmovinPlayer (= 3.74.0) + - RNBitmovinPlayer (0.30.0): + - BitmovinPlayer (= 3.77.0) - GoogleAds-IMA-iOS-SDK (= 3.23.0) - GoogleAds-IMA-tvOS-SDK (= 4.13.0) - React-Core @@ -1103,13 +1103,12 @@ DEPENDENCIES: - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - https://github.com/bitmovin/cocoapod-specs.git: - - BitmovinPlayer - - BitmovinPlayerCore https://github.com/react-native-tvos/react-native-tvos-podspecs.git: - libevent trunk: - BitmovinAnalyticsCollector + - BitmovinPlayer + - BitmovinPlayerCore - GoogleAds-IMA-iOS-SDK - SocketRocket @@ -1215,15 +1214,15 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - BitmovinAnalyticsCollector: 972e52381ef61210fbf9397e5fbf22db462ac94a - BitmovinPlayer: 4a7f76d0d904f61ed66adde34741e051a5b955ef - BitmovinPlayerCore: d171e1f6b9d64a2eb2cc9c168d6bdcf00af313e4 + BitmovinAnalyticsCollector: d08e0b13bcc32973370e0d71f2faa739561bac0a + BitmovinPlayer: 65866e13f7a8246ccbc7378607d6ca789f0f459e + BitmovinPlayerCore: 158b4a5b81b12b819f0f51b7b89711ca47e11583 boost: 88202336c3ba1e7a264a83c0c888784b0f360c28 - DoubleConversion: 74cb0ce4de271b23e772567504735c87134edf0a + DoubleConversion: 234abba95e31cc2aada0cf3b97cdb11bc5b90575 FBLazyVector: 33a271a7e8de0bd321e47356d8bc3b2d5fb9ddba FBReactNativeSpec: 55b7e93b71f300a051190f63c2afeccd839b7e9a fmt: 745abaaffe4da13101ae15d70dc68ec3d6a666a2 - glog: f0ddebfc00a905e9213e37801095a0a705d2e5f6 + glog: a2ded9bf28f0cb2fce90ad21eb419299a500ff6c GoogleAds-IMA-iOS-SDK: ee2a68ed7a1a17c7bb81bdb1b81590b35a3fc8f3 hermes-engine: e7981489a718dff7c3a2dacd6302b8761375928d libevent: a6d75fcd7be07cbc5070300ea8dbc8d55dfab88e @@ -1267,10 +1266,10 @@ SPEC CHECKSUMS: React-runtimescheduler: 20b2202e3396589a71069d12ae9f328949c7c7b8 React-utils: 0307d396f233e47a167b5aaf045b0e4e1dc19d74 ReactCommon: 17891ca337bfa5a7263649b09f27a8c664537bf2 - RNBitmovinPlayer: 2f8aa7c280fe632550dcb872738610632d87440f + RNBitmovinPlayer: 5df76edfd71a5887aa20210108bdf9ac7227048b SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Yoga: ab50eb8f7fcf1b36aad1801b5687b66b2c0aa000 + Yoga: e7f2a2256464d4ef7b3825d216bd22aac3b449c1 -PODFILE CHECKSUM: 0bfe194f5e28f1cf54d3d732eda8c78fadbeeedd +PODFILE CHECKSUM: d1cd0316ec7219d421f4dfb46ced3af29fd4e932 COCOAPODS: 1.15.2 diff --git a/integration_test/yarn.lock b/integration_test/yarn.lock index fc0cbc4e..b8d1f068 100644 --- a/integration_test/yarn.lock +++ b/integration_test/yarn.lock @@ -2466,9 +2466,9 @@ fast-xml-parser@4.4.1: strnum "^1.0.5" fast-xml-parser@^4.0.12, fast-xml-parser@^4.2.4: - version "4.4.0" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz#341cc98de71e9ba9e651a67f41f1752d1441a501" - integrity sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg== + version "4.5.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz#2882b7d01a6825dfdf909638f2de0256351def37" + integrity sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg== dependencies: strnum "^1.0.5" diff --git a/ios/RCTConvert+BitmovinPlayer.swift b/ios/RCTConvert+BitmovinPlayer.swift index 4034411f..4cef95dd 100644 --- a/ios/RCTConvert+BitmovinPlayer.swift +++ b/ios/RCTConvert+BitmovinPlayer.swift @@ -1242,9 +1242,13 @@ extension RCTConvert { guard let json = json as? [String: Any?] else { return nil } + let variant = json["variant"] as? [String: Any?] + let uiManagerFactoryFunction = variant?["uiManagerFactoryFunction"] as? String + let defaultUiManagerFactoryFunction = "bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI" return RNUiConfig( - playbackSpeedSelectionEnabled: json["playbackSpeedSelectionEnabled"] as? Bool ?? true + playbackSpeedSelectionEnabled: json["playbackSpeedSelectionEnabled"] as? Bool ?? true, + uiManagerFactoryFunction: uiManagerFactoryFunction ?? defaultUiManagerFactoryFunction ) } @@ -1384,6 +1388,7 @@ internal struct RNPlayerViewConfig { */ internal struct RNUiConfig { let playbackSpeedSelectionEnabled: Bool + let uiManagerFactoryFunction: String } /** diff --git a/ios/RNPlayerViewManager.swift b/ios/RNPlayerViewManager.swift index d6a381be..96390e3f 100644 --- a/ios/RNPlayerViewManager.swift +++ b/ios/RNPlayerViewManager.swift @@ -74,6 +74,7 @@ public class RNPlayerViewManager: RCTViewManager { if let uiConfig = playerViewConfig?.uiConfig { bitmovinUserInterfaceConfig .playbackSpeedSelectionEnabled = uiConfig.playbackSpeedSelectionEnabled + bitmovinUserInterfaceConfig.uiManagerFactoryFunction = uiConfig.uiManagerFactoryFunction } if let hideFirstFrame = playerViewConfig?.hideFirstFrame { bitmovinUserInterfaceConfig.hideFirstFrame = hideFirstFrame diff --git a/package.json b/package.json index f05c6549..ae3f9c51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bitmovin-player-react-native", - "version": "0.29.0", + "version": "0.30.0", "description": "Official React Native bindings for Bitmovin's mobile Player SDKs.", "main": "lib/index.js", "module": "lib/index.mjs", diff --git a/src/components/PlayerView/playerViewConfig.ts b/src/components/PlayerView/playerViewConfig.ts index d61df77d..33e474df 100644 --- a/src/components/PlayerView/playerViewConfig.ts +++ b/src/components/PlayerView/playerViewConfig.ts @@ -43,4 +43,57 @@ export interface WebUiConfig extends UiConfig { * Default is `true`. */ playbackSpeedSelectionEnabled?: boolean; + /** + * The UI variant to use for the Bitmovin Player Web UI. + * + * Default is {@link SmallScreenUi} + */ + variant?: Variant; + /** + * Whether the WebView should be focused on initialization. + * + * By default this is enabled only for the TV UI variant, as it's needed there to + * initiate spatial navigation using the remote control. + * + * @platform Android + */ + focusUiOnInitialization?: boolean; +} + +export abstract class Variant { + /** + * Specifies the function name that will be used to initialize the `UIManager` + * for the Bitmovin Player Web UI. + * + * The function is called on the `window` object with the `Player` as the first argument and + * the `UIConfig` as the second argument. + * + * Example: + * When you added a new function or want to use a different function of our `UIFactory`, + * you can specify the full qualifier name including namespaces. + * e.g. `bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI` for the SmallScreenUi. + * @see UIFactory https://github.com/bitmovin/bitmovin-player-ui/blob/develop/src/ts/uifactory.ts#L60 + * + * Notes: + * - It's not necessary to use our `UIFactory`. Any static function can be specified. + */ + constructor(public readonly uiManagerFactoryFunction: string) {} +} + +export class SmallScreenUi extends Variant { + constructor() { + super('bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI'); + } +} + +export class TvUi extends Variant { + constructor() { + super('bitmovin.playerui.UIFactory.buildDefaultTvUI'); + } +} + +export class CustomUi extends Variant { + constructor(uiManagerFactoryFunction: string) { + super(uiManagerFactoryFunction); + } }