bitmovin-player-react-native 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +1 -0
- package/AGENTS.md +91 -0
- package/CHANGELOG.md +10 -0
- package/android/build.gradle +3 -3
- package/ios/RCTConvert+BitmovinPlayer.swift +1 -1
- package/ios/RNBitmovinPlayer.podspec +3 -3
- package/package.json +2 -2
- package/plugin/build/withAppGradleDependencies.js +26 -0
- package/plugin/src/withAppGradleDependencies.ts +35 -0
- package/scripts/setup-hooks.sh +7 -9
- package/android/src/main/AndroidManifestNew.xml +0 -2
package/.prettierignore
CHANGED
package/AGENTS.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
|
|
5
|
+
- `src/`: TypeScript API surface and React components (library code).
|
|
6
|
+
- `ios/`, `android/`: Native bridges (Swift/Kotlin) used by the Expo Module.
|
|
7
|
+
- `plugin/`: Expo Config Plugin code used during prebuild.
|
|
8
|
+
- `example/`: Runnable sample app (Expo) to develop and validate changes.
|
|
9
|
+
- `integration_test/`: Expo app + Cavy-based integration tests.
|
|
10
|
+
- `scripts/`: Repo tooling (lint/format hooks, helpers). `build/`: transpiled output.
|
|
11
|
+
|
|
12
|
+
## Build, Test, and Development Commands
|
|
13
|
+
|
|
14
|
+
- `yarn bootstrap` — install deps, prebuild example, set up pods.
|
|
15
|
+
- `yarn build` (`build:module`, `build:plugin`) — build the library and plugin to `build/`.
|
|
16
|
+
- `yarn example start | ios | android` — run Metro or launch the example on simulators/emulators.
|
|
17
|
+
- `yarn integration-test test:ios | test:android | test` — run Cavy tests.
|
|
18
|
+
- `yarn lint` (`lint:all`), `yarn typecheck` (`typecheck:all`), `yarn format:all` — quality gates.
|
|
19
|
+
- `yarn docs` — generate TypeDoc documentation.
|
|
20
|
+
|
|
21
|
+
## Coding Style & Naming Conventions
|
|
22
|
+
|
|
23
|
+
- TypeScript: ESLint + Prettier (2 spaces, single quotes, trailing commas `es5`).
|
|
24
|
+
- Names: types/interfaces PascalCase; variables/functions camelCase; React components PascalCase.
|
|
25
|
+
- Files in `src/` use camelCase (e.g., `playerConfig.ts`).
|
|
26
|
+
- iOS: SwiftLint via `yarn lint:ios`; format with `yarn format:ios`.
|
|
27
|
+
- Android: ktlint via `yarn lint:android`; format with `yarn format:android`.
|
|
28
|
+
|
|
29
|
+
## Testing Guidelines
|
|
30
|
+
|
|
31
|
+
- Framework: Cavy; tests live under `integration_test/tests`.
|
|
32
|
+
- Setup: `cp integration_test/.env.example integration_test/.env` and set `EXPO_PUBLIC_BITMOVIN_PLAYER_LICENSE_KEY`.
|
|
33
|
+
- Run: `yarn integration-test test:ios` or `test:android` (simulator/emulator only).
|
|
34
|
+
- Add per‑feature tests (e.g., `Playback.test.ts`) covering happy‑path and error events.
|
|
35
|
+
|
|
36
|
+
## Commit & Pull Request Guidelines
|
|
37
|
+
|
|
38
|
+
- Commits: concise, imperative; do not use prefixes such as `fix:`, `chore:`, etc.
|
|
39
|
+
- PRs: follow `.github/PULL_REQUEST_TEMPLATE.md`; link issues; add screenshots for UI-facing changes.
|
|
40
|
+
- Required before review: `yarn lint:all`, `yarn typecheck:all`, build the library, and run the example on at least one platform.
|
|
41
|
+
- Changelog: add a `CHANGELOG.md` entry for user‑visible behavior changes.
|
|
42
|
+
|
|
43
|
+
## Security & Configuration Tips
|
|
44
|
+
|
|
45
|
+
- Never commit secrets. Keep license keys only in `integration_test/.env` (gitignored).
|
|
46
|
+
|
|
47
|
+
## Docs Index
|
|
48
|
+
|
|
49
|
+
- CONTRIBUTING.md — Development workflow, Development setup, TypeScript Code Style, Linting (pre-commit hooks), Kotlin, Swift, Testing, Scripts.
|
|
50
|
+
- example/README.md — Getting started, Development Setup (.env and license keys), Running the application (iOS/Android/tvOS/Android TV), Bundler only, Architecture, Troubleshooting.
|
|
51
|
+
- integration_test/README.md — Setup, Environment Configuration (.env), Running the tests, Architecture, Test Coverage, Platform Support.
|
|
52
|
+
- README.md — “Sample Application” section links to `example/` README and official docs; use as entry point.
|
|
53
|
+
|
|
54
|
+
## Developer Essentials
|
|
55
|
+
|
|
56
|
+
- Environment
|
|
57
|
+
- Node + Yarn (use Yarn across workspaces); macOS: Xcode + CocoaPods; Android: Android Studio + JDK 17+ (Gradle 8.2 wrapper).
|
|
58
|
+
- Platforms per README: Expo 53+, React Native 0.79+, React 17+.
|
|
59
|
+
- Tooling & Hooks
|
|
60
|
+
- Install hooks with `yarn setup-hooks`; verify with `yarn lint:all` and `yarn typecheck:all` before PRs.
|
|
61
|
+
- SwiftLint/ktlint required for native; use `yarn format:ios` / `yarn format:android` for auto-fixes.
|
|
62
|
+
- Workflow
|
|
63
|
+
- Bootstrap from repo root: `yarn bootstrap`. Re-run prebuilds after env/native/config changes (`yarn example prebuild`, `yarn integration-test prebuild`).
|
|
64
|
+
- Public API: export via `src/index.ts`; keep native module/view names identical to TS wrappers; maintain event parity with TS types.
|
|
65
|
+
- Instance routing uses stable `nativeId` values; ensure native registries clean up on module destruction.
|
|
66
|
+
- Secrets
|
|
67
|
+
- Never commit keys. Store license keys only in `.env` under `example/` and `integration_test/` as documented.
|
|
68
|
+
- Validation
|
|
69
|
+
- Use the example app for manual checks and the integration tests on simulators/emulators for feature coverage.
|
|
70
|
+
|
|
71
|
+
## Routing Public API to React Native
|
|
72
|
+
|
|
73
|
+
- Source of truth: export public surface from `src/index.ts:1-29` (ensure new modules are re‑exported).
|
|
74
|
+
- Use typed Expo wrappers in `src/modules/`:
|
|
75
|
+
- Define `declare class <Feature>Module extends NativeModule<Events> { ... }` and load with `requireNativeModule('<Feature>Module')` (example: `src/modules/PlayerModule.ts:1,251`).
|
|
76
|
+
- Match native names exactly on both platforms:
|
|
77
|
+
- iOS: `Name("PlayerModule")` in `ios/PlayerModule.swift:7`; Android: `Name("PlayerModule")` in `android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt:23`.
|
|
78
|
+
- Bridge views via view managers:
|
|
79
|
+
- TS host component: `requireNativeViewManager('RNPlayerViewManager')` in `src/components/PlayerView/native.ts:33-35`.
|
|
80
|
+
- iOS manager: `ios/RNPlayerViewManager.swift:6`; Android manager: `android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt:12`.
|
|
81
|
+
- Events flow native → JS via Expo `Events(...)` lists; keep parity with TS props:
|
|
82
|
+
- Android events list: `android/.../RNPlayerViewManager.kt:50-112`; iOS: `ios/RNPlayerViewManager.swift:33-60`.
|
|
83
|
+
- TS event typings live in `src/components/PlayerView/nativeEvents.ts:72-160` (extend as needed).
|
|
84
|
+
- Instance routing uses `nativeId` across modules; keep IDs stable and registry-backed on native:
|
|
85
|
+
- Example registry and async functions in `android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt:18-24,41-49`.
|
|
86
|
+
- Adding a new API (happy path):
|
|
87
|
+
- TS: add method on a `src/modules/<Feature>Module.ts` wrapper, export from `src/index.ts`.
|
|
88
|
+
- iOS/Android: add matching `AsyncFunction("methodName")` to Expo `ModuleDefinition`; emit events if needed.
|
|
89
|
+
- Views: add `Prop(...)`/`Events(...)` in native managers and extend `NativePlayerViewProps`.
|
|
90
|
+
- Tests: extend integration tests; validate on at least one platform.
|
|
91
|
+
- Naming: keep method/event names identical across TS, iOS, Android.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0] - 2025-10-17
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Update Bitmovin's native iOS SDK version to `3.97.2`
|
|
8
|
+
- Update Bitmovin's native Android SDK version to `3.128.0+jason`
|
|
9
|
+
- Update IMA SDK dependency on iOS to `3.26.1`
|
|
10
|
+
- Update IMA SDK dependency on tvOS to `4.15.1`
|
|
11
|
+
- Update IMA SDK dependency on Android to `3.37.0`
|
|
12
|
+
|
|
3
13
|
## [1.1.0] - 2025-09-03
|
|
4
14
|
|
|
5
15
|
### Changed
|
package/android/build.gradle
CHANGED
|
@@ -104,10 +104,10 @@ dependencies {
|
|
|
104
104
|
implementation "androidx.concurrent:concurrent-futures-ktx:1.1.0"
|
|
105
105
|
|
|
106
106
|
// Google IMA
|
|
107
|
-
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.
|
|
107
|
+
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.37.0'
|
|
108
108
|
|
|
109
109
|
// Bitmovin
|
|
110
110
|
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
|
111
|
-
implementation 'com.bitmovin.player:player:3.
|
|
112
|
-
implementation 'com.bitmovin.player:player-media-session:3.
|
|
111
|
+
implementation 'com.bitmovin.player:player:3.128.0+jason'
|
|
112
|
+
implementation 'com.bitmovin.player:player-media-session:3.128.0+jason'
|
|
113
113
|
}
|
|
@@ -196,7 +196,7 @@ extension RCTConvert {
|
|
|
196
196
|
return nil
|
|
197
197
|
}
|
|
198
198
|
var request = HttpRequest(url: url, method: method)
|
|
199
|
-
request.headers =
|
|
199
|
+
request.headers = headers
|
|
200
200
|
|
|
201
201
|
if let bodyBase64EncodedString = json["body"] as? String {
|
|
202
202
|
request.body = Data(base64Encoded: bodyBase64EncodedString)
|
|
@@ -28,9 +28,9 @@ Pod::Spec.new do |s|
|
|
|
28
28
|
s.static_framework = true
|
|
29
29
|
|
|
30
30
|
s.dependency 'ExpoModulesCore'
|
|
31
|
-
s.dependency "BitmovinPlayer", "3.
|
|
32
|
-
s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.
|
|
33
|
-
s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.
|
|
31
|
+
s.dependency "BitmovinPlayer", "3.97.2"
|
|
32
|
+
s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.26.1"
|
|
33
|
+
s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.15.1"
|
|
34
34
|
|
|
35
35
|
if podfile_properties['BITMOVIN_GOOGLE_CAST_SDK_VERSION'].to_s != ''
|
|
36
36
|
s.ios.dependency "google-cast-sdk", podfile_properties['BITMOVIN_GOOGLE_CAST_SDK_VERSION'].to_s
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bitmovin-player-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Official React Native bindings for Bitmovin's mobile Player SDKs.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -94,6 +94,6 @@
|
|
|
94
94
|
"./scripts/format-android.sh",
|
|
95
95
|
"./scripts/lint-android.sh"
|
|
96
96
|
],
|
|
97
|
-
"*.(ts|tsx|js|jsx|md|json|yml|yaml)": "prettier --write"
|
|
97
|
+
"*.(ts|tsx|js|jsx|md|json|yml|yaml)": "prettier --write --no-error-on-unmatched-pattern"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -19,6 +19,30 @@ const withAppGradleDependencies = (config, props) => {
|
|
|
19
19
|
if (filteredDependencies.length === 0) {
|
|
20
20
|
return config;
|
|
21
21
|
}
|
|
22
|
+
const androidBlockStart = config.modResults.contents.search(/^android \{$/m);
|
|
23
|
+
if (androidBlockStart === -1) {
|
|
24
|
+
config_plugins_1.WarningAggregator.addWarningAndroid('withAppGradleDependencies', `Cannot configure app/build.gradle as no android block start was found`);
|
|
25
|
+
return config;
|
|
26
|
+
}
|
|
27
|
+
const fromAndroid = config.modResults.contents.substring(androidBlockStart);
|
|
28
|
+
const androidBlockEnd = fromAndroid.search(/^\}$/m);
|
|
29
|
+
if (androidBlockEnd === -1) {
|
|
30
|
+
config_plugins_1.WarningAggregator.addWarningAndroid('withAppGradleDependencies', `Cannot configure app/build.gradle as no android block end was found`);
|
|
31
|
+
return config;
|
|
32
|
+
}
|
|
33
|
+
const androidPosition = androidBlockStart + androidBlockEnd;
|
|
34
|
+
const compileOptions = [];
|
|
35
|
+
compileOptions.push(`${combinedProps.spacing}compileOptions {`);
|
|
36
|
+
compileOptions.push('\n');
|
|
37
|
+
compileOptions.push(`${combinedProps.spacing}setCoreLibraryDesugaringEnabled(true)`);
|
|
38
|
+
compileOptions.push('\n');
|
|
39
|
+
compileOptions.push(`${combinedProps.spacing}}`);
|
|
40
|
+
compileOptions.push('\n');
|
|
41
|
+
config.modResults.contents = [
|
|
42
|
+
config.modResults.contents.slice(0, androidPosition),
|
|
43
|
+
...compileOptions,
|
|
44
|
+
config.modResults.contents.slice(androidPosition),
|
|
45
|
+
].join('');
|
|
22
46
|
const dependenciesBlockStart = config.modResults.contents.search(/^dependencies \{$/m);
|
|
23
47
|
if (dependenciesBlockStart === -1) {
|
|
24
48
|
config_plugins_1.WarningAggregator.addWarningAndroid('withAppGradleDependencies', `Cannot configure app/build.gradle as no dependency block start was found`);
|
|
@@ -33,6 +57,8 @@ const withAppGradleDependencies = (config, props) => {
|
|
|
33
57
|
const position = dependenciesBlockStart + dependenciesBlockEnd;
|
|
34
58
|
let insertedDependencies = [];
|
|
35
59
|
insertedDependencies.push('\n');
|
|
60
|
+
insertedDependencies.push(`${combinedProps.spacing}coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'`);
|
|
61
|
+
insertedDependencies.push('\n');
|
|
36
62
|
filteredDependencies.forEach((dependency) => {
|
|
37
63
|
insertedDependencies.push(`${combinedProps.spacing}implementation '${dependency}'\n`);
|
|
38
64
|
});
|
|
@@ -38,6 +38,39 @@ const withAppGradleDependencies: ConfigPlugin<PluginProps> = (
|
|
|
38
38
|
return config;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
const androidBlockStart = config.modResults.contents.search(/^android \{$/m);
|
|
42
|
+
if (androidBlockStart === -1) {
|
|
43
|
+
WarningAggregator.addWarningAndroid(
|
|
44
|
+
'withAppGradleDependencies',
|
|
45
|
+
`Cannot configure app/build.gradle as no android block start was found`
|
|
46
|
+
);
|
|
47
|
+
return config;
|
|
48
|
+
}
|
|
49
|
+
const fromAndroid = config.modResults.contents.substring(
|
|
50
|
+
androidBlockStart
|
|
51
|
+
);
|
|
52
|
+
const androidBlockEnd = fromAndroid.search(/^\}$/m);
|
|
53
|
+
if (androidBlockEnd === -1) {
|
|
54
|
+
WarningAggregator.addWarningAndroid(
|
|
55
|
+
'withAppGradleDependencies',
|
|
56
|
+
`Cannot configure app/build.gradle as no android block end was found`
|
|
57
|
+
);
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
const androidPosition = androidBlockStart + androidBlockEnd;
|
|
61
|
+
const compileOptions = []
|
|
62
|
+
compileOptions.push(`${combinedProps.spacing}compileOptions {`)
|
|
63
|
+
compileOptions.push('\n');
|
|
64
|
+
compileOptions.push(`${combinedProps.spacing}setCoreLibraryDesugaringEnabled(true)`)
|
|
65
|
+
compileOptions.push('\n');
|
|
66
|
+
compileOptions.push(`${combinedProps.spacing}}`)
|
|
67
|
+
compileOptions.push('\n');
|
|
68
|
+
config.modResults.contents = [
|
|
69
|
+
config.modResults.contents.slice(0, androidPosition),
|
|
70
|
+
... compileOptions,
|
|
71
|
+
config.modResults.contents.slice(androidPosition),
|
|
72
|
+
].join('');
|
|
73
|
+
|
|
41
74
|
const dependenciesBlockStart =
|
|
42
75
|
config.modResults.contents.search(/^dependencies \{$/m);
|
|
43
76
|
if (dependenciesBlockStart === -1) {
|
|
@@ -61,6 +94,8 @@ const withAppGradleDependencies: ConfigPlugin<PluginProps> = (
|
|
|
61
94
|
const position = dependenciesBlockStart + dependenciesBlockEnd;
|
|
62
95
|
let insertedDependencies: string[] = [];
|
|
63
96
|
insertedDependencies.push('\n');
|
|
97
|
+
insertedDependencies.push(`${combinedProps.spacing}coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'`)
|
|
98
|
+
insertedDependencies.push('\n');
|
|
64
99
|
filteredDependencies.forEach((dependency) => {
|
|
65
100
|
insertedDependencies.push(
|
|
66
101
|
`${combinedProps.spacing}implementation '${dependency}'\n`
|
package/scripts/setup-hooks.sh
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
3
5
|
# Setup git pre-commit hooks for the project
|
|
4
6
|
echo "Setting up pre-commit hooks..."
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
if [ ! -d ".git" ]; then
|
|
8
|
-
echo "Error: Not a git repository. Please run this from the root of the project."
|
|
9
|
-
exit 1
|
|
10
|
-
fi
|
|
8
|
+
HOOK_DIR=$(git rev-parse --git-path hooks)
|
|
11
9
|
|
|
12
10
|
# Check if hooks directory exists
|
|
13
|
-
if [ ! -d "
|
|
14
|
-
echo "Creating
|
|
15
|
-
mkdir -p
|
|
11
|
+
if [ ! -d "$HOOK_DIR" ]; then
|
|
12
|
+
echo "Creating $HOOK_DIR directory..."
|
|
13
|
+
mkdir -p "$HOOK_DIR"
|
|
16
14
|
fi
|
|
17
15
|
|
|
18
16
|
# Get the directory where this script is located
|
|
@@ -26,7 +24,7 @@ if [ ! -f "$PRE_COMMIT_SOURCE" ]; then
|
|
|
26
24
|
fi
|
|
27
25
|
|
|
28
26
|
# Check if pre-commit hook already exists and compare content
|
|
29
|
-
HOOK_PATH="
|
|
27
|
+
HOOK_PATH="$HOOK_DIR/pre-commit"
|
|
30
28
|
NEEDS_UPDATE=true
|
|
31
29
|
|
|
32
30
|
if [ -f "$HOOK_PATH" ]; then
|