spactureai-mobile-player 1.0.31 → 1.0.33

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.
@@ -11,18 +11,53 @@ import Foundation
11
11
  import MobileVLCKit
12
12
  import NitroModules
13
13
 
14
- // MARK: - HLS / network tuning (conservative defaults; override via source headers if needed)
14
+ // MARK: - HLS / network tuning (libvlc `network-caching` / `live-caching`)
15
15
 
16
+ /// libvlc `network-caching` is a **single** input-side budget (ms). Setting it
17
+ /// to many minutes makes VLC stay in `opening` / `buffering` for a long time
18
+ /// before first frame — the default must stay small for CCTV/HLS. Opt into a
19
+ /// larger window only via `VideoConfig.bufferConfig` (forward + back sum).
16
20
  private enum VLCHLSDefaults {
17
- /// Milliseconds of media to prefetch before playback resumes.
18
- /// VLC sits buffering for at least this long after every seek, so we
19
- /// keep it small for VOD HLS (recordings) where the user expects scrub
20
- /// to land near-instantly. Bump back up if you see frequent stutter.
21
- static let networkCachingMs = 300
22
- /// Same as above but only used when libvlc tags the stream as live; our
23
- /// MediaMTX recordings are VOD, so this almost never applies. Keep it
24
- /// low so the rare live tail doesn't add seconds of pre-roll.
25
- static let liveCachingMs = 300
21
+ static let floorMs = 300
22
+ /// Default total when JS omits `bufferConfig` prioritises time-to-first-frame.
23
+ static let defaultRemoteTotalMs = 4_000
24
+ /// Per-side fallback when `bufferConfig` is present but a field is nil (1 min).
25
+ static let bufferConfigSideFallbackMs = 60_000
26
+ static let hardCapMs = 2 * 3600 * 1_000
27
+ /// First-frame watchdog: if we never leave loading, surface `error` to JS.
28
+ static let firstFrameTimeoutSeconds: TimeInterval = 45
29
+
30
+ static func networkCachingMs(for config: NativeVideoConfig, sourceURL: URL) -> Int {
31
+ let scheme = sourceURL.scheme?.lowercased() ?? ""
32
+ let isRemote =
33
+ scheme == "http" || scheme == "https" || scheme == "rtsp" || scheme == "rtsps"
34
+ guard isRemote else { return floorMs }
35
+
36
+ guard let b = config.bufferConfig else {
37
+ return min(max(floorMs, defaultRemoteTotalMs), hardCapMs)
38
+ }
39
+
40
+ let side = Double(bufferConfigSideFallbackMs)
41
+ let forward = Int(b.preferredForwardBufferDurationMs ?? b.maxBufferMs ?? side)
42
+ let back = Int(b.backBufferDurationMs ?? b.minBufferMs ?? side)
43
+ let total = max(floorMs, forward + back)
44
+ return min(total, hardCapMs)
45
+ }
46
+
47
+ static func liveCachingMs(for config: NativeVideoConfig, networkCachingMs: Int) -> Int {
48
+ if let target = config.bufferConfig?.livePlayback?.targetOffsetMs, target > 0 {
49
+ return max(floorMs, min(Int(target), networkCachingMs))
50
+ }
51
+ return networkCachingMs
52
+ }
53
+
54
+ #if DEBUG
55
+ static func log(_ message: String) {
56
+ print("[UnifiedPlayer/VLC] \(message)")
57
+ }
58
+ #else
59
+ static func log(_ message: String) {}
60
+ #endif
26
61
  }
27
62
 
28
63
  final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
@@ -60,6 +95,28 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
60
95
  /// from `VideoComponentView` when the surface attaches.
61
96
  private var wantsPlaybackWhenDrawableReady: Bool = false
62
97
 
98
+ private var loadTimeoutWorkItem: DispatchWorkItem?
99
+
100
+ /// Marshal a closure onto the main thread, executing inline if we're
101
+ /// already there. VLC's renderer (`VLCOpenGLES2VideoView`) reaches into
102
+ /// `CAEAGLLayer` to manage its OpenGL renderbuffer when the active
103
+ /// media changes (`mediaPlayer.media = ...`), the player stops, or the
104
+ /// drawable is reattached. Those CALayer mutations must happen on the
105
+ /// main thread; otherwise iOS raises
106
+ /// `_raiseExceptionForBackgroundThreadLayerPropertyModification`.
107
+ /// JS-driven lifecycle calls (release / replaceSourceAsync /
108
+ /// constructor) can land on Nitro's worker thread, so we must hop
109
+ /// before touching any `mediaPlayer.*` setter that triggers a render
110
+ /// reset.
111
+ @inline(__always)
112
+ private static func runOnMain(_ block: @escaping () -> Void) {
113
+ if Thread.isMainThread {
114
+ block()
115
+ } else {
116
+ DispatchQueue.main.async(execute: block)
117
+ }
118
+ }
119
+
63
120
  init(source: (any HybridVideoPlayerSourceSpec)) throws {
64
121
  self.source = source
65
122
  self.eventEmitter = HybridVideoPlayerEventEmitter()
@@ -199,17 +256,21 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
199
256
  }
