@bluebillywig/react-native-bb-player 8.42.10 → 8.42.14
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/CHANGELOG.md +22 -0
- package/README.md +58 -1
- package/android/build.gradle +7 -1
- package/android/src/main/java/com/bluebillywig/bbplayer/BBPlayerModule.kt +62 -62
- package/ios/BBPlayerView.swift +66 -24
- package/ios/BBPlayerViewController.swift +19 -42
- package/lib/commonjs/specs/NativeBBPlayerModule.js +2 -1
- package/lib/commonjs/specs/NativeBBPlayerModule.js.map +1 -1
- package/lib/module/specs/NativeBBPlayerModule.js +2 -1
- package/lib/module/specs/NativeBBPlayerModule.js.map +1 -1
- package/lib/typescript/src/specs/NativeBBPlayerModule.d.ts +1 -1
- package/lib/typescript/src/specs/NativeBBPlayerModule.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/specs/NativeBBPlayerModule.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to react-native-bb-player will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [8.42.10] - 2026-01-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **TurboModule support** for React Native New Architecture (Fabric)
|
|
12
|
+
- Added `NativeBBPlayerModule` TurboModule spec for React Native codegen
|
|
13
|
+
- Native module now uses `TurboModuleRegistry` when available, with automatic fallback to legacy `NativeModules`
|
|
14
|
+
- Added architecture-specific source sets (`newarch`/`paper`) for Android
|
|
15
|
+
- iOS module converted to Objective-C++ (`.mm`) for C++ interop required by TurboModules
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- `BBPlayerPackage.kt` now implements `TurboReactPackage` for New Architecture compatibility
|
|
19
|
+
- `BBPlayerModule.kt` extends generated `NativeBBPlayerModuleSpec` for type-safe TurboModule implementation
|
|
20
|
+
- Updated `react-native-bb-player.podspec` with New Architecture compiler flags and configuration
|
|
21
|
+
- Added `codegenConfig` to `package.json` for React Native codegen integration
|
|
22
|
+
|
|
23
|
+
### Technical Details
|
|
24
|
+
- Supports both Old Architecture (Paper) and New Architecture (Fabric/TurboModules)
|
|
25
|
+
- Tested with React Native 0.82.1
|
|
26
|
+
- No breaking changes - existing apps continue to work without modification
|
|
27
|
+
- New Architecture is automatically detected and used when enabled in the app
|
|
28
|
+
|
|
8
29
|
## [2.0.0] - 2026-01-20
|
|
9
30
|
|
|
10
31
|
### Changed
|
|
@@ -44,5 +65,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
44
65
|
- Android fullscreen landscape: proper orientation locking and state restoration
|
|
45
66
|
- Performance optimizations: reduced bridge traffic and memory leak fixes
|
|
46
67
|
|
|
68
|
+
[8.42.10]: https://github.com/bluebillywig/react-native-bb-player/releases/tag/v8.42.10
|
|
47
69
|
[2.0.0]: https://github.com/bluebillywig/react-native-bb-player/releases/tag/v2.0.0
|
|
48
70
|
[1.0.0]: https://github.com/bluebillywig/react-native-bb-player/releases/tag/v1.0.0
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Native video player for React Native - powered by Blue Billywig's iOS and Androi
|
|
|
18
18
|
|----------|-------------|---------------|
|
|
19
19
|
| **iOS** | 12.0+ | AVPlayer |
|
|
20
20
|
| **Android** | API 21+ (5.0+) | ExoPlayer |
|
|
21
|
-
| **React Native** | 0.73+ | Old & New Architecture |
|
|
21
|
+
| **React Native** | 0.73+ | Old & New Architecture (TurboModules) |
|
|
22
22
|
| **Expo** | SDK 51+ | With config plugin (optional) |
|
|
23
23
|
|
|
24
24
|
## Installation
|
|
@@ -673,6 +673,63 @@ function CustomScreen() {
|
|
|
673
673
|
}
|
|
674
674
|
```
|
|
675
675
|
|
|
676
|
+
## New Architecture (Fabric & TurboModules)
|
|
677
|
+
|
|
678
|
+
This package fully supports React Native's New Architecture, including:
|
|
679
|
+
|
|
680
|
+
- **Fabric** - The new rendering system
|
|
681
|
+
- **TurboModules** - The new native module system with synchronous access and lazy loading
|
|
682
|
+
|
|
683
|
+
### Automatic Detection
|
|
684
|
+
|
|
685
|
+
The package automatically detects which architecture your app uses:
|
|
686
|
+
- **New Architecture enabled**: Uses `TurboModuleRegistry` for optimal performance
|
|
687
|
+
- **Old Architecture**: Falls back to `NativeModules` (no changes needed)
|
|
688
|
+
|
|
689
|
+
### Enabling New Architecture
|
|
690
|
+
|
|
691
|
+
#### React Native 0.76+
|
|
692
|
+
New Architecture is enabled by default in React Native 0.76 and later.
|
|
693
|
+
|
|
694
|
+
#### React Native 0.73-0.75
|
|
695
|
+
Enable in your app's configuration:
|
|
696
|
+
|
|
697
|
+
**Android** (`android/gradle.properties`):
|
|
698
|
+
```properties
|
|
699
|
+
newArchEnabled=true
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**iOS** (`ios/Podfile`):
|
|
703
|
+
```ruby
|
|
704
|
+
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Then rebuild your app:
|
|
708
|
+
```bash
|
|
709
|
+
# iOS
|
|
710
|
+
cd ios && pod install && cd ..
|
|
711
|
+
npx react-native run-ios
|
|
712
|
+
|
|
713
|
+
# Android
|
|
714
|
+
cd android && ./gradlew clean && cd ..
|
|
715
|
+
npx react-native run-android
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### No Code Changes Required
|
|
719
|
+
|
|
720
|
+
Your existing code works with both architectures. The package handles the architecture detection internally:
|
|
721
|
+
|
|
722
|
+
```tsx
|
|
723
|
+
// This works on both Old and New Architecture
|
|
724
|
+
import { BBPlayerView } from '@bluebillywig/react-native-bb-player';
|
|
725
|
+
|
|
726
|
+
<BBPlayerView
|
|
727
|
+
ref={playerRef}
|
|
728
|
+
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
|
|
729
|
+
onDidTriggerPlay={() => console.log('Playing')}
|
|
730
|
+
/>
|
|
731
|
+
```
|
|
732
|
+
|
|
676
733
|
## FAQ
|
|
677
734
|
|
|
678
735
|
### Can I use this in production?
|
package/android/build.gradle
CHANGED
|
@@ -11,6 +11,11 @@ def isNewArchitectureEnabled() {
|
|
|
11
11
|
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// Apply React Native plugin for codegen when new arch is enabled
|
|
15
|
+
if (isNewArchitectureEnabled()) {
|
|
16
|
+
apply plugin: "com.facebook.react"
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
group = 'com.bluebillywig.bbplayer'
|
|
15
20
|
version = '2.0.0'
|
|
16
21
|
|
|
@@ -49,7 +54,8 @@ android {
|
|
|
49
54
|
main {
|
|
50
55
|
java.srcDirs = ['src/main/java']
|
|
51
56
|
if (isNewArchitectureEnabled()) {
|
|
52
|
-
|
|
57
|
+
// Include codegen-generated specs first (takes precedence)
|
|
58
|
+
java.srcDirs += ["build/generated/source/codegen/java"]
|
|
53
59
|
} else {
|
|
54
60
|
java.srcDirs += ['src/paper/java']
|
|
55
61
|
}
|
|
@@ -61,85 +61,85 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
@ReactMethod
|
|
64
|
-
override fun play(viewTag:
|
|
65
|
-
runOnUiThread(viewTag) { it.play() }
|
|
64
|
+
override fun play(viewTag: Double) {
|
|
65
|
+
runOnUiThread(viewTag.toInt()) { it.play() }
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
@ReactMethod
|
|
69
|
-
override fun pause(viewTag:
|
|
70
|
-
runOnUiThread(viewTag) { it.pause() }
|
|
69
|
+
override fun pause(viewTag: Double) {
|
|
70
|
+
runOnUiThread(viewTag.toInt()) { it.pause() }
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
@ReactMethod
|
|
74
|
-
override fun seek(viewTag:
|
|
75
|
-
runOnUiThread(viewTag) { it.seek(position) }
|
|
74
|
+
override fun seek(viewTag: Double, position: Double) {
|
|
75
|
+
runOnUiThread(viewTag.toInt()) { it.seek(position) }
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
@ReactMethod
|
|
79
|
-
override fun seekRelative(viewTag:
|
|
80
|
-
runOnUiThread(viewTag) { it.seekRelative(offsetSeconds) }
|
|
79
|
+
override fun seekRelative(viewTag: Double, offsetSeconds: Double) {
|
|
80
|
+
runOnUiThread(viewTag.toInt()) { it.seekRelative(offsetSeconds) }
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
@ReactMethod
|
|
84
|
-
override fun setVolume(viewTag:
|
|
85
|
-
runOnUiThread(viewTag) { it.setVolume(volume) }
|
|
84
|
+
override fun setVolume(viewTag: Double, volume: Double) {
|
|
85
|
+
runOnUiThread(viewTag.toInt()) { it.setVolume(volume) }
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
@ReactMethod
|
|
89
|
-
override fun setMuted(viewTag:
|
|
90
|
-
runOnUiThread(viewTag) { it.setMuted(muted) }
|
|
89
|
+
override fun setMuted(viewTag: Double, muted: Boolean) {
|
|
90
|
+
runOnUiThread(viewTag.toInt()) { it.setMuted(muted) }
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
@ReactMethod
|
|
94
|
-
override fun enterFullscreen(viewTag:
|
|
95
|
-
runOnUiThread(viewTag) { it.enterFullscreen() }
|
|
94
|
+
override fun enterFullscreen(viewTag: Double) {
|
|
95
|
+
runOnUiThread(viewTag.toInt()) { it.enterFullscreen() }
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
@ReactMethod
|
|
99
|
-
override fun enterFullscreenLandscape(viewTag:
|
|
100
|
-
runOnUiThread(viewTag) { it.enterFullscreenLandscape() }
|
|
99
|
+
override fun enterFullscreenLandscape(viewTag: Double) {
|
|
100
|
+
runOnUiThread(viewTag.toInt()) { it.enterFullscreenLandscape() }
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
@ReactMethod
|
|
104
|
-
override fun exitFullscreen(viewTag:
|
|
105
|
-
runOnUiThread(viewTag) { it.exitFullscreen() }
|
|
104
|
+
override fun exitFullscreen(viewTag: Double) {
|
|
105
|
+
runOnUiThread(viewTag.toInt()) { it.exitFullscreen() }
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
@ReactMethod
|
|
109
|
-
override fun collapse(viewTag:
|
|
110
|
-
runOnUiThread(viewTag) { it.collapse() }
|
|
109
|
+
override fun collapse(viewTag: Double) {
|
|
110
|
+
runOnUiThread(viewTag.toInt()) { it.collapse() }
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
@ReactMethod
|
|
114
|
-
override fun expand(viewTag:
|
|
115
|
-
runOnUiThread(viewTag) { it.expand() }
|
|
114
|
+
override fun expand(viewTag: Double) {
|
|
115
|
+
runOnUiThread(viewTag.toInt()) { it.expand() }
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
@ReactMethod
|
|
119
|
-
override fun autoPlayNextCancel(viewTag:
|
|
120
|
-
runOnUiThread(viewTag) { it.autoPlayNextCancel() }
|
|
119
|
+
override fun autoPlayNextCancel(viewTag: Double) {
|
|
120
|
+
runOnUiThread(viewTag.toInt()) { it.autoPlayNextCancel() }
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
@ReactMethod
|
|
124
|
-
override fun destroy(viewTag:
|
|
125
|
-
runOnUiThread(viewTag) { it.destroy() }
|
|
124
|
+
override fun destroy(viewTag: Double) {
|
|
125
|
+
runOnUiThread(viewTag.toInt()) { it.destroy() }
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
@ReactMethod
|
|
129
|
-
override fun showCastPicker(viewTag:
|
|
130
|
-
runOnUiThread(viewTag) { it.showCastPicker() }
|
|
129
|
+
override fun showCastPicker(viewTag: Double) {
|
|
130
|
+
runOnUiThread(viewTag.toInt()) { it.showCastPicker() }
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
@ReactMethod
|
|
134
134
|
override fun loadWithClipId(
|
|
135
|
-
viewTag:
|
|
135
|
+
viewTag: Double,
|
|
136
136
|
clipId: String,
|
|
137
137
|
initiator: String?,
|
|
138
138
|
autoPlay: Boolean,
|
|
139
139
|
seekTo: Double
|
|
140
140
|
) {
|
|
141
141
|
Log.d("BBPlayerModule", "loadWithClipId called - viewTag: $viewTag, clipId: $clipId, autoPlay: $autoPlay")
|
|
142
|
-
runOnUiThread(viewTag) {
|
|
142
|
+
runOnUiThread(viewTag.toInt()) {
|
|
143
143
|
it.loadWithClipId(
|
|
144
144
|
clipId,
|
|
145
145
|
initiator,
|
|
@@ -151,13 +151,13 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
151
151
|
|
|
152
152
|
@ReactMethod
|
|
153
153
|
override fun loadWithClipListId(
|
|
154
|
-
viewTag:
|
|
154
|
+
viewTag: Double,
|
|
155
155
|
clipListId: String,
|
|
156
156
|
initiator: String?,
|
|
157
157
|
autoPlay: Boolean,
|
|
158
158
|
seekTo: Double
|
|
159
159
|
) {
|
|
160
|
-
runOnUiThread(viewTag) {
|
|
160
|
+
runOnUiThread(viewTag.toInt()) {
|
|
161
161
|
it.loadWithClipListId(
|
|
162
162
|
clipListId,
|
|
163
163
|
initiator,
|
|
@@ -169,13 +169,13 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
169
169
|
|
|
170
170
|
@ReactMethod
|
|
171
171
|
override fun loadWithProjectId(
|
|
172
|
-
viewTag:
|
|
172
|
+
viewTag: Double,
|
|
173
173
|
projectId: String,
|
|
174
174
|
initiator: String?,
|
|
175
175
|
autoPlay: Boolean,
|
|
176
176
|
seekTo: Double
|
|
177
177
|
) {
|
|
178
|
-
runOnUiThread(viewTag) {
|
|
178
|
+
runOnUiThread(viewTag.toInt()) {
|
|
179
179
|
it.loadWithProjectId(
|
|
180
180
|
projectId,
|
|
181
181
|
initiator,
|
|
@@ -187,13 +187,13 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
187
187
|
|
|
188
188
|
@ReactMethod
|
|
189
189
|
override fun loadWithClipJson(
|
|
190
|
-
viewTag:
|
|
190
|
+
viewTag: Double,
|
|
191
191
|
clipJson: String,
|
|
192
192
|
initiator: String?,
|
|
193
193
|
autoPlay: Boolean,
|
|
194
194
|
seekTo: Double
|
|
195
195
|
) {
|
|
196
|
-
runOnUiThread(viewTag) {
|
|
196
|
+
runOnUiThread(viewTag.toInt()) {
|
|
197
197
|
it.loadWithClipJson(
|
|
198
198
|
clipJson,
|
|
199
199
|
initiator,
|
|
@@ -205,13 +205,13 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
205
205
|
|
|
206
206
|
@ReactMethod
|
|
207
207
|
override fun loadWithClipListJson(
|
|
208
|
-
viewTag:
|
|
208
|
+
viewTag: Double,
|
|
209
209
|
clipListJson: String,
|
|
210
210
|
initiator: String?,
|
|
211
211
|
autoPlay: Boolean,
|
|
212
212
|
seekTo: Double
|
|
213
213
|
) {
|
|
214
|
-
runOnUiThread(viewTag) {
|
|
214
|
+
runOnUiThread(viewTag.toInt()) {
|
|
215
215
|
it.loadWithClipListJson(
|
|
216
216
|
clipListJson,
|
|
217
217
|
initiator,
|
|
@@ -223,13 +223,13 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
223
223
|
|
|
224
224
|
@ReactMethod
|
|
225
225
|
override fun loadWithProjectJson(
|
|
226
|
-
viewTag:
|
|
226
|
+
viewTag: Double,
|
|
227
227
|
projectJson: String,
|
|
228
228
|
initiator: String?,
|
|
229
229
|
autoPlay: Boolean,
|
|
230
230
|
seekTo: Double
|
|
231
231
|
) {
|
|
232
|
-
runOnUiThread(viewTag) {
|
|
232
|
+
runOnUiThread(viewTag.toInt()) {
|
|
233
233
|
it.loadWithProjectJson(
|
|
234
234
|
projectJson,
|
|
235
235
|
initiator,
|
|
@@ -241,11 +241,11 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
241
241
|
|
|
242
242
|
@ReactMethod
|
|
243
243
|
override fun loadWithJsonUrl(
|
|
244
|
-
viewTag:
|
|
244
|
+
viewTag: Double,
|
|
245
245
|
jsonUrl: String,
|
|
246
246
|
autoPlay: Boolean
|
|
247
247
|
) {
|
|
248
|
-
runOnUiThread(viewTag) {
|
|
248
|
+
runOnUiThread(viewTag.toInt()) {
|
|
249
249
|
it.loadWithJsonUrl(jsonUrl, autoPlay)
|
|
250
250
|
}
|
|
251
251
|
}
|
|
@@ -255,9 +255,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
255
255
|
|
|
256
256
|
// Getter methods with Promise support
|
|
257
257
|
@ReactMethod
|
|
258
|
-
override fun getDuration(viewTag:
|
|
258
|
+
override fun getDuration(viewTag: Double, promise: Promise) {
|
|
259
259
|
UiThreadUtil.runOnUiThread {
|
|
260
|
-
val view = findPlayerView(viewTag)
|
|
260
|
+
val view = findPlayerView(viewTag.toInt())
|
|
261
261
|
if (view != null) {
|
|
262
262
|
val duration = view.getDuration()
|
|
263
263
|
promise.resolve(duration)
|
|
@@ -268,9 +268,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
@ReactMethod
|
|
271
|
-
override fun getCurrentTime(viewTag:
|
|
271
|
+
override fun getCurrentTime(viewTag: Double, promise: Promise) {
|
|
272
272
|
UiThreadUtil.runOnUiThread {
|
|
273
|
-
val view = findPlayerView(viewTag)
|
|
273
|
+
val view = findPlayerView(viewTag.toInt())
|
|
274
274
|
if (view != null) {
|
|
275
275
|
val currentTime = view.getCurrentTime()
|
|
276
276
|
promise.resolve(currentTime)
|
|
@@ -281,9 +281,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
@ReactMethod
|
|
284
|
-
override fun getMuted(viewTag:
|
|
284
|
+
override fun getMuted(viewTag: Double, promise: Promise) {
|
|
285
285
|
UiThreadUtil.runOnUiThread {
|
|
286
|
-
val view = findPlayerView(viewTag)
|
|
286
|
+
val view = findPlayerView(viewTag.toInt())
|
|
287
287
|
if (view != null) {
|
|
288
288
|
val muted = view.getMuted()
|
|
289
289
|
promise.resolve(muted)
|
|
@@ -294,9 +294,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
@ReactMethod
|
|
297
|
-
override fun getVolume(viewTag:
|
|
297
|
+
override fun getVolume(viewTag: Double, promise: Promise) {
|
|
298
298
|
UiThreadUtil.runOnUiThread {
|
|
299
|
-
val view = findPlayerView(viewTag)
|
|
299
|
+
val view = findPlayerView(viewTag.toInt())
|
|
300
300
|
if (view != null) {
|
|
301
301
|
val volume = view.getVolume()
|
|
302
302
|
promise.resolve(volume)
|
|
@@ -307,9 +307,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
@ReactMethod
|
|
310
|
-
override fun getPhase(viewTag:
|
|
310
|
+
override fun getPhase(viewTag: Double, promise: Promise) {
|
|
311
311
|
UiThreadUtil.runOnUiThread {
|
|
312
|
-
val view = findPlayerView(viewTag)
|
|
312
|
+
val view = findPlayerView(viewTag.toInt())
|
|
313
313
|
if (view != null) {
|
|
314
314
|
val phase = view.getPhase()
|
|
315
315
|
promise.resolve(phase?.name)
|
|
@@ -320,9 +320,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
@ReactMethod
|
|
323
|
-
override fun getState(viewTag:
|
|
323
|
+
override fun getState(viewTag: Double, promise: Promise) {
|
|
324
324
|
UiThreadUtil.runOnUiThread {
|
|
325
|
-
val view = findPlayerView(viewTag)
|
|
325
|
+
val view = findPlayerView(viewTag.toInt())
|
|
326
326
|
if (view != null) {
|
|
327
327
|
val state = view.getState()
|
|
328
328
|
promise.resolve(state?.name)
|
|
@@ -333,9 +333,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
333
333
|
}
|
|
334
334
|
|
|
335
335
|
@ReactMethod
|
|
336
|
-
override fun getMode(viewTag:
|
|
336
|
+
override fun getMode(viewTag: Double, promise: Promise) {
|
|
337
337
|
UiThreadUtil.runOnUiThread {
|
|
338
|
-
val view = findPlayerView(viewTag)
|
|
338
|
+
val view = findPlayerView(viewTag.toInt())
|
|
339
339
|
if (view != null) {
|
|
340
340
|
val mode = view.getMode()
|
|
341
341
|
promise.resolve(mode)
|
|
@@ -346,9 +346,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
@ReactMethod
|
|
349
|
-
override fun getClipData(viewTag:
|
|
349
|
+
override fun getClipData(viewTag: Double, promise: Promise) {
|
|
350
350
|
UiThreadUtil.runOnUiThread {
|
|
351
|
-
val view = findPlayerView(viewTag)
|
|
351
|
+
val view = findPlayerView(viewTag.toInt())
|
|
352
352
|
if (view != null) {
|
|
353
353
|
val clipData = view.getClipData()
|
|
354
354
|
if (clipData != null) {
|
|
@@ -369,9 +369,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
@ReactMethod
|
|
372
|
-
override fun getProjectData(viewTag:
|
|
372
|
+
override fun getProjectData(viewTag: Double, promise: Promise) {
|
|
373
373
|
UiThreadUtil.runOnUiThread {
|
|
374
|
-
val view = findPlayerView(viewTag)
|
|
374
|
+
val view = findPlayerView(viewTag.toInt())
|
|
375
375
|
if (view != null) {
|
|
376
376
|
val projectData = view.getProjectData()
|
|
377
377
|
if (projectData != null) {
|
|
@@ -390,9 +390,9 @@ class BBPlayerModule(private val reactContext: ReactApplicationContext) :
|
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
@ReactMethod
|
|
393
|
-
override fun getPlayoutData(viewTag:
|
|
393
|
+
override fun getPlayoutData(viewTag: Double, promise: Promise) {
|
|
394
394
|
UiThreadUtil.runOnUiThread {
|
|
395
|
-
val view = findPlayerView(viewTag)
|
|
395
|
+
val view = findPlayerView(viewTag.toInt())
|
|
396
396
|
if (view != null) {
|
|
397
397
|
val playoutData = view.getPlayoutData()
|
|
398
398
|
if (playoutData != null) {
|
package/ios/BBPlayerView.swift
CHANGED
|
@@ -42,9 +42,11 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
42
42
|
private var isPlaying: Bool = false
|
|
43
43
|
private var currentDuration: Double = 0.0
|
|
44
44
|
private var lastKnownTime: Double = 0.0
|
|
45
|
-
private var playbackStartTimestamp:
|
|
45
|
+
private var playbackStartTimestamp: CFTimeInterval = 0 // Use CFTimeInterval for CACurrentMediaTime
|
|
46
46
|
private var lastEmittedTime: Double = 0.0
|
|
47
47
|
private var isInFullscreen: Bool = false
|
|
48
|
+
private var backgroundObserver: NSObjectProtocol?
|
|
49
|
+
private var foregroundObserver: NSObjectProtocol?
|
|
48
50
|
// Independent Google Cast button for showing the cast picker
|
|
49
51
|
private var independentCastButton: GCKUICastButton?
|
|
50
52
|
|
|
@@ -144,6 +146,9 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
144
146
|
// Ensure this view respects its frame from React Native layout
|
|
145
147
|
self.clipsToBounds = false // Allow settings overlay to render outside bounds
|
|
146
148
|
|
|
149
|
+
// Set up lifecycle observers to pause timer when app goes to background (saves battery)
|
|
150
|
+
setupAppLifecycleObservers()
|
|
151
|
+
|
|
147
152
|
// Find the parent view controller from the responder chain
|
|
148
153
|
var parentVC: UIViewController?
|
|
149
154
|
var responder = self.next
|
|
@@ -211,8 +216,8 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
211
216
|
timeUpdateTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
|
|
212
217
|
guard let self = self, self.isPlaying else { return }
|
|
213
218
|
|
|
214
|
-
//
|
|
215
|
-
let elapsedSeconds =
|
|
219
|
+
// Use CACurrentMediaTime() instead of Date() - much more efficient (no system call overhead)
|
|
220
|
+
let elapsedSeconds = CACurrentMediaTime() - self.playbackStartTimestamp
|
|
216
221
|
let estimatedTime = self.lastKnownTime + elapsedSeconds
|
|
217
222
|
let currentTime = min(estimatedTime, self.currentDuration)
|
|
218
223
|
|
|
@@ -234,13 +239,62 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
234
239
|
timeUpdateTimer = nil
|
|
235
240
|
}
|
|
236
241
|
|
|
237
|
-
// Clean up timers and views to prevent memory leaks
|
|
242
|
+
// Clean up timers, observers, and views to prevent memory leaks
|
|
238
243
|
deinit {
|
|
239
244
|
stopTimeUpdates()
|
|
245
|
+
removeAppLifecycleObservers()
|
|
240
246
|
independentCastButton?.removeFromSuperview()
|
|
241
247
|
independentCastButton = nil
|
|
242
248
|
}
|
|
243
249
|
|
|
250
|
+
// MARK: - App Lifecycle Management (Battery Optimization)
|
|
251
|
+
|
|
252
|
+
private func setupAppLifecycleObservers() {
|
|
253
|
+
// Only set up once
|
|
254
|
+
guard backgroundObserver == nil else { return }
|
|
255
|
+
|
|
256
|
+
// Pause timer when app goes to background to save battery
|
|
257
|
+
backgroundObserver = NotificationCenter.default.addObserver(
|
|
258
|
+
forName: UIApplication.didEnterBackgroundNotification,
|
|
259
|
+
object: nil,
|
|
260
|
+
queue: .main
|
|
261
|
+
) { [weak self] _ in
|
|
262
|
+
guard let self = self else { return }
|
|
263
|
+
// Save current time before pausing timer so we can resume accurately
|
|
264
|
+
if self.isPlaying {
|
|
265
|
+
self.lastKnownTime = self.calculateCurrentTime()
|
|
266
|
+
}
|
|
267
|
+
self.stopTimeUpdates()
|
|
268
|
+
log("Timer paused - app entered background", level: .debug)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Resume timer when app comes back to foreground
|
|
272
|
+
foregroundObserver = NotificationCenter.default.addObserver(
|
|
273
|
+
forName: UIApplication.willEnterForegroundNotification,
|
|
274
|
+
object: nil,
|
|
275
|
+
queue: .main
|
|
276
|
+
) { [weak self] _ in
|
|
277
|
+
guard let self = self else { return }
|
|
278
|
+
if self.isPlaying && self.enableTimeUpdates {
|
|
279
|
+
// Reset timestamp to now for accurate time calculation after background
|
|
280
|
+
self.playbackStartTimestamp = CACurrentMediaTime()
|
|
281
|
+
self.startTimeUpdates()
|
|
282
|
+
log("Timer resumed - app entered foreground", level: .debug)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private func removeAppLifecycleObservers() {
|
|
288
|
+
if let observer = backgroundObserver {
|
|
289
|
+
NotificationCenter.default.removeObserver(observer)
|
|
290
|
+
backgroundObserver = nil
|
|
291
|
+
}
|
|
292
|
+
if let observer = foregroundObserver {
|
|
293
|
+
NotificationCenter.default.removeObserver(observer)
|
|
294
|
+
foregroundObserver = nil
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
244
298
|
func bbPlayerViewController(
|
|
245
299
|
_ controller: BBPlayerViewController, didTriggerEvent event: BBPlayerEvent
|
|
246
300
|
) {
|
|
@@ -341,7 +395,7 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
341
395
|
|
|
342
396
|
case .playing:
|
|
343
397
|
isPlaying = true
|
|
344
|
-
playbackStartTimestamp = Date()
|
|
398
|
+
playbackStartTimestamp = CACurrentMediaTime() // More efficient than Date()
|
|
345
399
|
lastEmittedTime = 0.0 // Reset to ensure immediate time update on play
|
|
346
400
|
lastKnownTime = calculateCurrentTime() // Update to ensure accuracy between events
|
|
347
401
|
startTimeUpdates()
|
|
@@ -352,21 +406,14 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
352
406
|
|
|
353
407
|
case .retractFullscreen:
|
|
354
408
|
isInFullscreen = false
|
|
355
|
-
|
|
356
|
-
//
|
|
357
|
-
if #available(iOS 16.0, *) {
|
|
358
|
-
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
|
|
359
|
-
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
|
|
360
|
-
log("Requested portrait rotation on retractFullscreen event", level: .info)
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
409
|
+
// Note: Orientation reset is handled by BBPlayerViewController.bbNativePlayerView(didTriggerRetractFullscreen:)
|
|
410
|
+
// to avoid duplicate calls which cause unnecessary CPU/GPU work
|
|
364
411
|
onDidTriggerRetractFullscreen?([:])
|
|
365
412
|
|
|
366
413
|
case .seeked(let seekOffset):
|
|
367
414
|
// Update lastKnownTime based on seek and reset playback timestamp
|
|
368
415
|
lastKnownTime = seekOffset ?? 0.0
|
|
369
|
-
playbackStartTimestamp = Date()
|
|
416
|
+
playbackStartTimestamp = CACurrentMediaTime() // More efficient than Date()
|
|
370
417
|
lastEmittedTime = 0.0 // Reset to ensure immediate time update after seek
|
|
371
418
|
onDidTriggerSeeked?(["payload": seekOffset as Any])
|
|
372
419
|
|
|
@@ -482,7 +529,8 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
482
529
|
/// iOS SDK doesn't expose direct currentTime property, so we estimate it
|
|
483
530
|
private func calculateCurrentTime() -> Double {
|
|
484
531
|
if isPlaying && playbackStartTimestamp > 0 {
|
|
485
|
-
|
|
532
|
+
// Use CACurrentMediaTime() - more efficient than Date() (no system call overhead)
|
|
533
|
+
let elapsedSeconds = CACurrentMediaTime() - playbackStartTimestamp
|
|
486
534
|
let estimatedTime = lastKnownTime + elapsedSeconds
|
|
487
535
|
return min(estimatedTime, currentDuration)
|
|
488
536
|
} else {
|
|
@@ -596,15 +644,9 @@ class BBPlayerView: UIView, BBPlayerViewControllerDelegate {
|
|
|
596
644
|
}
|
|
597
645
|
|
|
598
646
|
func exitFullscreen() {
|
|
599
|
-
// Force rotation back to portrait before exiting fullscreen
|
|
600
|
-
if #available(iOS 16.0, *) {
|
|
601
|
-
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
|
|
602
|
-
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
|
|
603
|
-
log("Requested portrait rotation before exitFullscreen", level: .info)
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
647
|
// iOS SDK Note: The iOS SDK uses exitFullScreen() method
|
|
648
|
+
// Orientation reset is handled by BBPlayerViewController.bbNativePlayerView(didTriggerRetractFullscreen:)
|
|
649
|
+
// to avoid duplicate orientation update calls which cause unnecessary CPU/GPU work
|
|
608
650
|
playerController.playerView?.player.exitFullScreen()
|
|
609
651
|
}
|
|
610
652
|
|
|
@@ -30,37 +30,8 @@ class BBPlayerViewController: UIViewController, BBNativePlayerViewDelegate {
|
|
|
30
30
|
/// Don't override preferredInterfaceOrientationForPresentation
|
|
31
31
|
/// Let the fullscreen modal (AVPlayerViewController) use its own preferred orientation
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
print("BBPlayer: refreshPlayerViewHierarchy - no playerView")
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
print("BBPlayer: Starting view hierarchy refresh")
|
|
40
|
-
|
|
41
|
-
// Force all sublayers to redraw by traversing the entire layer hierarchy
|
|
42
|
-
func refreshLayerTree(_ layer: CALayer) {
|
|
43
|
-
layer.setNeedsDisplay()
|
|
44
|
-
layer.displayIfNeeded()
|
|
45
|
-
for sublayer in layer.sublayers ?? [] {
|
|
46
|
-
refreshLayerTree(sublayer)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Refresh the entire layer tree of the player view
|
|
51
|
-
refreshLayerTree(playerView.layer)
|
|
52
|
-
|
|
53
|
-
// Force the player view and all its subviews to re-layout
|
|
54
|
-
playerView.setNeedsLayout()
|
|
55
|
-
playerView.layoutIfNeeded()
|
|
56
|
-
|
|
57
|
-
for subview in playerView.subviews {
|
|
58
|
-
subview.setNeedsLayout()
|
|
59
|
-
subview.layoutIfNeeded()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
print("BBPlayer: View hierarchy refresh complete")
|
|
63
|
-
}
|
|
33
|
+
// NOTE: Removed refreshPlayerViewHierarchy() - it was unused dead code that forced
|
|
34
|
+
// GPU redraw on every layer in the hierarchy, which would cause severe heat/battery drain
|
|
64
35
|
|
|
65
36
|
override func viewDidLayoutSubviews() {
|
|
66
37
|
super.viewDidLayoutSubviews()
|
|
@@ -308,23 +279,29 @@ class BBPlayerViewController: UIViewController, BBNativePlayerViewDelegate {
|
|
|
308
279
|
NSLog("BBPlayer: Refreshing view hierarchy after fullscreen exit")
|
|
309
280
|
|
|
310
281
|
// Reset any transforms that might be lingering from fullscreen
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
282
|
+
// Use iterative approach instead of recursion to avoid deep stack calls
|
|
283
|
+
// Only reset views that actually have non-identity transforms to save CPU
|
|
284
|
+
var viewsToProcess: [UIView] = [playerView]
|
|
285
|
+
var transformsReset = 0
|
|
286
|
+
|
|
287
|
+
while !viewsToProcess.isEmpty {
|
|
288
|
+
let view = viewsToProcess.removeLast()
|
|
289
|
+
// Only reset if transform is not already identity (avoids unnecessary work)
|
|
290
|
+
if view.transform != .identity {
|
|
291
|
+
view.transform = .identity
|
|
292
|
+
transformsReset += 1
|
|
318
293
|
}
|
|
294
|
+
viewsToProcess.append(contentsOf: view.subviews)
|
|
319
295
|
}
|
|
320
296
|
|
|
321
|
-
|
|
297
|
+
if transformsReset > 0 {
|
|
298
|
+
NSLog("BBPlayer: Reset \(transformsReset) non-identity transforms")
|
|
299
|
+
}
|
|
322
300
|
|
|
323
|
-
//
|
|
301
|
+
// Single batched layout update instead of multiple calls
|
|
324
302
|
playerView.setNeedsLayout()
|
|
325
|
-
playerView.layoutIfNeeded()
|
|
326
303
|
self.view.setNeedsLayout()
|
|
327
|
-
self.view.layoutIfNeeded()
|
|
304
|
+
self.view.layoutIfNeeded() // This will also layout playerView as it's a subview
|
|
328
305
|
|
|
329
306
|
// Log the player state for debugging
|
|
330
307
|
let player = playerView.player
|
|
@@ -5,5 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _reactNative = require("react-native");
|
|
8
|
-
|
|
8
|
+
// Use get() instead of getEnforcing() to avoid crash when module not registered
|
|
9
|
+
var _default = exports.default = _reactNative.TurboModuleRegistry.get("BBPlayerModule");
|
|
9
10
|
//# sourceMappingURL=NativeBBPlayerModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","get"],"sourceRoot":"../../../src","sources":["specs/NativeBBPlayerModule.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAmFA;AAAA,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACeC,gCAAmB,CAACC,GAAG,CAAO,gBAAgB,CAAC","ignoreList":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { TurboModuleRegistry } from "react-native";
|
|
4
|
-
|
|
4
|
+
// Use get() instead of getEnforcing() to avoid crash when module not registered
|
|
5
|
+
export default TurboModuleRegistry.get("BBPlayerModule");
|
|
5
6
|
//# sourceMappingURL=NativeBBPlayerModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","get"],"sourceRoot":"../../../src","sources":["specs/NativeBBPlayerModule.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAmFlD;AACA,eAAeA,mBAAmB,CAACC,GAAG,CAAO,gBAAgB,CAAC","ignoreList":[]}
|
|
@@ -32,6 +32,6 @@ export interface Spec extends TurboModule {
|
|
|
32
32
|
getProjectData(viewTag: number): Promise<Object | null>;
|
|
33
33
|
getPlayoutData(viewTag: number): Promise<Object | null>;
|
|
34
34
|
}
|
|
35
|
-
declare const _default: Spec;
|
|
35
|
+
declare const _default: Spec | null;
|
|
36
36
|
export default _default;
|
|
37
37
|
//# sourceMappingURL=NativeBBPlayerModule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeBBPlayerModule.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeBBPlayerModule.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"NativeBBPlayerModule.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeBBPlayerModule.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bluebillywig/react-native-bb-player",
|
|
3
|
-
"version": "8.42.
|
|
3
|
+
"version": "8.42.14",
|
|
4
4
|
"description": "Blue Billywig Native Video Player for React Native - iOS AVPlayer and Android ExoPlayer integration",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -79,10 +79,10 @@
|
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@types/react": "~19.
|
|
82
|
+
"@types/react": "~19.2.0",
|
|
83
83
|
"expo": "~51.0.0",
|
|
84
|
-
"react": "19.
|
|
85
|
-
"react-native": "0.
|
|
84
|
+
"react": "19.2.0",
|
|
85
|
+
"react-native": "0.83.1",
|
|
86
86
|
"react-native-builder-bob": "^0.31.0",
|
|
87
87
|
"typedoc": "^0.28.16",
|
|
88
88
|
"typedoc-plugin-markdown": "^4.9.0",
|
|
@@ -82,4 +82,5 @@ export interface Spec extends TurboModule {
|
|
|
82
82
|
getPlayoutData(viewTag: number): Promise<Object | null>;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
// Use get() instead of getEnforcing() to avoid crash when module not registered
|
|
86
|
+
export default TurboModuleRegistry.get<Spec>("BBPlayerModule");
|