expo-libvlc-player 7.0.20 → 7.0.22

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/README.md CHANGED
@@ -289,13 +289,13 @@ interface MediaInfo {
289
289
 
290
290
  On Android, the `libvlcjni` player detaches from the View after switching screens.
291
291
 
292
- The current workaround attaches the View back but it causes a brief black screen.
292
+ The current workaround attaches the View back but this causes a brief black screen.
293
293
 
294
294
  https://code.videolan.org/videolan/vlc-android/-/issues/1495
295
295
 
296
- On iOS, the `VLCKit` player deselects the video track after switching screens.
296
+ On iOS, the `VLCKit` player deselects the current video track after switching screens.
297
297
 
298
- The current workaround selects the video track back but it causes a brief black screen.
298
+ The current workaround selects the previous video track but this causes a brief black screen.
299
299
 
300
300
  https://code.videolan.org/videolan/VLCKit/-/issues/743
301
301
 
@@ -63,7 +63,6 @@ class LibVlcPlayerView(
63
63
 
64
64
  var firstPlay: Boolean = true
65
65
  private var shouldInit: Boolean = true
66
- var isInBackground: Boolean = false
67
66
 
68
67
  val onBuffering by EventDispatcher<Unit>()
69
68
  val onPlaying by EventDispatcher<Unit>()
@@ -578,10 +577,7 @@ class LibVlcPlayerView(
578
577
 
579
578
  pauseCoroutine =
580
579
  CoroutineScope(Dispatchers.Main).launch {
581
- if (pictureInPicture) {
582
- delay(MediaPlayerConstants.PAUSE_DELAY_MS)
583
- }
584
-
580
+ delay(MediaPlayerConstants.PAUSE_DELAY_MS)
585
581
  mediaPlayer?.pause()
586
582
  }
587
583
  }
@@ -42,17 +42,23 @@ object MediaPlayerManager {
42
42
 
43
43
  fun onModuleForeground() {
44
44
  expoViews.forEach { view ->
45
- view.isInBackground = false
46
45
  view.onForeground(Unit)
47
- view.cancelPauseJob()
46
+
47
+ if (view.pictureInPicture) {
48
+ view.cancelPauseJob()
49
+ }
48
50
  }
49
51
  }
50
52
 
51
53
  fun onModuleBackground() {
52
54
  expoViews.forEach { view ->
53
- view.isInBackground = true
54
55
  view.onBackground(Unit)
55
- view.pauseJob()
56
+
57
+ if (view.pictureInPicture) {
58
+ view.pauseJob()
59
+ } else {
60
+ view.pause()
61
+ }
56
62
  }
57
63
  }
58
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { useRef, type ComponentType } from \"react\";\nimport { View } from \"react-native\";\n\nimport {\n type LibVlcPlayerViewNativeProps,\n type LibVlcPlayerViewProps,\n type Dialog,\n type Error,\n type MediaInfo,\n type MediaTracks,\n type NativeEvent,\n type Position,\n type Recording,\n type Snapshot,\n type Time,\n type VideoAspectRatio,\n} from \"./LibVlcPlayer.types\";\nimport { convertAspectRatio } from \"./utils/aspect\";\nimport { parseNativeSource } from \"./utils/assets\";\nimport { convertNativeEvent } from \"./utils/events\";\n\nconst NativeView: ComponentType<LibVlcPlayerViewNativeProps> =\n requireNativeView(\"ExpoLibVlcPlayer\");\n\nconst RENDERING_CHILDREN_WARNING =\n \"The <LibVlcPlayerView> component does not support children. This may lead to inconsistent behaviour or crashes. If you want to render content on top of the LibVlcPlayer, consider using absolute positioning.\";\n\nlet loggedRenderingChildrenWarning = false;\n\nconst FALLBACK_RATIO = 16 / 9;\n\nconst LibVlcPlayerView = ({ ref, ...props }: LibVlcPlayerViewProps) => {\n const defaultRatio = useRef<VideoAspectRatio>(FALLBACK_RATIO);\n\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(RENDERING_CHILDREN_WARNING);\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onEncounteredError) {\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onDialogDisplay) {\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onTimeChanged) {\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onPositionChanged) {\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onESAdded) {\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onRecordChanged) {\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onSnapshotTaken) {\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n const nativeEvent = convertNativeEvent(event);\n const mediaRatio = nativeEvent.width / nativeEvent.height;\n\n if (props.onFirstPlay) {\n props.onFirstPlay(nativeEvent);\n }\n\n defaultRatio.current = mediaRatio || FALLBACK_RATIO;\n };\n\n const propRatio = props.aspectRatio;\n const aspectRatio = propRatio === \"auto\" ? defaultRatio.current : propRatio;\n const nativeRatio = convertAspectRatio(aspectRatio);\n\n return (\n <View style={[props.style, { aspectRatio: nativeRatio }]}>\n <NativeView\n {...props}\n ref={ref}\n style={[props.style, { height: \"100%\" }]}\n source={parseNativeSource(props.source)}\n slaves={props.slaves?.map((slave) => ({\n ...slave,\n source: parseNativeSource(slave.source),\n }))}\n onEncounteredError={onEncounteredError}\n onDialogDisplay={onDialogDisplay}\n onTimeChanged={onTimeChanged}\n onPositionChanged={onPositionChanged}\n onESAdded={onESAdded}\n onRecordChanged={onRecordChanged}\n onSnapshotTaken={onSnapshotTaken}\n onFirstPlay={onFirstPlay}\n />\n </View>\n );\n};\n\nexport default LibVlcPlayerView;\n"]}
1
+ {"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { useRef, type ComponentType } from \"react\";\nimport { View } from \"react-native\";\n\nimport {\n type LibVlcPlayerViewNativeProps,\n type LibVlcPlayerViewProps,\n type VideoAspectRatio,\n type NativeEvent,\n type Error,\n type Dialog,\n type Time,\n type Position,\n type MediaTracks,\n type Recording,\n type Snapshot,\n type MediaInfo,\n} from \"./LibVlcPlayer.types\";\nimport { convertAspectRatio } from \"./utils/aspect\";\nimport { parseNativeSource } from \"./utils/assets\";\nimport { convertNativeEvent } from \"./utils/events\";\n\nconst NativeView: ComponentType<LibVlcPlayerViewNativeProps> =\n requireNativeView(\"ExpoLibVlcPlayer\");\n\nconst RENDERING_CHILDREN_WARNING =\n \"The <LibVlcPlayerView> component does not support children. This may lead to inconsistent behaviour or crashes. If you want to render content on top of the LibVlcPlayer, consider using absolute positioning.\";\n\nlet loggedRenderingChildrenWarning = false;\n\nconst FALLBACK_RATIO = 16 / 9;\n\nconst LibVlcPlayerView = ({ ref, ...props }: LibVlcPlayerViewProps) => {\n const defaultRatio = useRef<VideoAspectRatio>(FALLBACK_RATIO);\n\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(RENDERING_CHILDREN_WARNING);\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onEncounteredError) {\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onDialogDisplay) {\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onTimeChanged) {\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onPositionChanged) {\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onESAdded) {\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onRecordChanged) {\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onSnapshotTaken) {\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n const nativeEvent = convertNativeEvent(event);\n const mediaRatio = nativeEvent.width / nativeEvent.height;\n\n if (props.onFirstPlay) {\n props.onFirstPlay(nativeEvent);\n }\n\n defaultRatio.current = mediaRatio || FALLBACK_RATIO;\n };\n\n const propRatio = props.aspectRatio;\n const aspectRatio = propRatio === \"auto\" ? defaultRatio.current : propRatio;\n const nativeRatio = convertAspectRatio(aspectRatio);\n\n return (\n <View style={[props.style, { aspectRatio: nativeRatio }]}>\n <NativeView\n {...props}\n ref={ref}\n style={[props.style, { height: \"100%\" }]}\n source={parseNativeSource(props.source)}\n slaves={props.slaves?.map((slave) => ({\n ...slave,\n source: parseNativeSource(slave.source),\n }))}\n onEncounteredError={onEncounteredError}\n onDialogDisplay={onDialogDisplay}\n onTimeChanged={onTimeChanged}\n onPositionChanged={onPositionChanged}\n onESAdded={onESAdded}\n onRecordChanged={onRecordChanged}\n onSnapshotTaken={onSnapshotTaken}\n onFirstPlay={onFirstPlay}\n />\n </View>\n );\n};\n\nexport default LibVlcPlayerView;\n"]}
@@ -14,10 +14,10 @@ class LibVlcPlayerView: ExpoView {
14
14
  var vlcDialogRef: NSValue?
15
15
 
16
16
  var oldVolume: Int = MediaPlayerConstants.maxPlayerVolume
17
+ var isInBackground: Bool = false
17
18
 
18
19
  var firstPlay: Bool = true
19
20
  private var shouldInit: Bool = true
20
- var isInBackground: Bool = false
21
21
 
22
22
  let onBuffering = EventDispatcher()
23
23
  let onPlaying = EventDispatcher()
@@ -73,11 +73,11 @@ class LibVlcPlayerView: ExpoView {
73
73
  }
74
74
 
75
75
  func createPlayer() {
76
- library = VLCLibrary()
77
76
  let drawable = pictureInPicture
78
77
  ? pictureDrawable!
79
78
  : playerDrawable
80
79
 
80
+ library = VLCLibrary()
81
81
  mediaPlayer = VLCMediaPlayer(library: library!)
82
82
  mediaPlayer!.drawable = drawable
83
83
  mediaPlayer!.delegate = self
@@ -299,16 +299,6 @@ class LibVlcPlayerView: ExpoView {
299
299
  return CGSize(width: 0, height: 0)
300
300
  }
301
301
 
302
- func resetVideoTrack() {
303
- guard let player = mediaPlayer,
304
- let videoTrack = player.videoTracks.first(where: { track in track.isSelected }),
305
- isInBackground
306
- else { return }
307
-
308
- videoTrack.isSelected = false
309
- videoTrack.isSelectedExclusively = true
310
- }
311
-
312
302
  var hasVideoSize: Bool {
313
303
  let video = getVideoSize()
314
304
  return video.width > 0 && video.height > 0
@@ -442,10 +432,15 @@ class LibVlcPlayerView: ExpoView {
442
432
  }
443
433
 
444
434
  func pauseReset() {
445
- if !pictureInPicture {
446
- mediaPlayer?.pause()
447
- resetVideoTrack()
448
- }
435
+ guard let player = mediaPlayer,
436
+ let videoTrack = player.videoTracks.first(where: { track in track.isSelected }),
437
+ isInBackground
438
+ else { return }
439
+
440
+ player.pause()
441
+ videoTrack.isSelected = false
442
+ videoTrack.isSelectedExclusively = true
443
+ DispatchQueue.main.async { player.time = VLCTime(int: player.time.intValue) }
449
444
  }
450
445
 
451
446
  func stop() {
@@ -470,13 +465,6 @@ class LibVlcPlayerView: ExpoView {
470
465
  }
471
466
  }
472
467
 
473
- func seekZero() {
474
- if let player = mediaPlayer {
475
- // Black screen workaround
476
- player.time = VLCTime(int: Int32(player.time.intValue))
477
- }
478
- }
479
-
480
468
  func record(_ path: String?) {
481
469
  if let player = mediaPlayer {
482
470
  if let path {
@@ -546,7 +534,7 @@ class LibVlcPlayerView: ExpoView {
546
534
  }
547
535
 
548
536
  func onStopPictureInPicture() {
549
- resetVideoTrack()
537
+ pauseReset()
550
538
  onPictureInPictureStop()
551
539
  }
552
540
 
@@ -1,15 +1,14 @@
1
1
  class LocalNetworkManager {
2
2
  static let shared = LocalNetworkManager()
3
3
 
4
- // Attempts to trigger the local network privacy alert.
5
- //
6
- // This builds a list of link-local IPv6 addresses and then creates a connected
7
- // UDP socket to each in turn. Connecting a UDP socket triggers the local
8
- // network alert without actually sending any traffic.
9
- //
10
- // This is a ‘best effort’ approach, and it handles errors by ignoring them.
11
- // There’s no guarantee that it’ll actually trigger the alert (FB8711182).
12
-
4
+ /// Attempts to trigger the local network privacy alert.
5
+ ///
6
+ /// This builds a list of link-local IPv6 addresses and then creates a connected
7
+ /// UDP socket to each in turn. Connecting a UDP socket triggers the local
8
+ /// network alert without actually sending any traffic.
9
+ ///
10
+ /// This is a ‘best effort’ approach, and it handles errors by ignoring them.
11
+ /// There’s no guarantee that it’ll actually trigger the alert (FB8711182).
13
12
  func triggerNetworkAlert() {
14
13
  let addresses = selectedLinkLocalIPv6Addresses()
15
14
  for address in addresses {
@@ -25,21 +24,20 @@ class LocalNetworkManager {
25
24
  }
26
25
  }
27
26
 
28
- // Returns a selection of IPv6 addresses to connect to.
29
- //
30
- // To build this list it:
31
- //
32
- // 1. Finds the IPv6 address of every broadcast-capable interface.
33
- //
34
- // 2. Filters out all the ones that aren’t link-local.
35
- //
36
- // 3. Sets the port number to port 9, that is, the discard service. Even
37
- // though the caller won’t actually send any traffic, this ensures that it
38
- // would be discarded if it were sent.
39
- //
40
- // 4. Creates two copies of each address, and replaces the host part with a
41
- // random number.
42
-
27
+ /// Returns a selection of IPv6 addresses to connect to.
28
+ ///
29
+ /// To build this list it:
30
+ ///
31
+ /// 1. Finds the IPv6 address of every broadcast-capable interface.
32
+ ///
33
+ /// 2. Filters out all the ones that aren’t link-local.
34
+ ///
35
+ /// 3. Sets the port number to port 9, that is, the discard service. Even
36
+ /// though the caller won’t actually send any traffic, this ensures that it
37
+ /// would be discarded if it were sent.
38
+ ///
39
+ /// 4. Creates two copies of each address, and replaces the host part with a
40
+ /// random number.
43
41
  private func selectedLinkLocalIPv6Addresses() -> [sockaddr_in6] {
44
42
  let r1 = (0 ..< 8).map { _ in UInt8.random(in: 0 ... 255) }
45
43
  let r2 = (0 ..< 8).map { _ in UInt8.random(in: 0 ... 255) }
@@ -50,14 +48,13 @@ class LocalNetworkManager {
50
48
  .joined())
51
49
  }
52
50
 
53
- // Replaces the host part of an IPv6 link-local address with the supplied
54
- // value.
55
- //
56
- // In this context, _host part_ refers to the bottom 64-bits of the address,
57
- // that is, the `interface ID` as defined in Section 2.5.6 of [RFC
58
- // 4291](https://tools.ietf.org/html/rfc4291)). Thus, the host part parameter
59
- // must be exactly 8 bytes.
60
-
51
+ /// Replaces the host part of an IPv6 link-local address with the supplied
52
+ /// value.
53
+ ///
54
+ /// In this context, _host part_ refers to the bottom 64-bits of the address,
55
+ /// that is, the `interface ID` as defined in Section 2.5.6 of [RFC
56
+ /// 4291](https://tools.ietf.org/html/rfc4291)). Thus, the host part parameter
57
+ /// must be exactly 8 bytes.
61
58
  private func setIPv6LinkLocalAddressHostPart(of address: sockaddr_in6, to hostPart: [UInt8]) -> sockaddr_in6 {
62
59
  precondition(hostPart.count == 8)
63
60
  var result = address
@@ -67,17 +64,15 @@ class LocalNetworkManager {
67
64
  return result
68
65
  }
69
66
 
70
- // Returns whether the supplied IPv6 address is link-local.
71
- //
72
- // Link-local address have the fe:c0/10 prefix.
73
-
67
+ /// Returns whether the supplied IPv6 address is link-local.
68
+ ///
69
+ /// Link-local address have the fe:c0/10 prefix.
74
70
  private func isIPv6AddressLinkLocal(_ address: sockaddr_in6) -> Bool {
75
71
  address.sin6_addr.__u6_addr.__u6_addr8.0 == 0xFE
76
72
  && (address.sin6_addr.__u6_addr.__u6_addr8.1 & 0xC0) == 0x80
77
73
  }
78
74
 
79
- // Returns the IPv6 address of every broadcast-capable interface.
80
-
75
+ /// Returns the IPv6 address of every broadcast-capable interface.
81
76
  private func ipv6AddressesOfBroadcastCapableInterfaces() -> [sockaddr_in6] {
82
77
  var addrList: UnsafeMutablePointer<ifaddrs>?
83
78
  let err = getifaddrs(&addrList)
@@ -27,7 +27,6 @@ class MediaPlayerManager {
27
27
  for view in expoViews.allObjects {
28
28
  view.isInBackground = false
29
29
  view.onForeground()
30
- view.seekZero()
31
30
  }
32
31
  }
33
32
 
@@ -35,7 +34,10 @@ class MediaPlayerManager {
35
34
  for view in expoViews.allObjects {
36
35
  view.isInBackground = true
37
36
  view.onBackground()
38
- view.pauseReset()
37
+
38
+ if !view.pictureInPicture {
39
+ view.pauseReset()
40
+ }
39
41
  }
40
42
  }
41
43
  }
@@ -83,13 +83,7 @@ extension PictureInPictureDrawable: VLCPictureInPictureMediaControlling {
83
83
  }
84
84
 
85
85
  func seek(by offset: Int64, completion: (() -> Void)!) {
86
- if let player = mediaPlayer {
87
- player.time = VLCTime(int: Int32(player.time.intValue + Int32(offset)))
88
-
89
- DispatchQueue.main.async {
90
- completion()
91
- }
92
- }
86
+ mediaPlayer?.jump(withOffset: Int32(offset), completion: completion)
93
87
  }
94
88
 
95
89
  func mediaLength() -> Int64 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-libvlc-player",
3
- "version": "7.0.20",
3
+ "version": "7.0.22",
4
4
  "description": "LibVLC Player for Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -36,7 +36,7 @@
36
36
  "@types/react": "^19.2.14",
37
37
  "eslint": "^9.39.4",
38
38
  "eslint-config-universe": "^15.0.3",
39
- "expo": "~55.0.19",
39
+ "expo": "~55.0.20",
40
40
  "husky": "^9.1.7",
41
41
  "lint-staged": "^16.4.0",
42
42
  "prettier": "^3.8.3",
@@ -5,16 +5,16 @@ import { View } from "react-native";
5
5
  import {
6
6
  type LibVlcPlayerViewNativeProps,
7
7
  type LibVlcPlayerViewProps,
8
- type Dialog,
9
- type Error,
10
- type MediaInfo,
11
- type MediaTracks,
8
+ type VideoAspectRatio,
12
9
  type NativeEvent,
10
+ type Error,
11
+ type Dialog,
12
+ type Time,
13
13
  type Position,
14
+ type MediaTracks,
14
15
  type Recording,
15
16
  type Snapshot,
16
- type Time,
17
- type VideoAspectRatio,
17
+ type MediaInfo,
18
18
  } from "./LibVlcPlayer.types";
19
19
  import { convertAspectRatio } from "./utils/aspect";
20
20
  import { parseNativeSource } from "./utils/assets";