expo-libvlc-player 0.1.49 → 0.1.51
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 +2 -2
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerModule.kt +4 -3
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +14 -15
- package/android/src/main/java/expo/modules/libvlcplayer/MediaListener.kt +25 -31
- package/android/src/main/java/expo/modules/libvlcplayer/records/Slave.kt +11 -0
- package/android/src/main/java/expo/modules/libvlcplayer/records/Track.kt +11 -0
- package/android/src/main/java/expo/modules/libvlcplayer/records/Tracks.kt +12 -0
- package/build/LibVlcPlayer.types.d.ts +3 -3
- package/build/LibVlcPlayer.types.js.map +1 -1
- package/build/LibVlcPlayerView.js.map +1 -1
- package/ios/LibVlcPlayerModule.swift +2 -2
- package/ios/LibVlcPlayerView.swift +8 -9
- package/ios/MediaDelegate.swift +14 -20
- package/ios/Records/Slave.swift +9 -0
- package/ios/Records/Track.swift +14 -0
- package/ios/Records/Tracks.swift +12 -0
- package/package.json +1 -1
- package/src/LibVlcPlayer.types.ts +3 -3
- package/src/LibVlcPlayerView.tsx +2 -2
package/README.md
CHANGED
|
@@ -138,7 +138,7 @@ The `LibVlcPlayerView` extends React Native `ViewProps` and implements its own:
|
|
|
138
138
|
| `onEndReached` | Called after the `EndReached` player event | |
|
|
139
139
|
| `onEncounteredError` | Called after the `EncounteredError` player event | `{ error: string }` |
|
|
140
140
|
| `onPositionChanged` | Called after the `PositionChanged` player event | `{ position: number }` |
|
|
141
|
-
| `onParsedChanged` | Called after the `ParsedChanged` media event | [`
|
|
141
|
+
| `onParsedChanged` | Called after the `ParsedChanged` media event | [`MediaInfo`](#mediainfo) |
|
|
142
142
|
| `onBackground` | Called after the player enters the background | |
|
|
143
143
|
|
|
144
144
|
### Player types
|
|
@@ -162,7 +162,7 @@ The `LibVlcPlayerView` extends React Native `ViewProps` and implements its own:
|
|
|
162
162
|
}
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
#### `
|
|
165
|
+
#### `MediaInfo`
|
|
166
166
|
|
|
167
167
|
```json
|
|
168
168
|
{
|
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.50'
|
|
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.50"
|
|
31
31
|
consumerProguardFiles("proguard-rules.pro")
|
|
32
32
|
}
|
|
33
33
|
lintOptions {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
package expo.modules.libvlcplayer
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.bridge.ReadableMap
|
|
4
3
|
import expo.modules.kotlin.modules.Module
|
|
5
4
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
6
5
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
6
|
+
import expo.modules.libvlcplayer.records.Slave
|
|
7
|
+
import expo.modules.libvlcplayer.records.Tracks
|
|
7
8
|
|
|
8
9
|
private const val BUFFERING_EVENT = "onBuffering"
|
|
9
10
|
private const val PLAYING_EVENT = "onPlaying"
|
|
@@ -52,11 +53,11 @@ class LibVlcPlayerModule : Module() {
|
|
|
52
53
|
view.options = options ?: ArrayList<String>()
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
Prop("slaves") { view: LibVlcPlayerView, slaves: ArrayList<
|
|
56
|
+
Prop("slaves") { view: LibVlcPlayerView, slaves: ArrayList<Slave>? ->
|
|
56
57
|
view.slaves = slaves
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
Prop("tracks") { view: LibVlcPlayerView, tracks:
|
|
60
|
+
Prop("tracks") { view: LibVlcPlayerView, tracks: Tracks? ->
|
|
60
61
|
view.tracks = tracks
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -2,12 +2,12 @@ package expo.modules.libvlcplayer
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.net.Uri
|
|
5
|
-
import com.facebook.react.bridge.ReadableMap
|
|
6
|
-
import com.facebook.react.bridge.WritableMap
|
|
7
5
|
import expo.modules.kotlin.AppContext
|
|
8
6
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
9
7
|
import expo.modules.kotlin.views.ExpoView
|
|
10
8
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
9
|
+
import expo.modules.libvlcplayer.records.Slave
|
|
10
|
+
import expo.modules.libvlcplayer.records.Tracks
|
|
11
11
|
import org.videolan.libvlc.LibVLC
|
|
12
12
|
import org.videolan.libvlc.Media
|
|
13
13
|
import org.videolan.libvlc.MediaPlayer
|
|
@@ -53,7 +53,7 @@ class LibVlcPlayerView(
|
|
|
53
53
|
internal val onEndReached by EventDispatcher()
|
|
54
54
|
internal val onEncounteredError by EventDispatcher()
|
|
55
55
|
internal val onPositionChanged by EventDispatcher()
|
|
56
|
-
internal val onParsedChanged by EventDispatcher
|
|
56
|
+
internal val onParsedChanged by EventDispatcher()
|
|
57
57
|
internal val onBackground by EventDispatcher()
|
|
58
58
|
|
|
59
59
|
init {
|
|
@@ -146,17 +146,16 @@ class LibVlcPlayerView(
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
fun addPlayerSlave(slave:
|
|
150
|
-
val
|
|
151
|
-
val type = slave.getString("type") ?: "item"
|
|
152
|
-
val selected = false
|
|
153
|
-
|
|
149
|
+
fun addPlayerSlave(slave: Slave) {
|
|
150
|
+
val type = slave.type
|
|
154
151
|
val slaveType =
|
|
155
152
|
if (type == "subtitle") {
|
|
156
153
|
IMedia.Slave.Type.Subtitle
|
|
157
154
|
} else {
|
|
158
155
|
IMedia.Slave.Type.Audio
|
|
159
156
|
}
|
|
157
|
+
val source = slave.source
|
|
158
|
+
val selected = false
|
|
160
159
|
|
|
161
160
|
try {
|
|
162
161
|
mediaPlayer?.addSlave(slaveType, Uri.parse(source), selected)
|
|
@@ -168,11 +167,11 @@ class LibVlcPlayerView(
|
|
|
168
167
|
|
|
169
168
|
fun addPlayerSlaves() {
|
|
170
169
|
// Add in this specific order, otherwise subtitle slaves will be missing
|
|
171
|
-
slaves?.filter { it.
|
|
172
|
-
slaves?.filter { it.
|
|
170
|
+
slaves?.filter { it.type == "subtitle" }?.forEach(::addPlayerSlave)
|
|
171
|
+
slaves?.filter { it.type == "audio" }?.forEach(::addPlayerSlave)
|
|
173
172
|
}
|
|
174
173
|
|
|
175
|
-
var slaves: ArrayList<
|
|
174
|
+
var slaves: ArrayList<Slave>? = null
|
|
176
175
|
set(value) {
|
|
177
176
|
field = value
|
|
178
177
|
addPlayerSlaves()
|
|
@@ -180,9 +179,9 @@ class LibVlcPlayerView(
|
|
|
180
179
|
|
|
181
180
|
fun setPlayerTracks() {
|
|
182
181
|
mediaPlayer?.let { player ->
|
|
183
|
-
val audioTrack = tracks?.
|
|
184
|
-
val videoTrack = tracks?.
|
|
185
|
-
val spuTrack = tracks?.
|
|
182
|
+
val audioTrack = tracks?.audio ?: player.getAudioTrack()
|
|
183
|
+
val videoTrack = tracks?.video ?: player.getVideoTrack()
|
|
184
|
+
val spuTrack = tracks?.subtitle ?: player.getSpuTrack()
|
|
186
185
|
|
|
187
186
|
player.setAudioTrack(audioTrack)
|
|
188
187
|
player.setVideoTrack(videoTrack)
|
|
@@ -190,7 +189,7 @@ class LibVlcPlayerView(
|
|
|
190
189
|
}
|
|
191
190
|
}
|
|
192
191
|
|
|
193
|
-
var tracks:
|
|
192
|
+
var tracks: Tracks? = null
|
|
194
193
|
set(value) {
|
|
195
194
|
if (options.hasAudioTrackOption()) {
|
|
196
195
|
val error = mapOf("error" to "Audio track selected via options")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
package expo.modules.libvlcplayer
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import expo.modules.libvlcplayer.records.Track
|
|
4
4
|
import org.videolan.libvlc.interfaces.IMedia.Event
|
|
5
5
|
import org.videolan.libvlc.interfaces.IMedia.EventListener
|
|
6
6
|
|
|
@@ -10,43 +10,37 @@ fun LibVlcPlayerView.setMediaListener() {
|
|
|
10
10
|
EventListener { event ->
|
|
11
11
|
when (event.type) {
|
|
12
12
|
Event.ParsedChanged -> {
|
|
13
|
-
val audioTracks =
|
|
13
|
+
val audioTracks = mutableListOf<Track>()
|
|
14
14
|
val audios = player.getAudioTracks()
|
|
15
15
|
|
|
16
16
|
audios?.forEach { track ->
|
|
17
|
-
val
|
|
18
|
-
|
|
19
|
-
trackMap.putString("name", track.name)
|
|
20
|
-
audioTracks.pushMap(trackMap)
|
|
17
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
18
|
+
audioTracks.add(trackObj)
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
val videoTracks =
|
|
21
|
+
val videoTracks = mutableListOf<Track>()
|
|
24
22
|
val videos = player.getVideoTracks()
|
|
25
23
|
|
|
26
24
|
videos?.forEach { track ->
|
|
27
|
-
val
|
|
28
|
-
|
|
29
|
-
trackMap.putString("name", track.name)
|
|
30
|
-
videoTracks.pushMap(trackMap)
|
|
25
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
26
|
+
videoTracks.add(trackObj)
|
|
31
27
|
}
|
|
32
28
|
|
|
33
|
-
val subtitleTracks =
|
|
29
|
+
val subtitleTracks = mutableListOf<Track>()
|
|
34
30
|
val subtitles = player.getSpuTracks()
|
|
35
31
|
|
|
36
32
|
subtitles?.forEach { track ->
|
|
37
|
-
val
|
|
38
|
-
|
|
39
|
-
trackMap.putString("name", track.name)
|
|
40
|
-
subtitleTracks.pushMap(trackMap)
|
|
33
|
+
val trackObj = Track(id = track.id, name = track.name)
|
|
34
|
+
subtitleTracks.add(trackObj)
|
|
41
35
|
}
|
|
42
36
|
|
|
43
37
|
val video = player.getCurrentVideoTrack()
|
|
44
38
|
val tracks =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
mapOf(
|
|
40
|
+
"audio" to audioTracks,
|
|
41
|
+
"video" to videoTracks,
|
|
42
|
+
"subtitle" to subtitleTracks,
|
|
43
|
+
)
|
|
50
44
|
val ratio = player.getAspectRatio()
|
|
51
45
|
val pLength = player.getLength()
|
|
52
46
|
val length =
|
|
@@ -57,17 +51,17 @@ fun LibVlcPlayerView.setMediaListener() {
|
|
|
57
51
|
}
|
|
58
52
|
val seekable = player.isSeekable()
|
|
59
53
|
|
|
60
|
-
val
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
val mediaInfo =
|
|
55
|
+
mapOf(
|
|
56
|
+
"width" to (video?.width ?: 0),
|
|
57
|
+
"height" to (video?.height ?: 0),
|
|
58
|
+
"tracks" to tracks,
|
|
59
|
+
"aspectRatio" to ratio,
|
|
60
|
+
"duration" to length.toDouble(),
|
|
61
|
+
"seekable" to seekable,
|
|
62
|
+
)
|
|
69
63
|
|
|
70
|
-
onParsedChanged(
|
|
64
|
+
onParsedChanged(mediaInfo)
|
|
71
65
|
|
|
72
66
|
videoLength = length
|
|
73
67
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package expo.modules.libvlcplayer.records
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.records.Field
|
|
4
|
+
import expo.modules.kotlin.records.Record
|
|
5
|
+
import java.io.Serializable
|
|
6
|
+
|
|
7
|
+
class Slave(
|
|
8
|
+
@Field var source: String,
|
|
9
|
+
@Field var type: String,
|
|
10
|
+
) : Record,
|
|
11
|
+
Serializable
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package expo.modules.libvlcplayer.records
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.records.Field
|
|
4
|
+
import expo.modules.kotlin.records.Record
|
|
5
|
+
import java.io.Serializable
|
|
6
|
+
|
|
7
|
+
data class Track(
|
|
8
|
+
@Field val id: Int,
|
|
9
|
+
@Field val name: String,
|
|
10
|
+
) : Record,
|
|
11
|
+
Serializable
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package expo.modules.libvlcplayer.records
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.records.Field
|
|
4
|
+
import expo.modules.kotlin.records.Record
|
|
5
|
+
import java.io.Serializable
|
|
6
|
+
|
|
7
|
+
class Tracks(
|
|
8
|
+
@Field var audio: Int,
|
|
9
|
+
@Field var video: Int,
|
|
10
|
+
@Field var subtitle: Int,
|
|
11
|
+
) : Record,
|
|
12
|
+
Serializable
|
|
@@ -37,7 +37,7 @@ export interface VideoTracks {
|
|
|
37
37
|
video: Track[];
|
|
38
38
|
subtitle: Track[];
|
|
39
39
|
}
|
|
40
|
-
export interface
|
|
40
|
+
export interface MediaInfo {
|
|
41
41
|
width: number;
|
|
42
42
|
height: number;
|
|
43
43
|
tracks: VideoTracks;
|
|
@@ -97,7 +97,7 @@ export type Position = {
|
|
|
97
97
|
* @hidden
|
|
98
98
|
*/
|
|
99
99
|
export type ParsedChangedListener = (event: {
|
|
100
|
-
nativeEvent:
|
|
100
|
+
nativeEvent: MediaInfo;
|
|
101
101
|
}) => void;
|
|
102
102
|
/**
|
|
103
103
|
* @hidden
|
|
@@ -270,7 +270,7 @@ export interface LibVlcPlayerViewProps extends ViewProps {
|
|
|
270
270
|
/**
|
|
271
271
|
* Called after the player loads the media
|
|
272
272
|
*/
|
|
273
|
-
onParsedChanged?: (event:
|
|
273
|
+
onParsedChanged?: (event: MediaInfo) => void;
|
|
274
274
|
/**
|
|
275
275
|
* Called after the player enters the background
|
|
276
276
|
*/
|
|
@@ -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 VideoTracks {\n audio: Track[];\n video: Track[];\n subtitle: Track[];\n}\n\nexport interface
|
|
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 VideoTracks {\n audio: Track[];\n video: Track[];\n subtitle: Track[];\n}\n\nexport interface MediaInfo {\n width: number;\n height: number;\n tracks: VideoTracks;\n aspectRatio: string | null;\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 ParsedChangedListener = (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 aspectRatio?: string;\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 onParsedChanged?: ParsedChangedListener;\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 aspect ratio. Must be a valid format\n *\n * @example \"16:9\"\n */\n aspectRatio?: string;\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 player loads the media\n */\n onParsedChanged?: (event: MediaInfo) => void;\n /**\n * Called after the player enters the background\n */\n onBackground?: () => void;\n}\n"]}
|
|
@@ -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,eAAe,GAAG,CAAC,EAAE,WAAW,EAA8B,EAAE,EAAE;QACtE,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACrC,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,eAAe,CAAC,CAAC,eAAe,CAAC,EACjC,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
|
|
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,eAAe,GAAG,CAAC,EAAE,WAAW,EAA8B,EAAE,EAAE;QACtE,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACrC,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,eAAe,CAAC,CAAC,eAAe,CAAC,EACjC,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 onParsedChanged = ({ nativeEvent }: { nativeEvent: MediaInfo }) => {\n if (props.onParsedChanged) {\n props.onParsedChanged(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 onParsedChanged={onParsedChanged}\n />\n );\n },\n);\n\nexport default LibVlcPlayerView;\n"]}
|
|
@@ -41,11 +41,11 @@ public class LibVlcPlayerModule: Module {
|
|
|
41
41
|
view.options = options ?? [String]()
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
Prop("slaves") { (view: LibVlcPlayerView, slaves: [
|
|
44
|
+
Prop("slaves") { (view: LibVlcPlayerView, slaves: [Slave]?) in
|
|
45
45
|
view.slaves = slaves
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
Prop("tracks") { (view: LibVlcPlayerView, tracks:
|
|
48
|
+
Prop("tracks") { (view: LibVlcPlayerView, tracks: Tracks?) in
|
|
49
49
|
view.tracks = tracks
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -117,14 +117,13 @@ class LibVlcPlayerView: ExpoView {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
func addPlayerSlave(_ slave:
|
|
121
|
-
let source = slave
|
|
122
|
-
let type = slave
|
|
123
|
-
let selected = false
|
|
124
|
-
|
|
120
|
+
func addPlayerSlave(_ slave: Slave) {
|
|
121
|
+
let source = slave.source
|
|
122
|
+
let type = slave.type
|
|
125
123
|
let slaveType = type == "subtitle" ?
|
|
126
124
|
VLCMediaPlaybackSlaveType.subtitle :
|
|
127
125
|
VLCMediaPlaybackSlaveType.audio
|
|
126
|
+
let selected = false
|
|
128
127
|
|
|
129
128
|
guard let url = URL(string: source) else {
|
|
130
129
|
let error = ["error": "Invalid slave, \(type) could not be added"]
|
|
@@ -137,11 +136,11 @@ class LibVlcPlayerView: ExpoView {
|
|
|
137
136
|
|
|
138
137
|
func addPlayerSlaves() {
|
|
139
138
|
// Add in this specific order, otherwise subtitle slaves will be missing
|
|
140
|
-
slaves?.filter {
|
|
141
|
-
slaves?.filter {
|
|
139
|
+
slaves?.filter { $0.type == "subtitle" }.forEach { addPlayerSlave($0) }
|
|
140
|
+
slaves?.filter { $0.type == "audio" }.forEach { addPlayerSlave($0) }
|
|
142
141
|
}
|
|
143
142
|
|
|
144
|
-
var slaves: [
|
|
143
|
+
var slaves: [Slave]? {
|
|
145
144
|
didSet {
|
|
146
145
|
addPlayerSlaves()
|
|
147
146
|
}
|
|
@@ -159,7 +158,7 @@ class LibVlcPlayerView: ExpoView {
|
|
|
159
158
|
player.currentVideoSubTitleIndex = Int32(videoSubTitleIndex)
|
|
160
159
|
}
|
|
161
160
|
|
|
162
|
-
var tracks:
|
|
161
|
+
var tracks: Tracks? {
|
|
163
162
|
didSet {
|
|
164
163
|
if options.hasAudioTrackOption() {
|
|
165
164
|
let error = ["error": "Audio track selected via options"]
|
package/ios/MediaDelegate.swift
CHANGED
|
@@ -4,44 +4,38 @@ extension LibVlcPlayerView: VLCMediaDelegate {
|
|
|
4
4
|
func mediaDidFinishParsing(_: VLCMedia) {
|
|
5
5
|
guard let player = mediaPlayer else { return }
|
|
6
6
|
|
|
7
|
-
var audioTracks: [
|
|
7
|
+
var audioTracks: [Track] = []
|
|
8
8
|
|
|
9
9
|
if let audios = player.audioTrackNames as? [String] {
|
|
10
10
|
if let audioIndexes = player.audioTrackIndexes as? [NSNumber] {
|
|
11
|
-
for (index,
|
|
11
|
+
for (index, trackName) in audios.enumerated() {
|
|
12
12
|
let trackId = audioIndexes[index].intValue
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"name": name,
|
|
16
|
-
])
|
|
13
|
+
let track = Track(id: trackId, name: trackName)
|
|
14
|
+
audioTracks.append(track)
|
|
17
15
|
}
|
|
18
16
|
}
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
var videoTracks: [
|
|
19
|
+
var videoTracks: [Track] = []
|
|
22
20
|
|
|
23
21
|
if let videos = player.videoTrackNames as? [String] {
|
|
24
22
|
if let videoIndexes = player.videoTrackIndexes as? [NSNumber] {
|
|
25
|
-
for (index,
|
|
23
|
+
for (index, trackName) in videos.enumerated() {
|
|
26
24
|
let trackId = videoIndexes[index].intValue
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"name": name,
|
|
30
|
-
])
|
|
25
|
+
let track = Track(id: trackId, name: trackName)
|
|
26
|
+
videoTracks.append(track)
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
var subtitleTracks: [
|
|
31
|
+
var subtitleTracks: [Track] = []
|
|
36
32
|
|
|
37
33
|
if let subtitles = player.videoSubTitlesNames as? [String] {
|
|
38
34
|
if let subtitleIndexes = player.videoSubTitlesIndexes as? [NSNumber] {
|
|
39
|
-
for (index,
|
|
35
|
+
for (index, trackName) in subtitles.enumerated() {
|
|
40
36
|
let trackId = subtitleIndexes[index].intValue
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"name": name,
|
|
44
|
-
])
|
|
37
|
+
let track = Track(id: trackId, name: trackName)
|
|
38
|
+
subtitleTracks.append(track)
|
|
45
39
|
}
|
|
46
40
|
}
|
|
47
41
|
}
|
|
@@ -56,7 +50,7 @@ extension LibVlcPlayerView: VLCMediaDelegate {
|
|
|
56
50
|
let length = player.media?.length.intValue ?? 0
|
|
57
51
|
let seekable = player.isSeekable
|
|
58
52
|
|
|
59
|
-
let
|
|
53
|
+
let mediaInfo: [String: Any] = [
|
|
60
54
|
"width": Int(video.width),
|
|
61
55
|
"height": Int(video.height),
|
|
62
56
|
"tracks": tracks,
|
|
@@ -65,7 +59,7 @@ extension LibVlcPlayerView: VLCMediaDelegate {
|
|
|
65
59
|
"seekable": seekable,
|
|
66
60
|
]
|
|
67
61
|
|
|
68
|
-
onParsedChanged(
|
|
62
|
+
onParsedChanged(mediaInfo)
|
|
69
63
|
|
|
70
64
|
videoLength = length
|
|
71
65
|
}
|
package/package.json
CHANGED
|
@@ -42,7 +42,7 @@ export interface VideoTracks {
|
|
|
42
42
|
subtitle: Track[];
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export interface
|
|
45
|
+
export interface MediaInfo {
|
|
46
46
|
width: number;
|
|
47
47
|
height: number;
|
|
48
48
|
tracks: VideoTracks;
|
|
@@ -112,7 +112,7 @@ export type Position = { position: number };
|
|
|
112
112
|
/**
|
|
113
113
|
* @hidden
|
|
114
114
|
*/
|
|
115
|
-
export type ParsedChangedListener = (event: { nativeEvent:
|
|
115
|
+
export type ParsedChangedListener = (event: { nativeEvent: MediaInfo }) => void;
|
|
116
116
|
|
|
117
117
|
/**
|
|
118
118
|
* @hidden
|
|
@@ -287,7 +287,7 @@ export interface LibVlcPlayerViewProps extends ViewProps {
|
|
|
287
287
|
/**
|
|
288
288
|
* Called after the player loads the media
|
|
289
289
|
*/
|
|
290
|
-
onParsedChanged?: (event:
|
|
290
|
+
onParsedChanged?: (event: MediaInfo) => void;
|
|
291
291
|
/**
|
|
292
292
|
* Called after the player enters the background
|
|
293
293
|
*/
|
package/src/LibVlcPlayerView.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
LibVlcPlayerViewRef,
|
|
8
8
|
type Error,
|
|
9
9
|
type Position,
|
|
10
|
-
type
|
|
10
|
+
type MediaInfo,
|
|
11
11
|
} from "./LibVlcPlayer.types";
|
|
12
12
|
import { parseSource } from "./utils/assets";
|
|
13
13
|
import { convertNativeProps } from "./utils/props";
|
|
@@ -41,7 +41,7 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const onParsedChanged = ({ nativeEvent }: { nativeEvent:
|
|
44
|
+
const onParsedChanged = ({ nativeEvent }: { nativeEvent: MediaInfo }) => {
|
|
45
45
|
if (props.onParsedChanged) {
|
|
46
46
|
props.onParsedChanged(nativeEvent);
|
|
47
47
|
}
|