expo-libvlc-player 7.0.21 → 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 +3 -3
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +1 -4
- package/android/src/main/java/expo/modules/libvlcplayer/managers/MediaPlayerManager.kt +10 -2
- package/build/LibVlcPlayerView.js.map +1 -1
- package/ios/LibVlcPlayerView.swift +12 -26
- package/ios/Managers/LocalNetworkManager.swift +33 -38
- package/ios/Managers/MediaPlayerManager.swift +4 -2
- package/ios/Utils/PictureInPictureDrawable.swift +1 -7
- package/package.json +2 -2
- package/src/LibVlcPlayerView.tsx +6 -6
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
|
|
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
|
|
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
|
|
|
@@ -577,10 +577,7 @@ class LibVlcPlayerView(
|
|
|
577
577
|
|
|
578
578
|
pauseCoroutine =
|
|
579
579
|
CoroutineScope(Dispatchers.Main).launch {
|
|
580
|
-
|
|
581
|
-
delay(MediaPlayerConstants.PAUSE_DELAY_MS)
|
|
582
|
-
}
|
|
583
|
-
|
|
580
|
+
delay(MediaPlayerConstants.PAUSE_DELAY_MS)
|
|
584
581
|
mediaPlayer?.pause()
|
|
585
582
|
}
|
|
586
583
|
}
|
|
@@ -43,14 +43,22 @@ object MediaPlayerManager {
|
|
|
43
43
|
fun onModuleForeground() {
|
|
44
44
|
expoViews.forEach { view ->
|
|
45
45
|
view.onForeground(Unit)
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
if (view.pictureInPicture) {
|
|
48
|
+
view.cancelPauseJob()
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
fun onModuleBackground() {
|
|
51
54
|
expoViews.forEach { view ->
|
|
52
55
|
view.onBackground(Unit)
|
|
53
|
-
|
|
56
|
+
|
|
57
|
+
if (view.pictureInPicture) {
|
|
58
|
+
view.pauseJob()
|
|
59
|
+
} else {
|
|
60
|
+
view.pause()
|
|
61
|
+
}
|
|
54
62
|
}
|
|
55
63
|
}
|
|
56
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
|
|
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
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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,15 +465,6 @@ class LibVlcPlayerView: ExpoView {
|
|
|
470
465
|
}
|
|
471
466
|
}
|
|
472
467
|
|
|
473
|
-
func seekZero() {
|
|
474
|
-
guard let player = mediaPlayer,
|
|
475
|
-
!player.isPlaying
|
|
476
|
-
else { return }
|
|
477
|
-
|
|
478
|
-
// Black screen workaround
|
|
479
|
-
player.time = VLCTime(int: Int32(player.time.intValue))
|
|
480
|
-
}
|
|
481
|
-
|
|
482
468
|
func record(_ path: String?) {
|
|
483
469
|
if let player = mediaPlayer {
|
|
484
470
|
if let path {
|
|
@@ -548,7 +534,7 @@ class LibVlcPlayerView: ExpoView {
|
|
|
548
534
|
}
|
|
549
535
|
|
|
550
536
|
func onStopPictureInPicture() {
|
|
551
|
-
|
|
537
|
+
pauseReset()
|
|
552
538
|
onPictureInPictureStop()
|
|
553
539
|
}
|
|
554
540
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
class LocalNetworkManager {
|
|
2
2
|
static let shared = LocalNetworkManager()
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
39
|
+
"expo": "~55.0.20",
|
|
40
40
|
"husky": "^9.1.7",
|
|
41
41
|
"lint-staged": "^16.4.0",
|
|
42
42
|
"prettier": "^3.8.3",
|
package/src/LibVlcPlayerView.tsx
CHANGED
|
@@ -5,16 +5,16 @@ import { View } from "react-native";
|
|
|
5
5
|
import {
|
|
6
6
|
type LibVlcPlayerViewNativeProps,
|
|
7
7
|
type LibVlcPlayerViewProps,
|
|
8
|
-
type
|
|
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
|
|
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";
|