expo-libvlc-player 0.1.63 → 0.1.65
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 +18 -18
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerModule.kt +2 -2
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +106 -4
- package/android/src/main/java/expo/modules/libvlcplayer/MediaPlayerListener.kt +6 -35
- package/build/LibVlcPlayer.types.d.ts +4 -4
- package/build/LibVlcPlayer.types.d.ts.map +1 -1
- package/build/LibVlcPlayer.types.js.map +1 -1
- package/build/LibVlcPlayerView.js +4 -4
- package/build/LibVlcPlayerView.js.map +1 -1
- package/ios/LibVlcPlayerModule.swift +2 -2
- package/ios/LibVlcPlayerView.swift +100 -4
- package/ios/MediaPlayerDelegate.swift +6 -34
- package/package.json +1 -1
- package/src/LibVlcPlayer.types.ts +4 -4
- package/src/LibVlcPlayerView.tsx +4 -4
- package/android/src/main/java/expo/modules/libvlcplayer/MediaListener.kt +0 -72
- package/ios/MediaDelegate.swift +0 -64
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ npm install expo-libvlc-player
|
|
|
28
28
|
|
|
29
29
|
### Bare React Native projects
|
|
30
30
|
|
|
31
|
-
For bare React Native projects, you must ensure that you have [installed and configured](https://docs.expo.dev/bare/installing-expo-modules/) the `expo` package
|
|
31
|
+
For bare React Native projects, you must ensure that you have [installed and configured](https://docs.expo.dev/bare/installing-expo-modules/) the `expo` package.
|
|
32
32
|
|
|
33
33
|
### Configure for Android
|
|
34
34
|
|
|
@@ -36,11 +36,11 @@ No additional configuration necessary.
|
|
|
36
36
|
|
|
37
37
|
#### Black screen issue
|
|
38
38
|
|
|
39
|
-
On Android, the `libvlcjni` player detaches from the View when
|
|
39
|
+
On Android, the `libvlcjni` player detaches from the View when the surface is destroyed after switching tabs.
|
|
40
40
|
|
|
41
41
|
This causes nothing to be displayed when coming back to the screen as native resources are released automatically.
|
|
42
42
|
|
|
43
|
-
The current workaround is to reattach the View
|
|
43
|
+
The current workaround is to reattach the View once the surface is recreated but this results in a brief black screen.
|
|
44
44
|
|
|
45
45
|
### Configure for iOS
|
|
46
46
|
|
|
@@ -50,11 +50,9 @@ Run `npx pod-install` after installing the npm package.
|
|
|
50
50
|
|
|
51
51
|
On iOS, the `MobileVLCKit` player seems to interact with the local network when playing media from external sources.
|
|
52
52
|
|
|
53
|
-
Starting in iOS 14 a clear message must be provided to the `NSLocalNetworkUsageDescription` key in the Info.plist file.
|
|
53
|
+
Starting in iOS 14, a clear message must be provided to the `NSLocalNetworkUsageDescription` key in the Info.plist file.
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
> https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy
|
|
55
|
+
https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy#Essentials
|
|
58
56
|
|
|
59
57
|
### Configuration in app config
|
|
60
58
|
|
|
@@ -91,10 +89,12 @@ You can configure `expo-libvlc-player` using its built-in config plugin if you u
|
|
|
91
89
|
import { LibVlcPlayerView } from "expo-libvlc-player";
|
|
92
90
|
|
|
93
91
|
return (
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
<View style={{ aspectRatio: 16 / 9 }}>
|
|
93
|
+
<LibVlcPlayerView
|
|
94
|
+
style={{ height: "100%" }}
|
|
95
|
+
source="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
|
|
96
|
+
/>
|
|
97
|
+
</View>
|
|
98
98
|
);
|
|
99
99
|
```
|
|
100
100
|
|
|
@@ -102,12 +102,12 @@ See the [Example App](<example/app/(tabs)/index.tsx>) for additional usage.
|
|
|
102
102
|
|
|
103
103
|
### Player methods
|
|
104
104
|
|
|
105
|
-
| Method
|
|
106
|
-
|
|
|
107
|
-
| `play()`
|
|
108
|
-
| `pause()`
|
|
109
|
-
| `stop()`
|
|
110
|
-
| `seek()`
|
|
105
|
+
| Method | Description |
|
|
106
|
+
| ------------------------ | ---------------------------------------------------------------------------- |
|
|
107
|
+
| `play()` | Starts playback of the current player |
|
|
108
|
+
| `pause()` | Pauses playback of the current player |
|
|
109
|
+
| `stop()` | Stops playback of the current player |
|
|
110
|
+
| `seek(position: number)` | Sets the position of the current player. Must be a float between `0` and `1` |
|
|
111
111
|
|
|
112
112
|
### Player props
|
|
113
113
|
|
|
@@ -141,7 +141,7 @@ The `LibVlcPlayerView` extends React Native `ViewProps` and implements its own:
|
|
|
141
141
|
| `onEndReached` | Called after the `EndReached` player event | |
|
|
142
142
|
| `onEncounteredError` | Called after the `EncounteredError` player event | `{ error: string }` |
|
|
143
143
|
| `onPositionChanged` | Called after the `PositionChanged` player event | `{ position: number }` |
|
|
144
|
-
| `
|
|
144
|
+
| `onFirstPlay` | Called after the first playing event | [`MediaInfo`](#mediainfo) |
|
|
145
145
|
| `onBackground` | Called after the player enters the background | |
|
|
146
146
|
|
|
147
147
|
### Player types
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'expo.modules.libvlcplayer'
|
|
4
|
-
version = '0.1.
|
|
4
|
+
version = '0.1.64'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -27,7 +27,7 @@ android {
|
|
|
27
27
|
namespace "expo.modules.libvlcplayer"
|
|
28
28
|
defaultConfig {
|
|
29
29
|
versionCode 1
|
|
30
|
-
versionName "0.1.
|
|
30
|
+
versionName "0.1.64"
|
|
31
31
|
consumerProguardFiles("proguard-rules.pro")
|
|
32
32
|
}
|
|
33
33
|
lintOptions {
|
|
@@ -13,7 +13,7 @@ private const val STOPPED_EVENT = "onStopped"
|
|
|
13
13
|
private const val END_REACHED_EVENT = "onEndReached"
|
|
14
14
|
private const val ENCOUNTERED_ERROR_EVENT = "onEncounteredError"
|
|
15
15
|
private const val POSITION_CHANGED_EVENT = "onPositionChanged"
|
|
16
|
-
private const val
|
|
16
|
+
private const val FIRST_PLAY_EVENT = "onFirstPlay"
|
|
17
17
|
private const val BACKGROUND_EVENT = "onBackground"
|
|
18
18
|
|
|
19
19
|
val playerEvents =
|
|
@@ -25,7 +25,7 @@ val playerEvents =
|
|
|
25
25
|
END_REACHED_EVENT,
|
|
26
26
|
ENCOUNTERED_ERROR_EVENT,
|
|
27
27
|
POSITION_CHANGED_EVENT,
|
|
28
|
-
|
|
28
|
+
FIRST_PLAY_EVENT,
|
|
29
29
|
BACKGROUND_EVENT,
|
|
30
30
|
)
|
|
31
31
|
|
|
@@ -7,7 +7,9 @@ import expo.modules.kotlin.viewevent.EventDispatcher
|
|
|
7
7
|
import expo.modules.kotlin.views.ExpoView
|
|
8
8
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
9
9
|
import expo.modules.libvlcplayer.records.MediaInfo
|
|
10
|
+
import expo.modules.libvlcplayer.records.MediaTracks
|
|
10
11
|
import expo.modules.libvlcplayer.records.Slave
|
|
12
|
+
import expo.modules.libvlcplayer.records.Track
|
|
11
13
|
import expo.modules.libvlcplayer.records.Tracks
|
|
12
14
|
import org.videolan.libvlc.LibVLC
|
|
13
15
|
import org.videolan.libvlc.Media
|
|
@@ -44,10 +46,10 @@ class LibVlcPlayerView(
|
|
|
44
46
|
internal var mediaPlayer: MediaPlayer? = null
|
|
45
47
|
internal var media: Media? = null
|
|
46
48
|
private var shouldCreate: Boolean = false
|
|
47
|
-
internal var shouldSetup: Boolean = true
|
|
48
49
|
|
|
49
50
|
internal var mediaLength: Long = 0L
|
|
50
51
|
internal var userVolume: Int = MAX_PLAYER_VOLUME
|
|
52
|
+
internal var firstPlay: Boolean = true
|
|
51
53
|
|
|
52
54
|
internal val onBuffering by EventDispatcher()
|
|
53
55
|
internal val onPlaying by EventDispatcher()
|
|
@@ -56,7 +58,7 @@ class LibVlcPlayerView(
|
|
|
56
58
|
internal val onEndReached by EventDispatcher()
|
|
57
59
|
internal val onEncounteredError by EventDispatcher()
|
|
58
60
|
internal val onPositionChanged by EventDispatcher()
|
|
59
|
-
internal val
|
|
61
|
+
internal val onFirstPlay by EventDispatcher<MediaInfo>()
|
|
60
62
|
internal val onBackground by EventDispatcher()
|
|
61
63
|
|
|
62
64
|
init {
|
|
@@ -69,6 +71,12 @@ class LibVlcPlayerView(
|
|
|
69
71
|
attachPlayer()
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
override fun onDetachedFromWindow() {
|
|
75
|
+
super.onDetachedFromWindow()
|
|
76
|
+
|
|
77
|
+
mediaPlayer?.detachViews()
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
fun createPlayer() {
|
|
73
81
|
if (!shouldCreate) {
|
|
74
82
|
return
|
|
@@ -83,7 +91,7 @@ class LibVlcPlayerView(
|
|
|
83
91
|
try {
|
|
84
92
|
media = Media(libVLC, Uri.parse(source))
|
|
85
93
|
mediaPlayer!!.setMedia(media)
|
|
86
|
-
|
|
94
|
+
media!!.release()
|
|
87
95
|
} catch (_: Exception) {
|
|
88
96
|
val error = mapOf("error" to "Invalid source, media could not be set")
|
|
89
97
|
onEncounteredError(error)
|
|
@@ -96,7 +104,6 @@ class LibVlcPlayerView(
|
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
shouldCreate = false
|
|
99
|
-
shouldSetup = true
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
fun attachPlayer() {
|
|
@@ -109,6 +116,101 @@ class LibVlcPlayerView(
|
|
|
109
116
|
}
|
|
110
117
|
}
|
|
111
118
|
|
|
119
|
+
fun setupMediaInfo() {
|
|
120
|
+
var mediaInfo = MediaInfo()
|
|
121
|
+
|
|
122
|
+
mediaPlayer?.let { player ->
|
|
123
|
+
val audioTracks = mutableListOf<Track>()
|
|
124
|
+
val audios = player.getAudioTracks()
|
|
125
|
+
|
|
126
|
+
audios?.forEach { track ->
|
|
127
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
128
|
+
audioTracks.add(trackObj)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
val videoTracks = mutableListOf<Track>()
|
|
132
|
+
val videos = player.getVideoTracks()
|
|
133
|
+
|
|
134
|
+
videos?.forEach { track ->
|
|
135
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
136
|
+
videoTracks.add(trackObj)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
val subtitleTracks = mutableListOf<Track>()
|
|
140
|
+
val subtitles = player.getSpuTracks()
|
|
141
|
+
|
|
142
|
+
subtitles?.forEach { track ->
|
|
143
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
144
|
+
subtitleTracks.add(trackObj)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
val video = player.getCurrentVideoTrack()
|
|
148
|
+
val tracks =
|
|
149
|
+
MediaTracks(
|
|
150
|
+
audio = audioTracks,
|
|
151
|
+
video = videoTracks,
|
|
152
|
+
subtitle = subtitleTracks,
|
|
153
|
+
)
|
|
154
|
+
val pLength = player.getLength()
|
|
155
|
+
val length =
|
|
156
|
+
if (pLength != -1L) {
|
|
157
|
+
pLength
|
|
158
|
+
} else {
|
|
159
|
+
0L
|
|
160
|
+
}
|
|
161
|
+
val seekable = player.isSeekable()
|
|
162
|
+
|
|
163
|
+
mediaInfo =
|
|
164
|
+
MediaInfo(
|
|
165
|
+
width = video?.width ?: 0,
|
|
166
|
+
height = video?.height ?: 0,
|
|
167
|
+
tracks = tracks,
|
|
168
|
+
duration = length.toDouble(),
|
|
169
|
+
seekable = seekable,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
mediaLength = length
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
onFirstPlay(mediaInfo)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fun setupPlayer() {
|
|
179
|
+
mediaPlayer?.let { player ->
|
|
180
|
+
setupMediaInfo()
|
|
181
|
+
setPlayerTracks()
|
|
182
|
+
|
|
183
|
+
if (volume != MAX_PLAYER_VOLUME || mute) {
|
|
184
|
+
val newVolume =
|
|
185
|
+
if (mute) {
|
|
186
|
+
MIN_PLAYER_VOLUME
|
|
187
|
+
} else {
|
|
188
|
+
volume
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
player.setVolume(newVolume)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (rate != DEFAULT_PLAYER_RATE) {
|
|
195
|
+
player.setRate(rate)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (time != DEFAULT_PLAYER_TIME) {
|
|
199
|
+
player.setTime(time.toLong())
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (scale != DEFAULT_PLAYER_SCALE) {
|
|
203
|
+
player.setScale(scale)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (aspectRatio != null) {
|
|
207
|
+
player.setAspectRatio(aspectRatio)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
firstPlay = false
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
112
214
|
fun destroyPlayer() {
|
|
113
215
|
media?.release()
|
|
114
216
|
media = null
|
|
@@ -15,40 +15,11 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
|
|
|
15
15
|
Event.Playing -> {
|
|
16
16
|
onPlaying(mapOf())
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (shouldSetup) {
|
|
21
|
-
if (volume != MAX_PLAYER_VOLUME || mute) {
|
|
22
|
-
val newVolume =
|
|
23
|
-
if (mute) {
|
|
24
|
-
MIN_PLAYER_VOLUME
|
|
25
|
-
} else {
|
|
26
|
-
volume
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
player.setVolume(newVolume)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (rate != DEFAULT_PLAYER_RATE) {
|
|
33
|
-
player.setRate(rate)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (time != DEFAULT_PLAYER_TIME) {
|
|
37
|
-
player.setTime(time.toLong())
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (scale != DEFAULT_PLAYER_SCALE) {
|
|
41
|
-
player.setScale(scale)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (aspectRatio != null) {
|
|
45
|
-
player.setAspectRatio(aspectRatio)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
setPlayerTracks()
|
|
49
|
-
|
|
50
|
-
shouldSetup = false
|
|
18
|
+
if (firstPlay) {
|
|
19
|
+
setupPlayer()
|
|
51
20
|
}
|
|
21
|
+
|
|
22
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
52
23
|
}
|
|
53
24
|
|
|
54
25
|
Event.Paused -> {
|
|
@@ -60,9 +31,9 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
|
|
|
60
31
|
Event.Stopped -> {
|
|
61
32
|
onStopped(mapOf())
|
|
62
33
|
|
|
63
|
-
|
|
34
|
+
firstPlay = true
|
|
64
35
|
|
|
65
|
-
|
|
36
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
66
37
|
}
|
|
67
38
|
|
|
68
39
|
Event.EndReached -> {
|
|
@@ -95,7 +95,7 @@ export type Position = {
|
|
|
95
95
|
/**
|
|
96
96
|
* @hidden
|
|
97
97
|
*/
|
|
98
|
-
export type
|
|
98
|
+
export type FirstPlayListener = (event: {
|
|
99
99
|
nativeEvent: MediaInfo;
|
|
100
100
|
}) => void;
|
|
101
101
|
/**
|
|
@@ -128,7 +128,7 @@ export interface LibVlcPlayerViewNativeProps {
|
|
|
128
128
|
onEndReached?: EndReachedListener;
|
|
129
129
|
onEncounteredError?: EncounteredErrorListener;
|
|
130
130
|
onPositionChanged?: PositionChangedListener;
|
|
131
|
-
|
|
131
|
+
onFirstPlay?: FirstPlayListener;
|
|
132
132
|
onBackground?: BackgroundListener;
|
|
133
133
|
}
|
|
134
134
|
export interface LibVlcPlayerViewProps extends ViewProps {
|
|
@@ -274,9 +274,9 @@ export interface LibVlcPlayerViewProps extends ViewProps {
|
|
|
274
274
|
*/
|
|
275
275
|
onPositionChanged?: (event: Position) => void;
|
|
276
276
|
/**
|
|
277
|
-
* Called after the
|
|
277
|
+
* Called after the first playing event
|
|
278
278
|
*/
|
|
279
|
-
|
|
279
|
+
onFirstPlay?: (event: MediaInfo) => void;
|
|
280
280
|
/**
|
|
281
281
|
* Called after the player enters the background
|
|
282
282
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LibVlcPlayer.types.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayer.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,QAAQ,EAAE,KAAK,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IAClC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,YAAY,GACZ,MAAM,GACN,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE;IAAE,WAAW,EAAE,KAAK,CAAA;CAAE,KAAK,IAAI,CAAC;AAE/E,MAAM,MAAM,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE;IAC5C,WAAW,EAAE,QAAQ,CAAC;CACvB,KAAK,IAAI,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"LibVlcPlayer.types.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayer.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LibVlcPlayer.types.js","sourceRoot":"","sources":["../src/LibVlcPlayer.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ViewProps } from \"react-native\";\n\nexport interface LibVlcPlayerViewRef {\n /**\n * Starts playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly play: () => Promise<void>;\n /**\n * Pauses playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly pause: () => Promise<void>;\n /**\n * Stops playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly stop: () => Promise<void>;\n /**\n * Changes position of the current player\n *\n * @param position - Must be a float between `0` and `1`\n *\n * @returns A promise which resolves to `void`\n */\n readonly seek: (position: number) => Promise<void>;\n}\n\nexport type LibVlcSource = string | number | null;\n\nexport interface Track {\n id: number;\n name: string;\n}\n\nexport interface MediaTracks {\n audio: Track[];\n video: Track[];\n subtitle: Track[];\n}\n\nexport interface MediaInfo {\n width: number;\n height: number;\n tracks: MediaTracks;\n duration: number;\n seekable: boolean;\n}\n\nexport interface Slave {\n source: NonNullable<LibVlcSource>;\n type: \"audio\" | \"subtitle\";\n}\n\nexport interface Tracks {\n audio?: number;\n video?: number;\n subtitle?: number;\n}\n\nexport type AudioMixingMode =\n | \"mixWithOthers\"\n | \"duckOthers\"\n | \"auto\"\n | \"doNotMix\";\n\n/**\n * @hidden\n */\nexport type BufferingListener = () => void;\n\n/**\n * @hidden\n */\nexport type PlayingListener = () => void;\n\n/**\n * @hidden\n */\nexport type PausedListener = () => void;\n\n/**\n * @hidden\n */\nexport type StoppedListener = () => void;\n\n/**\n * @hidden\n */\nexport type EndReachedListener = () => void;\n\n/**\n * @hidden\n */\nexport type EncounteredErrorListener = (event: { nativeEvent: Error }) => void;\n\nexport type Error = { error: string };\n\n/**\n * @hidden\n */\nexport type PositionChangedListener = (event: {\n nativeEvent: Position;\n}) => void;\n\nexport type Position = { position: number };\n\n/**\n * @hidden\n */\nexport type
|
|
1
|
+
{"version":3,"file":"LibVlcPlayer.types.js","sourceRoot":"","sources":["../src/LibVlcPlayer.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ViewProps } from \"react-native\";\n\nexport interface LibVlcPlayerViewRef {\n /**\n * Starts playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly play: () => Promise<void>;\n /**\n * Pauses playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly pause: () => Promise<void>;\n /**\n * Stops playback of the current player\n *\n * @returns A promise which resolves to `void`\n */\n readonly stop: () => Promise<void>;\n /**\n * Changes position of the current player\n *\n * @param position - Must be a float between `0` and `1`\n *\n * @returns A promise which resolves to `void`\n */\n readonly seek: (position: number) => Promise<void>;\n}\n\nexport type LibVlcSource = string | number | null;\n\nexport interface Track {\n id: number;\n name: string;\n}\n\nexport interface MediaTracks {\n audio: Track[];\n video: Track[];\n subtitle: Track[];\n}\n\nexport interface MediaInfo {\n width: number;\n height: number;\n tracks: MediaTracks;\n duration: number;\n seekable: boolean;\n}\n\nexport interface Slave {\n source: NonNullable<LibVlcSource>;\n type: \"audio\" | \"subtitle\";\n}\n\nexport interface Tracks {\n audio?: number;\n video?: number;\n subtitle?: number;\n}\n\nexport type AudioMixingMode =\n | \"mixWithOthers\"\n | \"duckOthers\"\n | \"auto\"\n | \"doNotMix\";\n\n/**\n * @hidden\n */\nexport type BufferingListener = () => void;\n\n/**\n * @hidden\n */\nexport type PlayingListener = () => void;\n\n/**\n * @hidden\n */\nexport type PausedListener = () => void;\n\n/**\n * @hidden\n */\nexport type StoppedListener = () => void;\n\n/**\n * @hidden\n */\nexport type EndReachedListener = () => void;\n\n/**\n * @hidden\n */\nexport type EncounteredErrorListener = (event: { nativeEvent: Error }) => void;\n\nexport type Error = { error: string };\n\n/**\n * @hidden\n */\nexport type PositionChangedListener = (event: {\n nativeEvent: Position;\n}) => void;\n\nexport type Position = { position: number };\n\n/**\n * @hidden\n */\nexport type FirstPlayListener = (event: { nativeEvent: MediaInfo }) => void;\n\n/**\n * @hidden\n */\nexport type BackgroundListener = () => void;\n\n/**\n * @hidden\n */\nexport interface LibVlcPlayerViewNativeProps {\n ref?: React.Ref<LibVlcPlayerViewRef>;\n source?: LibVlcSource;\n options?: string[];\n slaves?: Slave[];\n tracks?: Tracks;\n volume?: number;\n mute?: boolean;\n rate?: number;\n time?: number;\n repeat?: boolean;\n scale?: number;\n aspectRatio?: string | null;\n audioMixingMode?: AudioMixingMode;\n playInBackground?: boolean;\n autoplay?: boolean;\n onBuffering?: BufferingListener;\n onPlaying?: PlayingListener;\n onPaused?: PausedListener;\n onStopped?: StoppedListener;\n onEndReached?: EndReachedListener;\n onEncounteredError?: EncounteredErrorListener;\n onPositionChanged?: PositionChangedListener;\n onFirstPlay?: FirstPlayListener;\n onBackground?: BackgroundListener;\n}\n\nexport interface LibVlcPlayerViewProps extends ViewProps {\n /**\n * Sets the source of the media to be played\n */\n source: LibVlcSource;\n /**\n * https://wiki.videolan.org/VLC_command-line_help/\n *\n * Sets the VLC options to initialize the player with\n *\n * @example\n * ```tsx\n * <LibVlcPlayerView\n * options={[\"--network-caching=1000\"]}\n * />\n * ```\n * @default []\n */\n options?: string[];\n /**\n * Sets the player audio and subtitle slaves\n *\n * @example\n * ```tsx\n * <LibVlcPlayerView\n * slaves={[\n * {\n * source: \"file://path/to/audio.aac\",\n * type: \"audio\",\n * },\n * {\n * source: \"file://path/to/subtitle.srt\",\n * type: \"subtitle\",\n * },\n * ]}\n * />\n * ```\n */\n slaves?: Slave[];\n /**\n * Sets the player audio, video and subtitle tracks\n *\n * @example\n * ```tsx\n * <LibVlcPlayerView\n * tracks={{\n * audio: 1,\n * video: 2,\n * subtitle: -1,\n * }}\n * />\n * ```\n */\n tracks?: Tracks;\n /**\n * Sets the player volume. Must be an integer between `0` and `100`\n *\n * @default 100\n */\n volume?: number;\n /**\n * Sets the player volume to `0` when `true`\n *\n * @default false\n */\n mute?: boolean;\n /**\n * Sets the player rate. Must be a float number\n *\n * @default 1\n */\n rate?: number;\n /**\n * Sets the initial player time. Must be an integer in milliseconds\n *\n * @default 0\n */\n time?: number;\n /**\n * Determines whether the player should repeat the media after playback ends\n *\n * @default false\n */\n repeat?: boolean;\n /**\n * Sets the player scaling factor. Must be a float equal or greater than `0`\n *\n * @default 0\n */\n scale?: number;\n /**\n * Sets the player aspect ratio. Must be a valid string or `null` to reset to default\n *\n * @example \"16:9\"\n */\n aspectRatio?: string | null;\n /**\n * Determines how the player will interact with other audio playing in the system\n *\n * @default \"auto\"\n */\n audioMixingMode?: AudioMixingMode;\n /**\n * Determines whether the player should continue playing after entering the background\n *\n * @default false\n */\n playInBackground?: boolean;\n /**\n * Determines whether the media should autoplay once created\n *\n * @default true\n */\n autoplay?: boolean;\n /**\n * Called after the `Buffering` player event\n */\n onBuffering?: () => void;\n /**\n * Called after the `Playing` player event\n */\n onPlaying?: () => void;\n /**\n * Called after the `Paused` player event\n */\n onPaused?: () => void;\n /**\n * Called after the `Stopped` player event\n */\n onStopped?: () => void;\n /**\n * Called after the `EndReached` player event\n */\n onEndReached?: () => void;\n /**\n * Called after the `EncounteredError` player event\n */\n onEncounteredError?: (event: Error) => void;\n /**\n * Called after the `PositionChanged` player event\n */\n onPositionChanged?: (event: Position) => void;\n /**\n * Called after the first playing event\n */\n onFirstPlay?: (event: MediaInfo) => void;\n /**\n * Called after the player enters the background\n */\n onBackground?: () => void;\n}\n"]}
|
|
@@ -21,15 +21,15 @@ const LibVlcPlayerView = forwardRef((props, ref) => {
|
|
|
21
21
|
props.onPositionChanged(nativeEvent);
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
const
|
|
25
|
-
if (props.
|
|
26
|
-
props.
|
|
24
|
+
const onFirstPlay = ({ nativeEvent }) => {
|
|
25
|
+
if (props.onFirstPlay) {
|
|
26
|
+
props.onFirstPlay(nativeEvent);
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
return (<NativeView {...nativeProps} ref={ref} source={parseSource(props.source)} slaves={props.slaves?.map((slave) => ({
|
|
30
30
|
...slave,
|
|
31
31
|
source: parseSource(slave.source),
|
|
32
|
-
}))} onEncounteredError={onEncounteredError} onPositionChanged={onPositionChanged}
|
|
32
|
+
}))} onEncounteredError={onEncounteredError} onPositionChanged={onPositionChanged} onFirstPlay={onFirstPlay}/>);
|
|
33
33
|
});
|
|
34
34
|
export default LibVlcPlayerView;
|
|
35
35
|
//# sourceMappingURL=LibVlcPlayerView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,UAAU,EAAsB,MAAM,OAAO,CAAC;AAUvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,UAAU,GACd,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AAExC,IAAI,8BAA8B,GAAY,KAAK,CAAC;AAEpD,MAAM,gBAAgB,GAAG,UAAU,CACjC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACb,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAE9C,mBAAmB;IACnB,IAAI,WAAW,CAAC,QAAQ,IAAI,CAAC,8BAA8B,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CACV,gNAAgN,CACjN,CAAC;QACF,8BAA8B,GAAG,IAAI,CAAC;IACxC,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,EAAE,WAAW,EAA0B,EAAE,EAAE;QACrE,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC7B,KAAK,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,EAAE,WAAW,EAA6B,EAAE,EAAE;QACvE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,
|
|
1
|
+
{"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,UAAU,EAAsB,MAAM,OAAO,CAAC;AAUvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,UAAU,GACd,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AAExC,IAAI,8BAA8B,GAAY,KAAK,CAAC;AAEpD,MAAM,gBAAgB,GAAG,UAAU,CACjC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACb,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAE9C,mBAAmB;IACnB,IAAI,WAAW,CAAC,QAAQ,IAAI,CAAC,8BAA8B,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CACV,gNAAgN,CACjN,CAAC;QACF,8BAA8B,GAAG,IAAI,CAAC;IACxC,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,EAAE,WAAW,EAA0B,EAAE,EAAE;QACrE,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC7B,KAAK,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,EAAE,WAAW,EAA6B,EAAE,EAAE;QACvE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,EAAE,WAAW,EAA8B,EAAE,EAAE;QAClE,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,CAAC,UAAU,CACT,IAAI,WAAW,CAAC,CAChB,GAAG,CAAC,CAAC,GAAG,CAAC,CACT,MAAM,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAClC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpC,GAAG,KAAK;YACR,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAE;SACnC,CAAC,CAAC,CAAC,CACJ,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CACvC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,CACrC,WAAW,CAAC,CAAC,WAAW,CAAC,EACzB,CACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { forwardRef, type ComponentType } from \"react\";\n\nimport {\n LibVlcPlayerViewNativeProps,\n LibVlcPlayerViewProps,\n LibVlcPlayerViewRef,\n type Error,\n type Position,\n type MediaInfo,\n} from \"./LibVlcPlayer.types\";\nimport { parseSource } from \"./utils/assets\";\nimport { convertNativeProps } from \"./utils/props\";\n\nconst NativeView: ComponentType<LibVlcPlayerViewNativeProps> =\n requireNativeView(\"ExpoLibVlcPlayer\");\n\nlet loggedRenderingChildrenWarning: boolean = false;\n\nconst LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(\n (props, ref) => {\n const nativeProps = convertNativeProps(props);\n\n // @ts-expect-error\n if (nativeProps.children && !loggedRenderingChildrenWarning) {\n console.warn(\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 );\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = ({ nativeEvent }: { nativeEvent: Error }) => {\n if (props.onEncounteredError) {\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onPositionChanged = ({ nativeEvent }: { nativeEvent: Position }) => {\n if (props.onPositionChanged) {\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onFirstPlay = ({ nativeEvent }: { nativeEvent: MediaInfo }) => {\n if (props.onFirstPlay) {\n props.onFirstPlay(nativeEvent);\n }\n };\n\n return (\n <NativeView\n {...nativeProps}\n ref={ref}\n source={parseSource(props.source)}\n slaves={props.slaves?.map((slave) => ({\n ...slave,\n source: parseSource(slave.source)!,\n }))}\n onEncounteredError={onEncounteredError}\n onPositionChanged={onPositionChanged}\n onFirstPlay={onFirstPlay}\n />\n );\n },\n);\n\nexport default LibVlcPlayerView;\n"]}
|
|
@@ -7,7 +7,7 @@ private let stoppedEvent = "onStopped"
|
|
|
7
7
|
private let endReachedEvent = "onEndReached"
|
|
8
8
|
private let encounteredErrorEvent = "onEncounteredError"
|
|
9
9
|
private let positionChangedEvent = "onPositionChanged"
|
|
10
|
-
private let
|
|
10
|
+
private let firstPlayEvent = "onFirstPlay"
|
|
11
11
|
private let backgroundEvent = "onBackground"
|
|
12
12
|
|
|
13
13
|
let playerEvents = [
|
|
@@ -18,7 +18,7 @@ let playerEvents = [
|
|
|
18
18
|
endReachedEvent,
|
|
19
19
|
encounteredErrorEvent,
|
|
20
20
|
positionChangedEvent,
|
|
21
|
-
|
|
21
|
+
firstPlayEvent,
|
|
22
22
|
backgroundEvent,
|
|
23
23
|
]
|
|
24
24
|
|
|
@@ -15,10 +15,10 @@ class LibVlcPlayerView: ExpoView {
|
|
|
15
15
|
|
|
16
16
|
var mediaPlayer: VLCMediaPlayer?
|
|
17
17
|
private var shouldCreate: Bool = false
|
|
18
|
-
var shouldSetup: Bool = true
|
|
19
18
|
|
|
20
19
|
var mediaLength: Int32 = 0
|
|
21
20
|
private var userVolume: Int = maxPlayerVolume
|
|
21
|
+
var firstPlay: Bool = true
|
|
22
22
|
|
|
23
23
|
let onBuffering = EventDispatcher()
|
|
24
24
|
let onPlaying = EventDispatcher()
|
|
@@ -27,7 +27,7 @@ class LibVlcPlayerView: ExpoView {
|
|
|
27
27
|
let onEndReached = EventDispatcher()
|
|
28
28
|
let onEncounteredError = EventDispatcher()
|
|
29
29
|
let onPositionChanged = EventDispatcher()
|
|
30
|
-
let
|
|
30
|
+
let onFirstPlay = EventDispatcher()
|
|
31
31
|
let onBackground = EventDispatcher()
|
|
32
32
|
|
|
33
33
|
required init(appContext: AppContext? = nil) {
|
|
@@ -65,7 +65,6 @@ class LibVlcPlayerView: ExpoView {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
mediaPlayer!.media = VLCMedia(url: url)
|
|
68
|
-
mediaPlayer!.media!.delegate = self
|
|
69
68
|
|
|
70
69
|
addPlayerSlaves()
|
|
71
70
|
|
|
@@ -74,7 +73,104 @@ class LibVlcPlayerView: ExpoView {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
shouldCreate = false
|
|
77
|
-
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
func setupMediaInfo() {
|
|
79
|
+
var mediaInfo = MediaInfo()
|
|
80
|
+
|
|
81
|
+
if let player = mediaPlayer {
|
|
82
|
+
var audioTracks: [Track] = []
|
|
83
|
+
|
|
84
|
+
if let audios = player.audioTrackNames as? [String] {
|
|
85
|
+
if let audioIndexes = player.audioTrackIndexes as? [NSNumber] {
|
|
86
|
+
for (index, trackName) in audios.enumerated() {
|
|
87
|
+
let trackId = audioIndexes[index].intValue
|
|
88
|
+
let track = Track(id: trackId, name: trackName)
|
|
89
|
+
audioTracks.append(track)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var videoTracks: [Track] = []
|
|
95
|
+
|
|
96
|
+
if let videos = player.videoTrackNames as? [String] {
|
|
97
|
+
if let videoIndexes = player.videoTrackIndexes as? [NSNumber] {
|
|
98
|
+
for (index, trackName) in videos.enumerated() {
|
|
99
|
+
let trackId = videoIndexes[index].intValue
|
|
100
|
+
let track = Track(id: trackId, name: trackName)
|
|
101
|
+
videoTracks.append(track)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
var subtitleTracks: [Track] = []
|
|
107
|
+
|
|
108
|
+
if let subtitles = player.videoSubTitlesNames as? [String] {
|
|
109
|
+
if let subtitleIndexes = player.videoSubTitlesIndexes as? [NSNumber] {
|
|
110
|
+
for (index, trackName) in subtitles.enumerated() {
|
|
111
|
+
let trackId = subtitleIndexes[index].intValue
|
|
112
|
+
let track = Track(id: trackId, name: trackName)
|
|
113
|
+
subtitleTracks.append(track)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let video = player.videoSize
|
|
119
|
+
let tracks = MediaTracks(
|
|
120
|
+
audio: audioTracks,
|
|
121
|
+
video: videoTracks,
|
|
122
|
+
subtitle: subtitleTracks
|
|
123
|
+
)
|
|
124
|
+
let length = player.media?.length.intValue ?? 0
|
|
125
|
+
let seekable = player.isSeekable
|
|
126
|
+
|
|
127
|
+
mediaInfo = MediaInfo(
|
|
128
|
+
width: Int(video.width),
|
|
129
|
+
height: Int(video.height),
|
|
130
|
+
tracks: tracks,
|
|
131
|
+
duration: Double(length),
|
|
132
|
+
seekable: seekable
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
mediaLength = length
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
onFirstPlay(mediaInfo)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func setupPlayer() {
|
|
142
|
+
guard let player = mediaPlayer else { return }
|
|
143
|
+
|
|
144
|
+
setupMediaInfo()
|
|
145
|
+
setPlayerTracks()
|
|
146
|
+
|
|
147
|
+
if volume != maxPlayerVolume || mute {
|
|
148
|
+
let newVolume = mute ?
|
|
149
|
+
minPlayerVolume :
|
|
150
|
+
volume
|
|
151
|
+
|
|
152
|
+
player.audio?.volume = Int32(newVolume)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if rate != defaultPlayerRate {
|
|
156
|
+
player.rate = rate
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if time != defaultPlayerTime {
|
|
160
|
+
player.time = VLCTime(int: Int32(time))
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if scale != defaultPlayerScale {
|
|
164
|
+
player.scaleFactor = scale
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if let aspectRatio = aspectRatio {
|
|
168
|
+
aspectRatio.withCString { cString in
|
|
169
|
+
player.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
firstPlay = false
|
|
78
174
|
}
|
|
79
175
|
|
|
80
176
|
func destroyPlayer() {
|
|
@@ -10,39 +10,11 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
|
|
|
10
10
|
case .playing:
|
|
11
11
|
onPlaying([:])
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if shouldSetup {
|
|
16
|
-
if volume != maxPlayerVolume || mute {
|
|
17
|
-
let newVolume = mute ?
|
|
18
|
-
minPlayerVolume :
|
|
19
|
-
volume
|
|
20
|
-
|
|
21
|
-
player.audio?.volume = Int32(newVolume)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if rate != defaultPlayerRate {
|
|
25
|
-
player.rate = rate
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if time != defaultPlayerTime {
|
|
29
|
-
player.time = VLCTime(int: Int32(time))
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if scale != defaultPlayerScale {
|
|
33
|
-
player.scaleFactor = scale
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if let aspectRatio = aspectRatio {
|
|
37
|
-
aspectRatio.withCString { cString in
|
|
38
|
-
player.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
setPlayerTracks()
|
|
43
|
-
|
|
44
|
-
shouldSetup = false
|
|
13
|
+
if firstPlay {
|
|
14
|
+
setupPlayer()
|
|
45
15
|
}
|
|
16
|
+
|
|
17
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
46
18
|
case .paused:
|
|
47
19
|
onPaused([:])
|
|
48
20
|
|
|
@@ -50,9 +22,9 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
|
|
|
50
22
|
case .stopped:
|
|
51
23
|
onStopped([:])
|
|
52
24
|
|
|
53
|
-
|
|
25
|
+
firstPlay = true
|
|
54
26
|
|
|
55
|
-
|
|
27
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
56
28
|
case .ended:
|
|
57
29
|
onEndReached([:])
|
|
58
30
|
|
package/package.json
CHANGED
|
@@ -111,7 +111,7 @@ export type Position = { position: number };
|
|
|
111
111
|
/**
|
|
112
112
|
* @hidden
|
|
113
113
|
*/
|
|
114
|
-
export type
|
|
114
|
+
export type FirstPlayListener = (event: { nativeEvent: MediaInfo }) => void;
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* @hidden
|
|
@@ -144,7 +144,7 @@ export interface LibVlcPlayerViewNativeProps {
|
|
|
144
144
|
onEndReached?: EndReachedListener;
|
|
145
145
|
onEncounteredError?: EncounteredErrorListener;
|
|
146
146
|
onPositionChanged?: PositionChangedListener;
|
|
147
|
-
|
|
147
|
+
onFirstPlay?: FirstPlayListener;
|
|
148
148
|
onBackground?: BackgroundListener;
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -291,9 +291,9 @@ export interface LibVlcPlayerViewProps extends ViewProps {
|
|
|
291
291
|
*/
|
|
292
292
|
onPositionChanged?: (event: Position) => void;
|
|
293
293
|
/**
|
|
294
|
-
* Called after the
|
|
294
|
+
* Called after the first playing event
|
|
295
295
|
*/
|
|
296
|
-
|
|
296
|
+
onFirstPlay?: (event: MediaInfo) => void;
|
|
297
297
|
/**
|
|
298
298
|
* Called after the player enters the background
|
|
299
299
|
*/
|
package/src/LibVlcPlayerView.tsx
CHANGED
|
@@ -41,9 +41,9 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
if (props.
|
|
46
|
-
props.
|
|
44
|
+
const onFirstPlay = ({ nativeEvent }: { nativeEvent: MediaInfo }) => {
|
|
45
|
+
if (props.onFirstPlay) {
|
|
46
|
+
props.onFirstPlay(nativeEvent);
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
|
|
@@ -58,7 +58,7 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
|
58
58
|
}))}
|
|
59
59
|
onEncounteredError={onEncounteredError}
|
|
60
60
|
onPositionChanged={onPositionChanged}
|
|
61
|
-
|
|
61
|
+
onFirstPlay={onFirstPlay}
|
|
62
62
|
/>
|
|
63
63
|
);
|
|
64
64
|
},
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
package expo.modules.libvlcplayer
|
|
2
|
-
|
|
3
|
-
import expo.modules.libvlcplayer.records.MediaInfo
|
|
4
|
-
import expo.modules.libvlcplayer.records.MediaTracks
|
|
5
|
-
import expo.modules.libvlcplayer.records.Track
|
|
6
|
-
import org.videolan.libvlc.interfaces.IMedia.Event
|
|
7
|
-
import org.videolan.libvlc.interfaces.IMedia.EventListener
|
|
8
|
-
|
|
9
|
-
fun LibVlcPlayerView.setMediaListener() {
|
|
10
|
-
mediaPlayer?.let { player ->
|
|
11
|
-
media?.setEventListener(
|
|
12
|
-
EventListener { event ->
|
|
13
|
-
when (event.type) {
|
|
14
|
-
Event.ParsedChanged -> {
|
|
15
|
-
val audioTracks = mutableListOf<Track>()
|
|
16
|
-
val audios = player.getAudioTracks()
|
|
17
|
-
|
|
18
|
-
audios?.forEach { track ->
|
|
19
|
-
val trackObj = Track(id = track.id, name = track.name)
|
|
20
|
-
audioTracks.add(trackObj)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
val videoTracks = mutableListOf<Track>()
|
|
24
|
-
val videos = player.getVideoTracks()
|
|
25
|
-
|
|
26
|
-
videos?.forEach { track ->
|
|
27
|
-
val trackObj = Track(id = track.id, name = track.name)
|
|
28
|
-
videoTracks.add(trackObj)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
val subtitleTracks = mutableListOf<Track>()
|
|
32
|
-
val subtitles = player.getSpuTracks()
|
|
33
|
-
|
|
34
|
-
subtitles?.forEach { track ->
|
|
35
|
-
val trackObj = Track(id = track.id, name = track.name)
|
|
36
|
-
subtitleTracks.add(trackObj)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
val video = player.getCurrentVideoTrack()
|
|
40
|
-
val tracks =
|
|
41
|
-
MediaTracks(
|
|
42
|
-
audio = audioTracks,
|
|
43
|
-
video = videoTracks,
|
|
44
|
-
subtitle = subtitleTracks,
|
|
45
|
-
)
|
|
46
|
-
val pLength = player.getLength()
|
|
47
|
-
val length =
|
|
48
|
-
if (pLength != -1L) {
|
|
49
|
-
pLength
|
|
50
|
-
} else {
|
|
51
|
-
0L
|
|
52
|
-
}
|
|
53
|
-
val seekable = player.isSeekable()
|
|
54
|
-
|
|
55
|
-
val mediaInfo =
|
|
56
|
-
MediaInfo(
|
|
57
|
-
width = video?.width ?: 0,
|
|
58
|
-
height = video?.height ?: 0,
|
|
59
|
-
tracks = tracks,
|
|
60
|
-
duration = length.toDouble(),
|
|
61
|
-
seekable = seekable,
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
onParsedChanged(mediaInfo)
|
|
65
|
-
|
|
66
|
-
mediaLength = length
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
}
|
package/ios/MediaDelegate.swift
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import MobileVLCKit
|
|
2
|
-
|
|
3
|
-
extension LibVlcPlayerView: VLCMediaDelegate {
|
|
4
|
-
func mediaDidFinishParsing(_: VLCMedia) {
|
|
5
|
-
guard let player = mediaPlayer else { return }
|
|
6
|
-
|
|
7
|
-
var audioTracks: [Track] = []
|
|
8
|
-
|
|
9
|
-
if let audios = player.audioTrackNames as? [String] {
|
|
10
|
-
if let audioIndexes = player.audioTrackIndexes as? [NSNumber] {
|
|
11
|
-
for (index, trackName) in audios.enumerated() {
|
|
12
|
-
let trackId = audioIndexes[index].intValue
|
|
13
|
-
let track = Track(id: trackId, name: trackName)
|
|
14
|
-
audioTracks.append(track)
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
var videoTracks: [Track] = []
|
|
20
|
-
|
|
21
|
-
if let videos = player.videoTrackNames as? [String] {
|
|
22
|
-
if let videoIndexes = player.videoTrackIndexes as? [NSNumber] {
|
|
23
|
-
for (index, trackName) in videos.enumerated() {
|
|
24
|
-
let trackId = videoIndexes[index].intValue
|
|
25
|
-
let track = Track(id: trackId, name: trackName)
|
|
26
|
-
videoTracks.append(track)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
var subtitleTracks: [Track] = []
|
|
32
|
-
|
|
33
|
-
if let subtitles = player.videoSubTitlesNames as? [String] {
|
|
34
|
-
if let subtitleIndexes = player.videoSubTitlesIndexes as? [NSNumber] {
|
|
35
|
-
for (index, trackName) in subtitles.enumerated() {
|
|
36
|
-
let trackId = subtitleIndexes[index].intValue
|
|
37
|
-
let track = Track(id: trackId, name: trackName)
|
|
38
|
-
subtitleTracks.append(track)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let video = player.videoSize
|
|
44
|
-
let tracks = MediaTracks(
|
|
45
|
-
audio: audioTracks,
|
|
46
|
-
video: videoTracks,
|
|
47
|
-
subtitle: subtitleTracks
|
|
48
|
-
)
|
|
49
|
-
let length = player.media?.length.intValue ?? 0
|
|
50
|
-
let seekable = player.isSeekable
|
|
51
|
-
|
|
52
|
-
let mediaInfo = MediaInfo(
|
|
53
|
-
width: Int(video.width),
|
|
54
|
-
height: Int(video.height),
|
|
55
|
-
tracks: tracks,
|
|
56
|
-
duration: Double(length),
|
|
57
|
-
seekable: seekable
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
onParsedChanged(mediaInfo)
|
|
61
|
-
|
|
62
|
-
mediaLength = length
|
|
63
|
-
}
|
|
64
|
-
}
|