200
257
 
201
258
  func release() {
259
+ cancelLoadTimeout()
202
260
  invalidateStallWatchdog()
203
- if mediaPlayer.isPlaying {
204
- mediaPlayer.stop()
205
- }
206
- media?.delegate = nil
261
+
262
+ // Capture the VLC objects so they survive past `self` being
263
+ // deallocated — `release()` may be called from `deinit` on a
264
+ // background thread, and the closure below has to outlive the
265
+ // `HybridVideoPlayer` instance.
266
+ let mp = mediaPlayer
267
+ let m = media
268
+ let proxy = authProxy
269
+
270
+ // Clear JS-side bookkeeping first; it doesn't touch any UIKit
271
+ // layer state and can safely run on whatever thread we're on.
207
272
  media = nil
208
- mediaPlayer.media = nil
209
- mediaPlayer.delegate = nil
210
273
  vlcDelegates = nil
211
-
212
- authProxy?.stop()
213
274
  authProxy = nil
214
275
 
215
276
  try? _eventEmitter?.clearAllListeners()
@@ -224,6 +285,21 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
224
285
  lastProgressTimeSeconds = 0
225
286
  lastProgressTickMonotonic = 0
226
287
 
288
+ // Tear down VLC on the main thread. `mp.stop()` and
289
+ // `mp.media = nil` cause `VLCOpenGLES2VideoView` to reset its
290
+ // OpenGL renderbuffer, which mutates `CAEAGLLayer.contents` —
291
+ // strictly main-thread-only. Without this hop, iOS raises
292
+ // `_raiseExceptionForBackgroundThreadLayerPropertyModification`
293
+ // whenever a player is released from a non-main queue (typical
294
+ // when the JS owner is dropped from a Nitro worker thread).
295
+ Self.runOnMain {
296
+ if mp.isPlaying { mp.stop() }
297
+ m?.delegate = nil
298
+ mp.media = nil
299
+ mp.delegate = nil
300
+ proxy?.stop()
301
+ }
302
+
227
303
  VideoManager.shared.unregister(player: self)
228
304
  }
229
305
 
@@ -238,26 +314,38 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
238
314
 
239
315
  func play() throws {
240
316
  wantsPlaybackWhenDrawableReady = true
241
- mediaPlayer.play()
317
+ let mp = mediaPlayer
318
+ Self.runOnMain { mp.play() }
242
319
  VideoManager.shared.requestAudioSessionUpdate()
243
320
  }
244
321
 
245
322
  func pause() throws {
246
323
  wantsPlaybackWhenDrawableReady = false
247
- if mediaPlayer.canPause {
248
- mediaPlayer.pause()
249
- } else {
250
- mediaPlayer.stop()
324
+ let mp = mediaPlayer
325
+ // VLC's `stop()` (the not-canPause fallback) tears down the
326
+ // renderbuffer; must be on main. Even `pause()` proper sometimes
327
+ // touches the GL view on first call after attach, so keep both
328
+ // branches on main for symmetry.
329
+ Self.runOnMain {
330
+ if mp.canPause {
331
+ mp.pause()
332
+ } else {
333
+ mp.stop()
334
+ }
251
335
  }
252
336
  VideoManager.shared.requestAudioSessionUpdate()
253
337
  }
254
338
 
255
339
  /// Called from `VideoComponentView` after `mediaPlayer.drawable` is set.
256
340
  func notifyVideoHostViewAttached() {
341
+ VLCHLSDefaults.log(
342
+ "drawable attached; wantsPlayback=\(wantsPlaybackWhenDrawableReady) state=\(String(describing: mediaPlayer.state))"
343
+ )
257
344
  if wantsPlaybackWhenDrawableReady, media != nil {
258
345
  mediaPlayer.play()
259
346
  }
260
347
  maybeFireOnLoad()
348
+ emitPlaybackState()
261
349
  }
262
350
 
263
351
  func seekBy(time: Double) throws {
@@ -293,15 +381,22 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
293
381
  promise.resolve(withResult: ())
294
382
  case .second(let newSource):
295
383
  wantsPlaybackWhenDrawableReady = false
384
+ cancelLoadTimeout()
296
385
  invalidateStallWatchdog()
297
- if mediaPlayer.isPlaying {
298
- mediaPlayer.stop()
386
+
387
+ // Tear down the previous VLC media on main — same reasoning as
388
+ // `release()`. `mediaPlayer.stop()` and `mediaPlayer.media = nil`
389
+ // both poke `VLCOpenGLES2VideoView`'s renderbuffer.
390
+ let mp = mediaPlayer
391
+ let oldMedia = media
392
+ let oldProxy = authProxy
393
+ Self.runOnMain {
394
+ if mp.isPlaying { mp.stop() }
395
+ oldMedia?.delegate = nil
396
+ mp.media = nil
397
+ oldProxy?.stop()
299
398
  }
300
- media?.delegate = nil
301
399
  media = nil
302
- mediaPlayer.media = nil
303
-
304
- authProxy?.stop()
305
400
  authProxy = nil
306
401
 
307
402
  self.source = newSource
@@ -415,7 +510,11 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
415
510
 
416
511
  let media = VLCMedia(url: mediaURL)
417
512
 
418
- applyHlsNetworkOptions(to: media)
513
+ applyHlsNetworkOptions(
514
+ to: media,
515
+ sourceURL: hybridSource.url,
516
+ videoConfig: hybridSource.config
517
+ )
419
518
 
420
519
  for (key, value) in residualHeaders {
421
520
  switch key.lowercased() {
@@ -432,7 +531,17 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
432
531
 
433
532
  media.delegate = vlcDelegates
434
533
  self.media = media
435
- mediaPlayer.media = media
534
+ // Assigning `mediaPlayer.media` causes VLC to swap the active
535
+ // `VLCOpenGLES2VideoView` renderbuffer, which mutates
536
+ // `CAEAGLLayer.contents`. Hop to main so the layer write is on
537
+ // the main thread. We capture `mediaPlayer` and the new `media`
538
+ // by value so the assignment is safe even if `self` is dropped
539
+ // before the dispatched block runs.
540
+ let mp = mediaPlayer
541
+ let mediaToAttach = media
542
+ Self.runOnMain {
543
+ mp.media = mediaToAttach
544
+ }
436
545
 
437
546
  if !hasFiredOnLoadStart {
438
547
  hasFiredOnLoadStart = true
@@ -450,6 +559,8 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
450
559
  status = .loading
451
560
  setBuffering(true)
452
561
  hasEmittedEndForCurrentItem = false
562
+ emitPlaybackState()
563
+ scheduleLoadTimeout()
453
564
  }
454
565
 
455
566
  /// Rewrite an http(s) URL to point at the local auth proxy on
@@ -467,11 +578,68 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
467
578
  return components.url
468
579
  }
469
580
 
470
- private func applyHlsNetworkOptions(to media: VLCMedia) {
471
- media.addOption(":network-caching=\(VLCHLSDefaults.networkCachingMs)")
472
- media.addOption(":live-caching=\(VLCHLSDefaults.liveCachingMs)")
581
+ private func applyHlsNetworkOptions(
582
+ to media: VLCMedia,
583
+ sourceURL: URL,
584
+ videoConfig: NativeVideoConfig
585
+ ) {
586
+ let scheme = sourceURL.scheme?.lowercased() ?? ""
587
+ let networkMs = VLCHLSDefaults.networkCachingMs(for: videoConfig, sourceURL: sourceURL)
588
+ let liveMs = VLCHLSDefaults.liveCachingMs(for: videoConfig, networkCachingMs: networkMs)
589
+ media.addOption(":network-caching=\(networkMs)")
590
+ media.addOption(":live-caching=\(liveMs)")
473
591
  // HLS over HTTP benefits from reconnect; harmless for file URLs.
474
592
  media.addOption(":http-reconnect=true")
593
+
594
+ // RTSP: UDP can be blocked on cellular / Wi‑Fi guest; TCP interleaved is
595
+ // the reliable default for CCTV / NVR streams.
596
+ if scheme == "rtsp" || scheme == "rtsps" {
597
+ media.addOption(":rtsp-tcp")
598
+ }
599
+
600
+ // HLS: libvlc may issue many small GETs (master + variant index.m3u8).
601
+ // Keep-alive amortizes TLS/TCP handshakes. Parallel segment threads help
602
+ // time-to-first-frame once a variant is selected. (Master still lists
603
+ // every variant; fastest fix for huge masters is pointing the URI at a
604
+ // single media playlist from the app.)
605
+ let path = sourceURL.absoluteString.lowercased()
606
+ if path.contains(".m3u8") {
607
+ media.addOption(":http-keep-alive=true")
608
+ media.addOption(":hls-segment-threads=2")
609
+ }
610
+
611
+ VLCHLSDefaults.log(
612
+ "options url=\(sourceURL.absoluteString) scheme=\(scheme) network-caching=\(networkMs) live-caching=\(liveMs)"
613
+ )
614
+ }
615
+
616
+ private func scheduleLoadTimeout() {
617
+ cancelLoadTimeout()
618
+ let item = DispatchWorkItem { [weak self] in
619
+ guard let self else { return }
620
+ guard self.media != nil else { return }
621
+ guard !self.hasFiredOnLoad else { return }
622
+ let vlcState = self.mediaPlayer.state
623
+ if vlcState == .playing || vlcState == .paused {
624
+ return
625
+ }
626
+ VLCHLSDefaults.log(
627
+ "first-frame timeout (state=\(String(describing: vlcState)) isPlaying=\(self.mediaPlayer.isPlaying))"
628
+ )
629
+ self.setBuffering(false)
630
+ self.status = .error
631
+ self.emitPlaybackState()
632
+ }
633
+ loadTimeoutWorkItem = item
634
+ DispatchQueue.main.asyncAfter(
635
+ deadline: .now() + VLCHLSDefaults.firstFrameTimeoutSeconds,
636
+ execute: item
637
+ )
638
+ }
639
+
640
+ private func cancelLoadTimeout() {
641
+ loadTimeoutWorkItem?.cancel()
642
+ loadTimeoutWorkItem = nil
475
643
  }
476
644
 
477
645
  /// Resets stall-watchdog liveness so a long seek / buffer gap is not mistaken for a dead stream.
@@ -482,17 +650,26 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
482
650
  private func applySeek(seconds target: Double) {
483
651
  let ms = Int32(min(Double(Int32.max), max(0, target * 1000.0)))
484
652
 
485
- if mediaPlayer.isSeekable {
486
- mediaPlayer.time = VLCTime(int: ms)
653
+ // VLC's seek can prompt the demuxer to re-attach segments and
654
+ // refresh the renderbuffer (especially for HLS where a seek
655
+ // jumps to a different .ts segment). Marshal onto main so any
656
+ // resulting CALayer write happens there. We capture the player
657
+ // by value so the dispatch is safe even if the JS owner is
658
+ // released before the block fires.
659
+ let mp = mediaPlayer
660
+ let totalMs = Double(media?.length.intValue ?? 0)
661
+ let isSeekable = mediaPlayer.isSeekable
662
+
663
+ if isSeekable {
487
664
  pendingSeekSeconds = nil
665
+ Self.runOnMain { mp.time = VLCTime(int: ms) }
488
666
  return
489
667
  }
490
668
 
491
- let totalMs = Double(media?.length.intValue ?? 0)
492
669
  if totalMs > 0 {
493
670
  let position = Float(min(1.0, (Double(ms)) / totalMs))
494
- mediaPlayer.position = position
495
671
  pendingSeekSeconds = nil
672
+ Self.runOnMain { mp.position = position }
496
673
  } else {
497
674
  pendingSeekSeconds = target
498
675
  }
@@ -500,6 +677,7 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
500
677
 
501
678
  private func handleStateChange() {
502
679
  let state = mediaPlayer.state
680
+ VLCHLSDefaults.log("stateChange -> \(String(describing: state))")
503
681
  switch state {
504
682
  case .opening:
505
683
  status = .loading
@@ -513,6 +691,7 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
513
691
  }
514
692
 
515
693
  case .playing:
694
+ cancelLoadTimeout()
516
695
  setBuffering(false)
517
696
  status = .readytoplay
518
697
  maybeFireOnLoad()
@@ -523,6 +702,7 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
523
702
  case .paused:
524
703
  setBuffering(false)
525
704
  if status == .loading { status = .readytoplay }
705
+ maybeFireOnLoad()
526
706
  VideoManager.shared.requestAudioSessionUpdate()
527
707
 
528
708
  case .stopped, .ended:
@@ -538,6 +718,7 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
538
718
  }
539
719
 
540
720
  case .error:
721
+ cancelLoadTimeout()
541
722
  setBuffering(false)
542
723
  status = .error
543
724
  // JS layer maps `error` status → `onError` (see VideoPlayer.ts).
@@ -590,13 +771,22 @@ final class HybridVideoPlayer: HybridVideoPlayerSpec, VLCPlaybackDelegateOwner {
590
771
  let hasDuration = dur.isFinite && dur > 0
591
772
  let size = mediaPlayer.videoSize
592
773
  let hasVideo = size.width > 0 && size.height > 0
774
+ let state = mediaPlayer.state
593
775
  // VOD HLS from MediaMTX may keep length at 0 until the playlist is fully
594
776
  // parsed; still emit onLoad once we are playing or have decoded dimensions
595
777
  // so JS overlays (e.g. preroll spinner) can clear.
596
- if !hasDuration && !mediaPlayer.isPlaying && !hasVideo {
778
+ let hasBasicReadiness =
779
+ hasDuration || mediaPlayer.isPlaying || hasVideo
780
+ // First paint: VLC can report 0×0 video size and unknown duration while
781
+ // already past demux (paused autoplay, or drawable attached a frame late).
782
+ let demuxPastOpen =
783
+ state == .playing || state == .paused || state == .buffering
784
+ let relaxedReadiness = (media?.isParsed == true) && demuxPastOpen
785
+ if !hasBasicReadiness && !relaxedReadiness {
597
786
  return
598
787
  }
599
788
  hasFiredOnLoad = true
789
+ cancelLoadTimeout()
600
790
  let width = Double(size.width)
601
791
  let height = Double(size.height)
602
792
  let orientation: VideoOrientation =
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  import * as React from 'react';
4
+ import { ActivityIndicator, StyleSheet, View } from 'react-native';
4
5
  import { NitroModules } from 'react-native-nitro-modules';
5
6
  import { tryParseNativeVideoError, VideoComponentError, VideoError } from "../types/VideoError.js";
6
7
  import { NativeVideoView } from './NativeVideoView';
7
- import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  let nitroIdCounter = 1;
9
10
  const VideoViewViewManagerFactory = NitroModules.createHybridObject('VideoViewViewManagerFactory');
10
11
  const wrapNativeViewManagerFunction = (manager, func) => {
@@ -50,6 +51,8 @@ const VideoView = /*#__PURE__*/React.forwardRef(({
50
51
  fullscreen = false,
51
52
  paused,
52
53
  speed,
54
+ showLoadingIndicator = false,
55
+ loadingIndicatorColor,
53
56
  onPictureInPictureChange,
54
57
  onFullscreenChange,
55
58
  willEnterFullscreen,
@@ -61,6 +64,37 @@ const VideoView = /*#__PURE__*/React.forwardRef(({
61
64
  const nitroId = React.useMemo(() => nitroIdCounter++, []);
62
65
  const nitroViewManager = React.useRef(null);
63
66
  const [isManagerReady, setIsManagerReady] = React.useState(false);
67
+ const [hasLoadedMedia, setHasLoadedMedia] = React.useState(false);
68
+ const [isBuffering, setIsBuffering] = React.useState(false);
69
+ const [playerStatus, setPlayerStatus] = React.useState(player.status);
70
+ React.useEffect(() => {
71
+ if (!showLoadingIndicator) {
72
+ return;
73
+ }
74
+ setPlayerStatus(player.status);
75
+ setHasLoadedMedia(player.status === 'readyToPlay');
76
+ const onLoadStart = () => {
77
+ setHasLoadedMedia(false);
78
+ setIsBuffering(true);
79
+ };
80
+ const onLoad = () => {
81
+ setHasLoadedMedia(true);
82
+ setIsBuffering(false);
83
+ };
84
+ const onBuffer = buffering => setIsBuffering(buffering);
85
+ const onStatus = status => setPlayerStatus(status);
86
+ const subLoadStart = player.addEventListener('onLoadStart', onLoadStart);
87
+ const subLoad = player.addEventListener('onLoad', onLoad);
88
+ const subBuffer = player.addEventListener('onBuffer', onBuffer);
89
+ const subStatus = player.addEventListener('onStatusChange', onStatus);
90
+ return () => {
91
+ subLoadStart.remove();
92
+ subLoad.remove();
93
+ subBuffer.remove();
94
+ subStatus.remove();
95
+ };
96
+ }, [player, showLoadingIndicator]);
97
+ const showNativeSpinner = showLoadingIndicator && playerStatus !== 'error' && playerStatus !== 'idle' && (!hasLoadedMedia || isBuffering);
64
98
  const setupViewManager = React.useCallback(id => {
65
99
  try {
66
100
  if (nitroViewManager.current === null) {
@@ -250,12 +284,38 @@ const VideoView = /*#__PURE__*/React.forwardRef(({
250
284
  console.warn('[UnifiedPlayer] Failed to change fullscreen state:', error);
251
285
  }
252
286
  }, [fullscreen, isManagerReady]);
253
- return /*#__PURE__*/_jsx(NativeVideoView, {
254
- nitroId: nitroId,
255
- onNitroIdChange: onNitroIdChange,
256
- ...props
287
+ if (!showLoadingIndicator) {
288
+ return /*#__PURE__*/_jsx(NativeVideoView, {
289
+ nitroId: nitroId,
290
+ onNitroIdChange: onNitroIdChange,
291
+ ...props
292
+ });
293
+ }
294
+ return /*#__PURE__*/_jsxs(View, {
295
+ style: props.style,
296
+ collapsable: false,
297
+ children: [/*#__PURE__*/_jsx(NativeVideoView, {
298
+ nitroId: nitroId,
299
+ onNitroIdChange: onNitroIdChange,
300
+ ...props,
301
+ style: StyleSheet.absoluteFill
302
+ }), showNativeSpinner ? /*#__PURE__*/_jsx(View, {
303
+ style: styles.loadingOverlay,
304
+ pointerEvents: "none",
305
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
306
+ size: "large",
307
+ color: loadingIndicatorColor
308
+ })
309
+ }) : null]
257
310
  });
258
311
  });
312
+ const styles = StyleSheet.create({
313
+ loadingOverlay: {
314
+ ...StyleSheet.absoluteFillObject,
315
+ alignItems: 'center',
316
+ justifyContent: 'center'
317
+ }
318
+ });
259
319
  VideoView.displayName = 'VideoView';
260
320
  export default /*#__PURE__*/React.memo(VideoView);
261
321
  //# sourceMappingURL=VideoView.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","NitroModules","tryParseNativeVideoError","VideoComponentError","VideoError","NativeVideoView","jsx","_jsx","nitroIdCounter","VideoViewViewManagerFactory","createHybridObject","wrapNativeViewManagerFunction","manager","func","error","updateProps","props","player","__getNativePlayer","controls","pictureInPicture","autoEnterPictureInPicture","resizeMode","keepScreenAwake","surfaceType","VideoView","forwardRef","autoplay","fullscreen","paused","speed","onPictureInPictureChange","onFullscreenChange","willEnterFullscreen","willExitFullscreen","willEnterPictureInPicture","willExitPictureInPicture","ref","nitroId","useMemo","nitroViewManager","useRef","isManagerReady","setIsManagerReady","useState","setupViewManager","useCallback","id","current","createViewManager","parsedError","code","console","warn","onNitroIdChange","event","nativeEvent","useImperativeHandle","enterFullscreen","exitFullscreen","enterPictureInPicture","exitPictureInPicture","canEnterPictureInPicture","addEventListener","callback","addOnPictureInPictureChangeListener","addOnFullscreenChangeListener","addWillEnterFullscreenListener","addWillExitFullscreenListener","addWillEnterPictureInPictureListener","addWillExitPictureInPictureListener","Error","useEffect","clearAllListeners","subscriptions","push","forEach","sub","remove","undefined","pause","play","rate","hasAutoplayedRef","prevFullscreenRef","prev","displayName","memo"],"sourceRoot":"../../../../src","sources":["core/video-view/VideoView.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","ActivityIndicator","StyleSheet","View","NitroModules","tryParseNativeVideoError","VideoComponentError","VideoError","NativeVideoView","jsx","_jsx","jsxs","_jsxs","nitroIdCounter","VideoViewViewManagerFactory","createHybridObject","wrapNativeViewManagerFunction","manager","func","error","updateProps","props","player","__getNativePlayer","controls","pictureInPicture","autoEnterPictureInPicture","resizeMode","keepScreenAwake","surfaceType","VideoView","forwardRef","autoplay","fullscreen","paused","speed","showLoadingIndicator","loadingIndicatorColor","onPictureInPictureChange","onFullscreenChange","willEnterFullscreen","willExitFullscreen","willEnterPictureInPicture","willExitPictureInPicture","ref","nitroId","useMemo","nitroViewManager","useRef","isManagerReady","setIsManagerReady","useState","hasLoadedMedia","setHasLoadedMedia","isBuffering","setIsBuffering","playerStatus","setPlayerStatus","status","useEffect","onLoadStart","onLoad","onBuffer","buffering","onStatus","subLoadStart","addEventListener","subLoad","subBuffer","subStatus","remove","showNativeSpinner","setupViewManager","useCallback","id","current","createViewManager","parsedError","code","console","warn","onNitroIdChange","event","nativeEvent","useImperativeHandle","enterFullscreen","exitFullscreen","enterPictureInPicture","exitPictureInPicture","canEnterPictureInPicture","callback","addOnPictureInPictureChangeListener","addOnFullscreenChangeListener","addWillEnterFullscreenListener","addWillExitFullscreenListener","addWillEnterPictureInPictureListener","addWillExitPictureInPictureListener","Error","clearAllListeners","subscriptions","push","forEach","sub","undefined","pause","play","rate","hasAutoplayedRef","prevFullscreenRef","prev","style","collapsable","children","absoluteFill","styles","loadingOverlay","pointerEvents","size","color","create","absoluteFillObject","alignItems","justifyContent","displayName","memo"],"sourceRoot":"../../../../src","sources":["core/video-view/VideoView.tsx"],"mappings":"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","ignoreList":[]}
@@ -38,12 +38,17 @@ export interface BufferConfig {
38
38
  * Minimum duration (ms) the player will attempt to keep buffered.
39
39
  * @default 5000
40
40
  * @platform android
41
+ * @platform ios (VLC) Back portion of `network-caching` when set; if omitted
42
+ * alongside the other buffer fields, defaults to 60s for that side. Large
43
+ * values delay first frame — prefer explicit tuning over huge defaults.
41
44
  */
42
45
  minBufferMs?: number;
43
46
  /**
44
47
  * Maximum duration (ms) the player will attempt to keep buffered.
45
48
  * @default 10000
46
49
  * @platform android
50
+ * @platform ios (VLC) Fallback for the **forward** half when
51
+ * `preferredForwardBufferDurationMs` is omitted.
47
52
  */
48
53
  maxBufferMs?: number;
49
54
  /**
@@ -61,11 +66,16 @@ export interface BufferConfig {
61
66
  /**
62
67
  * Duration (ms) of media that must be buffered before it can be played from the back buffer.
63
68
  * @platform android
69
+ * @platform ios (VLC) Back portion of libvlc `network-caching`; if omitted
70
+ * defaults to 60s when any `bufferConfig` field is set.
64
71
  */
65
72
  backBufferDurationMs?: number;
66
73
  /**
67
74
  * The preferred duration (ms) of media that the player will attempt to retain in the buffer.
68
- * @platform ios, visionOS, tvOS
75
+ * @platform ios, visionOS, tvOS — AVKit semantics where applicable.
76
+ * @platform ios (VLC / unified-player) Forward portion of libvlc `network-caching`
77
+ * (combined with `backBufferDurationMs` / `minBufferMs`). Omit all fields to use
78
+ * a small default (~4s total) for fast first frame.
69
79
  */
70
80
  preferredForwardBufferDurationMs?: number;
71
81
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"BufferConfig.d.ts","sourceRoot":"","sources":["../../../../../src/core/types/BufferConfig.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAIlC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAI9B;;;OAGG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,UAAU,CAAC;IACxC;;;OAGG;IACH,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAClD;;;OAGG;IACH,8CAA8C,CAAC,EAAE,UAAU,CAAC;CAC7D"}
1
+ {"version":3,"file":"BufferConfig.d.ts","sourceRoot":"","sources":["../../../../../src/core/types/BufferConfig.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAIlC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAI9B;;;;;;OAMG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,UAAU,CAAC;IACxC;;;OAGG;IACH,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAClD;;;OAGG;IACH,8CAA8C,CAAC,EAAE,UAAU,CAAC;CAC7D"}
@@ -68,6 +68,16 @@ export interface VideoViewProps extends Partial<VideoViewEvents>, ViewProps {
68
68
  * The playback speed of the video. Defaults to 1.0.
69
69
  */
70
70
  speed?: number;
71
+ /**
72
+ * When true, shows a centered activity indicator while the source is
73
+ * loading or the native player reports buffering (initial load and rebuffer).
74
+ * @default false
75
+ */
76
+ showLoadingIndicator?: boolean;
77
+ /**
78
+ * @platform ios
79
+ */
80
+ loadingIndicatorColor?: string;
71
81
  }
72
82
  export interface VideoViewRef {
73
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.d.ts","sourceRoot":"","sources":["../../../../../src/core/video-view/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAC3F,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,eAAe,CAAC,EAAE,SAAS;IACzE;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B;;OAEG;IACH,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC;;OAEG;IACH,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC;;;OAGG;IACH,wBAAwB,EAAE,MAAM,OAAO,CAAC;IACxC;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,KAAK,SAAS,MAAM,eAAe,EACpD,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,KAC7B,oBAAoB,CAAC;CAC3B;;AAsXD,wBAAqC"}
1
+ {"version":3,"file":"VideoView.d.ts","sourceRoot":"","sources":["../../../../../src/core/video-view/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAC3F,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,eAAe,CAAC,EAAE,SAAS;IACzE;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B;;OAEG;IACH,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC;;OAEG;IACH,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC;;;OAGG;IACH,wBAAwB,EAAE,MAAM,OAAO,CAAC;IACxC;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,KAAK,SAAS,MAAM,eAAe,EACpD,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,KAC7B,oBAAoB,CAAC;CAC3B;;AA8bD,wBAAqC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spactureai-mobile-player",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "description": "Spacture AI Mobile Player",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
@@ -43,12 +43,17 @@ export interface BufferConfig {
43
43
  * Minimum duration (ms) the player will attempt to keep buffered.
44
44
  * @default 5000
45
45
  * @platform android
46
+ * @platform ios (VLC) Back portion of `network-caching` when set; if omitted
47
+ * alongside the other buffer fields, defaults to 60s for that side. Large
48
+ * values delay first frame — prefer explicit tuning over huge defaults.
46
49
  */
47
50
  minBufferMs?: number;
48
51
  /**
49
52
  * Maximum duration (ms) the player will attempt to keep buffered.
50
53
  * @default 10000
51
54
  * @platform android
55
+ * @platform ios (VLC) Fallback for the **forward** half when
56
+ * `preferredForwardBufferDurationMs` is omitted.
52
57
  */
53
58
  maxBufferMs?: number;
54
59
  /**
@@ -66,6 +71,8 @@ export interface BufferConfig {
66
71
  /**
67
72
  * Duration (ms) of media that must be buffered before it can be played from the back buffer.
68
73
  * @platform android
74
+ * @platform ios (VLC) Back portion of libvlc `network-caching`; if omitted
75
+ * defaults to 60s when any `bufferConfig` field is set.
69
76
  */
70
77
  backBufferDurationMs?: number;
71
78
 
@@ -73,7 +80,10 @@ export interface BufferConfig {
73
80
 
74
81
  /**
75
82
  * The preferred duration (ms) of media that the player will attempt to retain in the buffer.
76
- * @platform ios, visionOS, tvOS
83
+ * @platform ios, visionOS, tvOS — AVKit semantics where applicable.
84
+ * @platform ios (VLC / unified-player) Forward portion of libvlc `network-caching`
85
+ * (combined with `backBufferDurationMs` / `minBufferMs`). Omit all fields to use
86
+ * a small default (~4s total) for fast first frame.
77
87
  */
78
88
  preferredForwardBufferDurationMs?: number;
79
89
  /**
@@ -1,5 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import type { ViewProps, ViewStyle } from 'react-native';
3
+ import {
4
+ ActivityIndicator,
5
+ StyleSheet,
6
+ View,
7
+ } from 'react-native';
3
8
  import { NitroModules } from 'react-native-nitro-modules';
4
9
  import type { ListenerSubscription } from '../../spec/nitro/VideoPlayerEventEmitter.nitro';
5
10
  import type {
@@ -14,6 +19,7 @@ import {
14
19
  VideoComponentError,
15
20
  VideoError,
16
21
  } from '../types/VideoError';
22
+ import type { VideoPlayerStatus } from '../types/VideoPlayerStatus';
17
23
  import type { VideoPlayer } from '../VideoPlayer';
18
24
  import { NativeVideoView } from './NativeVideoView';
19
25
 
@@ -81,6 +87,16 @@ export interface VideoViewProps extends Partial<VideoViewEvents>, ViewProps {
81
87
  * The playback speed of the video. Defaults to 1.0.
82
88
  */
83
89
  speed?: number;
90
+ /**
91
+ * When true, shows a centered activity indicator while the source is
92
+ * loading or the native player reports buffering (initial load and rebuffer).
93
+ * @default false
94
+ */
95
+ showLoadingIndicator?: boolean;
96
+ /**
97
+ * @platform ios
98
+ */
99
+ loadingIndicatorColor?: string;
84
100
  }
85
101
 
86
102
  export interface VideoViewRef {
@@ -173,6 +189,8 @@ const VideoView = React.forwardRef<VideoViewRef, VideoViewProps>(
173
189
  fullscreen = false,
174
190
  paused,
175
191
  speed,
192
+ showLoadingIndicator = false,
193
+ loadingIndicatorColor,
176
194
  onPictureInPictureChange,
177
195
  onFullscreenChange,
178
196
  willEnterFullscreen,
@@ -187,6 +205,47 @@ const VideoView = React.forwardRef<VideoViewRef, VideoViewProps>(
187
205
  const nitroViewManager = React.useRef<VideoViewViewManager | null>(null);
188
206
  const [isManagerReady, setIsManagerReady] = React.useState(false);
189
207
 
208
+ const [hasLoadedMedia, setHasLoadedMedia] = React.useState(false);
209
+ const [isBuffering, setIsBuffering] = React.useState(false);
210
+ const [playerStatus, setPlayerStatus] =
211
+ React.useState<VideoPlayerStatus>(player.status);
212
+
213
+ React.useEffect(() => {
214
+ if (!showLoadingIndicator) {
215
+ return;
216
+ }
217
+ setPlayerStatus(player.status);
218
+ setHasLoadedMedia(player.status === 'readyToPlay');
219
+ const onLoadStart = () => {
220
+ setHasLoadedMedia(false);
221
+ setIsBuffering(true);
222
+ };
223
+ const onLoad = () => {
224
+ setHasLoadedMedia(true);
225
+ setIsBuffering(false);
226
+ };
227
+ const onBuffer = (buffering: boolean) => setIsBuffering(buffering);
228
+ const onStatus = (status: VideoPlayerStatus) => setPlayerStatus(status);
229
+
230
+ const subLoadStart = player.addEventListener('onLoadStart', onLoadStart);
231
+ const subLoad = player.addEventListener('onLoad', onLoad);
232
+ const subBuffer = player.addEventListener('onBuffer', onBuffer);
233
+ const subStatus = player.addEventListener('onStatusChange', onStatus);
234
+
235
+ return () => {
236
+ subLoadStart.remove();
237
+ subLoad.remove();
238
+ subBuffer.remove();
239
+ subStatus.remove();
240
+ };
241
+ }, [player, showLoadingIndicator]);
242
+
243
+ const showNativeSpinner =
244
+ showLoadingIndicator &&
245
+ playerStatus !== 'error' &&
246
+ playerStatus !== 'idle' &&
247
+ (!hasLoadedMedia || isBuffering);
248
+
190
249
  const setupViewManager = React.useCallback(
191
250
  (id: number) => {
192
251
  try {
@@ -477,16 +536,45 @@ const VideoView = React.forwardRef<VideoViewRef, VideoViewProps>(
477
536
  }
478
537
  }, [fullscreen, isManagerReady]);
479
538
 
539
+ if (!showLoadingIndicator) {
540
+ return (
541
+ <NativeVideoView
542
+ nitroId={nitroId}
543
+ onNitroIdChange={onNitroIdChange}
544
+ {...props}
545
+ />
546
+ );
547
+ }
548
+
480
549
  return (
481
- <NativeVideoView
482
- nitroId={nitroId}
483
- onNitroIdChange={onNitroIdChange}
484
- {...props}
485
- />
550
+ <View style={props.style} collapsable={false}>
551
+ <NativeVideoView
552
+ nitroId={nitroId}
553
+ onNitroIdChange={onNitroIdChange}
554
+ {...props}
555
+ style={StyleSheet.absoluteFill}
556
+ />
557
+ {showNativeSpinner ? (
558
+ <View style={styles.loadingOverlay} pointerEvents="none">
559
+ <ActivityIndicator
560
+ size="large"
561
+ color={loadingIndicatorColor}
562
+ />
563
+ </View>
564
+ ) : null}
565
+ </View>
486
566
  );
487
567
  }
488
568
  );
489
569
 
570
+ const styles = StyleSheet.create({
571
+ loadingOverlay: {
572
+ ...StyleSheet.absoluteFillObject,
573
+ alignItems: 'center',
574
+ justifyContent: 'center',
575
+ },
576
+ });
577
+
490
578
  VideoView.displayName = 'VideoView';
491
579
 
492
580
  export default React.memo(VideoView);