expo-libvlc-player 2.0.14 → 2.1.0
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 +8 -6
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/libvlcplayer/DialogCallbacks.kt +38 -0
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerModule.kt +10 -0
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +19 -4
- package/android/src/main/java/expo/modules/libvlcplayer/MediaPlayerListener.kt +15 -1
- package/android/src/main/java/expo/modules/libvlcplayer/records/Dialog.kt +14 -0
- package/build/LibVlcPlayer.types.d.ts +40 -18
- package/build/LibVlcPlayer.types.d.ts.map +1 -1
- package/build/LibVlcPlayer.types.js.map +1 -1
- package/build/LibVlcPlayerView.d.ts.map +1 -1
- package/build/LibVlcPlayerView.js +24 -3
- package/build/LibVlcPlayerView.js.map +1 -1
- package/ios/DialogProtocol.swift +58 -0
- package/ios/LibVlcPlayerModule.swift +10 -0
- package/ios/LibVlcPlayerView.swift +26 -2
- package/ios/MediaPlayerDelegate.swift +15 -1
- package/ios/Records/Dialog.swift +18 -0
- package/package.json +1 -1
- package/src/LibVlcPlayer.types.ts +42 -12
- package/src/LibVlcPlayerView.tsx +37 -6
package/README.md
CHANGED
|
@@ -111,12 +111,14 @@ See the [Example App](example/components/PlayerView.tsx) for additional usage.
|
|
|
111
111
|
|
|
112
112
|
### Player methods
|
|
113
113
|
|
|
114
|
-
| Method
|
|
115
|
-
|
|
|
116
|
-
| `play()`
|
|
117
|
-
| `pause()`
|
|
118
|
-
| `stop()`
|
|
119
|
-
| `seek(position: number)`
|
|
114
|
+
| Method | Description |
|
|
115
|
+
| ---------------------------- | --------------------------------------------------------------------------------- |
|
|
116
|
+
| `play()` | Starts playback of the current player |
|
|
117
|
+
| `pause()` | Pauses playback of the current player |
|
|
118
|
+
| `stop()` | Stops playback of the current player |
|
|
119
|
+
| `seek(position: number)` | Sets the position of the current player. Must be a float between `0` and `1` |
|
|
120
|
+
| `postAction(action: number)` | Posts an answer to the current `Dialog` when displayed. Must be either `1` or `2` |
|
|
121
|
+
| `dismiss()` | Dismisses the current `Dialog` when displayed |
|
|
120
122
|
|
|
121
123
|
### Player props
|
|
122
124
|
|
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 = "2.0
|
|
4
|
+
version = "2.1.0"
|
|
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 "2.0
|
|
30
|
+
versionName "2.1.0"
|
|
31
31
|
consumerProguardFiles("proguard-rules.pro")
|
|
32
32
|
}
|
|
33
33
|
lintOptions {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package expo.modules.libvlcplayer
|
|
2
|
+
|
|
3
|
+
import expo.modules.libvlcplayer.records.Dialog
|
|
4
|
+
import org.videolan.libvlc.Dialog as VLCDialog
|
|
5
|
+
|
|
6
|
+
fun LibVlcPlayerView.setDialogCallbacks() {
|
|
7
|
+
VLCDialog.setCallbacks(
|
|
8
|
+
libVLC!!,
|
|
9
|
+
object : VLCDialog.Callbacks {
|
|
10
|
+
override fun onDisplay(dialog: VLCDialog.ErrorMessage) {}
|
|
11
|
+
|
|
12
|
+
override fun onDisplay(dialog: VLCDialog.LoginDialog) {}
|
|
13
|
+
|
|
14
|
+
override fun onDisplay(dialog: VLCDialog.QuestionDialog) {
|
|
15
|
+
question = dialog
|
|
16
|
+
|
|
17
|
+
val dialog =
|
|
18
|
+
Dialog(
|
|
19
|
+
title = dialog.getTitle(),
|
|
20
|
+
text = dialog.getText(),
|
|
21
|
+
cancelText = dialog.getCancelText(),
|
|
22
|
+
action1Text = dialog.getAction1Text(),
|
|
23
|
+
action2Text = dialog.getAction2Text(),
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
onDialogDisplay(dialog)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun onDisplay(dialog: VLCDialog.ProgressDialog) {}
|
|
30
|
+
|
|
31
|
+
override fun onCanceled(dialog: VLCDialog) {
|
|
32
|
+
question = null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onProgressUpdate(dialog: VLCDialog.ProgressDialog) {}
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
}
|
|
@@ -14,6 +14,7 @@ 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
16
|
private const val ES_ADDED_EVENT = "onESAdded"
|
|
17
|
+
private const val DIALOG_DISPLAY_EVENT = "onDialogDisplay"
|
|
17
18
|
private const val FIRST_PLAY_EVENT = "onFirstPlay"
|
|
18
19
|
private const val BACKGROUND_EVENT = "onBackground"
|
|
19
20
|
|
|
@@ -27,6 +28,7 @@ val playerEvents =
|
|
|
27
28
|
ENCOUNTERED_ERROR_EVENT,
|
|
28
29
|
POSITION_CHANGED_EVENT,
|
|
29
30
|
ES_ADDED_EVENT,
|
|
31
|
+
DIALOG_DISPLAY_EVENT,
|
|
30
32
|
FIRST_PLAY_EVENT,
|
|
31
33
|
BACKGROUND_EVENT,
|
|
32
34
|
)
|
|
@@ -127,6 +129,14 @@ class LibVlcPlayerModule : Module() {
|
|
|
127
129
|
AsyncFunction("seek") { view: LibVlcPlayerView, position: Float ->
|
|
128
130
|
view.seek(position)
|
|
129
131
|
}
|
|
132
|
+
|
|
133
|
+
AsyncFunction("postAction") { view: LibVlcPlayerView, action: Int ->
|
|
134
|
+
view.postAction(action)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
AsyncFunction("dismiss") { view: LibVlcPlayerView ->
|
|
138
|
+
view.dismiss()
|
|
139
|
+
}
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
OnActivityEntersBackground {
|
|
@@ -6,6 +6,7 @@ import expo.modules.kotlin.AppContext
|
|
|
6
6
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
7
7
|
import expo.modules.kotlin.views.ExpoView
|
|
8
8
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
9
|
+
import expo.modules.libvlcplayer.records.Dialog
|
|
9
10
|
import expo.modules.libvlcplayer.records.MediaInfo
|
|
10
11
|
import expo.modules.libvlcplayer.records.MediaTracks
|
|
11
12
|
import expo.modules.libvlcplayer.records.Slave
|
|
@@ -18,6 +19,7 @@ import org.videolan.libvlc.interfaces.IMedia
|
|
|
18
19
|
import org.videolan.libvlc.util.DisplayManager
|
|
19
20
|
import org.videolan.libvlc.util.VLCVideoLayout
|
|
20
21
|
import java.net.URI
|
|
22
|
+
import org.videolan.libvlc.Dialog as VLCDialog
|
|
21
23
|
|
|
22
24
|
const val DEFAULT_PLAYER_RATE: Float = 1f
|
|
23
25
|
const val DEFAULT_PLAYER_TIME: Int = 0
|
|
@@ -40,13 +42,15 @@ class LibVlcPlayerView(
|
|
|
40
42
|
addView(it)
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
internal var libVLC: LibVLC? = null
|
|
44
46
|
internal var mediaPlayer: MediaPlayer? = null
|
|
45
47
|
private var media: Media? = null
|
|
46
|
-
|
|
48
|
+
internal var question: VLCDialog.QuestionDialog? = null
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
internal var mediaLength: Long = 0L
|
|
49
51
|
internal var oldVolume: Int = MAX_PLAYER_VOLUME
|
|
52
|
+
|
|
53
|
+
private var shouldCreate: Boolean = false
|
|
50
54
|
internal var firstPlay: Boolean = false
|
|
51
55
|
|
|
52
56
|
internal val onBuffering by EventDispatcher()
|
|
@@ -57,6 +61,7 @@ class LibVlcPlayerView(
|
|
|
57
61
|
internal val onEncounteredError by EventDispatcher()
|
|
58
62
|
internal val onPositionChanged by EventDispatcher()
|
|
59
63
|
internal val onESAdded by EventDispatcher<MediaTracks>()
|
|
64
|
+
internal val onDialogDisplay by EventDispatcher<Dialog>()
|
|
60
65
|
internal val onFirstPlay by EventDispatcher<MediaInfo>()
|
|
61
66
|
internal val onBackground by EventDispatcher()
|
|
62
67
|
|
|
@@ -86,6 +91,7 @@ class LibVlcPlayerView(
|
|
|
86
91
|
val source = source ?: return
|
|
87
92
|
|
|
88
93
|
libVLC = LibVLC(context, options)
|
|
94
|
+
setDialogCallbacks()
|
|
89
95
|
mediaPlayer = MediaPlayer(libVLC)
|
|
90
96
|
setMediaPlayerListener()
|
|
91
97
|
|
|
@@ -105,8 +111,8 @@ class LibVlcPlayerView(
|
|
|
105
111
|
|
|
106
112
|
mediaPlayer!!.play()
|
|
107
113
|
|
|
108
|
-
shouldCreate = false
|
|
109
114
|
firstPlay = true
|
|
115
|
+
shouldCreate = false
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
fun attachPlayer() {
|
|
@@ -131,6 +137,7 @@ class LibVlcPlayerView(
|
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
fun destroyPlayer() {
|
|
140
|
+
question = null
|
|
134
141
|
media = null
|
|
135
142
|
mediaPlayer?.release()
|
|
136
143
|
mediaPlayer = null
|
|
@@ -429,6 +436,14 @@ class LibVlcPlayerView(
|
|
|
429
436
|
}
|
|
430
437
|
}
|
|
431
438
|
|
|
439
|
+
fun postAction(action: Int) {
|
|
440
|
+
question?.postAction(action)
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
fun dismiss() {
|
|
444
|
+
question?.dismiss()
|
|
445
|
+
}
|
|
446
|
+
|
|
432
447
|
private fun ArrayList<String>.hasAudioOption(): Boolean {
|
|
433
448
|
val options =
|
|
434
449
|
setOf(
|
|
@@ -22,7 +22,9 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
|
|
|
22
22
|
|
|
23
23
|
val mediaInfo = getMediaInfo()
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
if (mediaInfo.length != 0.0) {
|
|
26
|
+
onFirstPlay(mediaInfo)
|
|
27
|
+
}
|
|
26
28
|
|
|
27
29
|
firstPlay = false
|
|
28
30
|
}
|
|
@@ -56,12 +58,24 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
|
|
|
56
58
|
|
|
57
59
|
Event.EncounteredError -> {
|
|
58
60
|
val error = mapOf("error" to "Player encountered an error")
|
|
61
|
+
|
|
59
62
|
onEncounteredError(error)
|
|
63
|
+
|
|
64
|
+
firstPlay = true
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
Event.PositionChanged -> {
|
|
63
68
|
val position = mapOf("position" to player.getPosition())
|
|
69
|
+
|
|
64
70
|
onPositionChanged(position)
|
|
71
|
+
|
|
72
|
+
if (mediaLength == 0L) {
|
|
73
|
+
val mediaInfo = getMediaInfo()
|
|
74
|
+
|
|
75
|
+
if (mediaInfo.length != 0.0) {
|
|
76
|
+
onFirstPlay(mediaInfo)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
Event.ESAdded -> {
|
|
@@ -0,0 +1,14 @@
|
|
|
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 Dialog(
|
|
8
|
+
@Field var title: String = "",
|
|
9
|
+
@Field var text: String = "",
|
|
10
|
+
@Field var cancelText: String? = "",
|
|
11
|
+
@Field var action1Text: String? = "",
|
|
12
|
+
@Field var action2Text: String? = "",
|
|
13
|
+
) : Record,
|
|
14
|
+
Serializable
|
|
@@ -26,6 +26,20 @@ export interface LibVlcPlayerViewRef {
|
|
|
26
26
|
* @returns A promise which resolves to `void`
|
|
27
27
|
*/
|
|
28
28
|
readonly seek: (position: number) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Posts an answer to the current `Dialog` when displayed
|
|
31
|
+
*
|
|
32
|
+
* @param action - Must be either `1` or `2`
|
|
33
|
+
*
|
|
34
|
+
* @returns A promise which resolves to `void`
|
|
35
|
+
*/
|
|
36
|
+
readonly postAction: (action: 1 | 2) => Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Dismisses the current `Dialog` when displayed
|
|
39
|
+
*
|
|
40
|
+
* @returns A promise which resolves to `void`
|
|
41
|
+
*/
|
|
42
|
+
readonly dismiss: () => Promise<void>;
|
|
29
43
|
}
|
|
30
44
|
export type LibVlcSource = string | number | null;
|
|
31
45
|
export interface Tracks {
|
|
@@ -55,63 +69,69 @@ export interface MediaInfo {
|
|
|
55
69
|
tracks: MediaTracks;
|
|
56
70
|
}
|
|
57
71
|
export type AudioMixingMode = "mixWithOthers" | "duckOthers" | "auto" | "doNotMix";
|
|
72
|
+
export interface NativeEvent<T> {
|
|
73
|
+
nativeEvent: T;
|
|
74
|
+
}
|
|
58
75
|
/**
|
|
59
76
|
* @hidden
|
|
60
77
|
*/
|
|
61
|
-
|
|
78
|
+
type BufferingListener = () => void;
|
|
62
79
|
/**
|
|
63
80
|
* @hidden
|
|
64
81
|
*/
|
|
65
|
-
|
|
82
|
+
type PlayingListener = () => void;
|
|
66
83
|
/**
|
|
67
84
|
* @hidden
|
|
68
85
|
*/
|
|
69
|
-
|
|
86
|
+
type PausedListener = () => void;
|
|
70
87
|
/**
|
|
71
88
|
* @hidden
|
|
72
89
|
*/
|
|
73
|
-
|
|
90
|
+
type StoppedListener = () => void;
|
|
74
91
|
/**
|
|
75
92
|
* @hidden
|
|
76
93
|
*/
|
|
77
|
-
|
|
94
|
+
type EndReachedListener = () => void;
|
|
78
95
|
/**
|
|
79
96
|
* @hidden
|
|
80
97
|
*/
|
|
81
|
-
|
|
82
|
-
nativeEvent: Error;
|
|
83
|
-
}) => void;
|
|
98
|
+
type EncounteredErrorListener = (event: NativeEvent<Error>) => void;
|
|
84
99
|
export type Error = {
|
|
85
100
|
error: string;
|
|
86
101
|
};
|
|
87
102
|
/**
|
|
88
103
|
* @hidden
|
|
89
104
|
*/
|
|
90
|
-
|
|
91
|
-
nativeEvent: Position;
|
|
92
|
-
}) => void;
|
|
105
|
+
type PositionChangedListener = (event: NativeEvent<Position>) => void;
|
|
93
106
|
export type Position = {
|
|
94
107
|
position: number;
|
|
95
108
|
};
|
|
96
109
|
/**
|
|
97
110
|
* @hidden
|
|
98
111
|
*/
|
|
99
|
-
|
|
100
|
-
nativeEvent: MediaTracks;
|
|
101
|
-
}) => void;
|
|
112
|
+
type ESAddedListener = (event: NativeEvent<MediaTracks>) => void;
|
|
102
113
|
/**
|
|
103
114
|
* @hidden
|
|
104
115
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
116
|
+
type DialogDisplayListener = (event: NativeEvent<Dialog>) => void;
|
|
117
|
+
/**
|
|
118
|
+
* @hidden
|
|
119
|
+
*/
|
|
120
|
+
interface Dialog {
|
|
121
|
+
title: string;
|
|
122
|
+
text: string;
|
|
123
|
+
cancelText?: string;
|
|
124
|
+
action1Text?: string;
|
|
125
|
+
action2Text?: string;
|
|
126
|
+
}
|
|
108
127
|
/**
|
|
109
128
|
* @hidden
|
|
110
129
|
*/
|
|
111
|
-
|
|
130
|
+
type FirstPlayListener = (event: NativeEvent<MediaInfo>) => void;
|
|
112
131
|
/**
|
|
113
132
|
* @hidden
|
|
114
133
|
*/
|
|
134
|
+
type BackgroundListener = () => void;
|
|
115
135
|
export interface LibVlcPlayerViewNativeProps {
|
|
116
136
|
ref?: React.Ref<LibVlcPlayerViewRef>;
|
|
117
137
|
source?: LibVlcSource;
|
|
@@ -136,6 +156,7 @@ export interface LibVlcPlayerViewNativeProps {
|
|
|
136
156
|
onEncounteredError?: EncounteredErrorListener;
|
|
137
157
|
onPositionChanged?: PositionChangedListener;
|
|
138
158
|
onESAdded?: ESAddedListener;
|
|
159
|
+
onDialogDisplay?: DialogDisplayListener;
|
|
139
160
|
onFirstPlay?: FirstPlayListener;
|
|
140
161
|
onBackground?: BackgroundListener;
|
|
141
162
|
}
|
|
@@ -293,4 +314,5 @@ export interface LibVlcPlayerViewProps extends ViewProps {
|
|
|
293
314
|
*/
|
|
294
315
|
onBackground?: () => void;
|
|
295
316
|
}
|
|
317
|
+
export {};
|
|
296
318
|
//# sourceMappingURL=LibVlcPlayer.types.d.ts.map
|
|
@@ -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;
|
|
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 * Sets the 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 Tracks {\n audio?: number;\n video?: number;\n subtitle?: number;\n}\n\nexport interface Slave {\n source: NonNullable<LibVlcSource>;\n type: \"audio\" | \"subtitle\";\n selected?: boolean;\n}\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 length: number;\n seekable: boolean;\n tracks: MediaTracks;\n}\n\nexport type AudioMixingMode =\n | \"mixWithOthers\"\n | \"duckOthers\"\n | \"auto\"\n | \"doNotMix\";\n\n/**\n * @hidden\n */\
|
|
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 * Sets the 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 * Posts an answer to the current `Dialog` when displayed\n *\n * @param action - Must be either `1` or `2`\n *\n * @returns A promise which resolves to `void`\n */\n readonly postAction: (action: 1 | 2) => Promise<void>;\n /**\n * Dismisses the current `Dialog` when displayed\n *\n * @returns A promise which resolves to `void`\n */\n readonly dismiss: () => Promise<void>;\n}\n\nexport type LibVlcSource = string | number | null;\n\nexport interface Tracks {\n audio?: number;\n video?: number;\n subtitle?: number;\n}\n\nexport interface Slave {\n source: NonNullable<LibVlcSource>;\n type: \"audio\" | \"subtitle\";\n selected?: boolean;\n}\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 length: number;\n seekable: boolean;\n tracks: MediaTracks;\n}\n\nexport type AudioMixingMode =\n | \"mixWithOthers\"\n | \"duckOthers\"\n | \"auto\"\n | \"doNotMix\";\n\nexport interface NativeEvent<T> {\n nativeEvent: T;\n}\n\n/**\n * @hidden\n */\ntype BufferingListener = () => void;\n\n/**\n * @hidden\n */\ntype PlayingListener = () => void;\n\n/**\n * @hidden\n */\ntype PausedListener = () => void;\n\n/**\n * @hidden\n */\ntype StoppedListener = () => void;\n\n/**\n * @hidden\n */\ntype EndReachedListener = () => void;\n\n/**\n * @hidden\n */\ntype EncounteredErrorListener = (event: NativeEvent<Error>) => void;\n\nexport type Error = { error: string };\n\n/**\n * @hidden\n */\ntype PositionChangedListener = (event: NativeEvent<Position>) => void;\n\nexport type Position = { position: number };\n\n/**\n * @hidden\n */\ntype ESAddedListener = (event: NativeEvent<MediaTracks>) => void;\n\n/**\n * @hidden\n */\ntype DialogDisplayListener = (event: NativeEvent<Dialog>) => void;\n\n/**\n * @hidden\n */\ninterface Dialog {\n title: string;\n text: string;\n cancelText?: string;\n action1Text?: string;\n action2Text?: string;\n}\n\n/**\n * @hidden\n */\ntype FirstPlayListener = (event: NativeEvent<MediaInfo>) => void;\n\n/**\n * @hidden\n */\ntype BackgroundListener = () => void;\n\nexport interface LibVlcPlayerViewNativeProps {\n ref?: React.Ref<LibVlcPlayerViewRef>;\n source?: LibVlcSource;\n options?: string[];\n tracks?: Tracks;\n slaves?: Slave[];\n scale?: number;\n aspectRatio?: string | null;\n rate?: number;\n time?: number;\n volume?: number;\n mute?: boolean;\n audioMixingMode?: AudioMixingMode;\n playInBackground?: boolean;\n autoplay?: boolean;\n repeat?: boolean;\n onBuffering?: BufferingListener;\n onPlaying?: PlayingListener;\n onPaused?: PausedListener;\n onStopped?: StoppedListener;\n onEndReached?: EndReachedListener;\n onEncounteredError?: EncounteredErrorListener;\n onPositionChanged?: PositionChangedListener;\n onESAdded?: ESAddedListener;\n onDialogDisplay?: DialogDisplayListener;\n onFirstPlay?: FirstPlayListener;\n onBackground?: BackgroundListener;\n}\n\nexport interface LibVlcPlayerViewProps extends ViewProps {\n /**\n * Sets the source of the media to be played. Set to `null` to release the player\n */\n source: LibVlcSource;\n /**\n * Sets the VLC options to initialize the player with\n *\n * https://wiki.videolan.org/VLC_command-line_help/\n *\n * @example [\"--network-caching=1000\"]\n *\n * @default []\n */\n options?: string[];\n /**\n * Sets the player audio, video and subtitle tracks\n *\n * @example\n * ```tsx\n * <LibVlcPlayerView\n * tracks={{\n * audio: 0,\n * video: 1,\n * subtitle: 2,\n * }}\n * />\n * ```\n *\n * @default undefined\n */\n tracks?: Tracks;\n /**\n * Sets the player audio and subtitle slaves\n *\n * @example\n * ```tsx\n * <LibVlcPlayerView\n * slaves={[\n * {\n * source: \"file://path/to/subtitle.srt\",\n * type: \"subtitle\",\n * selected: true\n * },\n * ]}\n * />\n * ```\n *\n * @default []\n */\n slaves?: Slave[];\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` for default\n *\n * @example \"16:9\"\n *\n * @default undefined\n */\n aspectRatio?: string | null;\n /**\n * Sets the player rate. Must be a float equal or greater than `1`\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 * 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`. Previous value is set when `false`\n *\n * @default false\n */\n mute?: boolean;\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 media 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 * Determines whether the media should repeat once ended\n *\n * @default false\n */\n repeat?: 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 `ESAdded` player event\n */\n onESAdded?: (event: MediaTracks) => void;\n /**\n * Called after the first `Playing` player event\n */\n onFirstPlay?: (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.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LibVlcPlayerView.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"AASA,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EAMpB,MAAM,sBAAsB,CAAC;AAS9B,QAAA,MAAM,gBAAgB,uHA4ErB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { requireNativeView } from "expo";
|
|
2
|
-
import { forwardRef } from "react";
|
|
2
|
+
import { forwardRef, useImperativeHandle, useRef, } from "react";
|
|
3
|
+
import { Alert } from "react-native";
|
|
3
4
|
import { parseSource } from "./utils/assets";
|
|
4
5
|
import { convertNativeProps } from "./utils/props";
|
|
5
6
|
const NativeView = requireNativeView("ExpoLibVlcPlayer");
|
|
6
7
|
let loggedRenderingChildrenWarning = false;
|
|
7
|
-
const LibVlcPlayerView = forwardRef((props,
|
|
8
|
+
const LibVlcPlayerView = forwardRef((props, forwardedRef) => {
|
|
8
9
|
const nativeProps = convertNativeProps(props);
|
|
10
|
+
const ref = useRef(null);
|
|
11
|
+
useImperativeHandle(forwardedRef, () => ref.current);
|
|
9
12
|
// @ts-expect-error
|
|
10
13
|
if (nativeProps.children && !loggedRenderingChildrenWarning) {
|
|
11
14
|
console.warn("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.");
|
|
@@ -34,7 +37,25 @@ const LibVlcPlayerView = forwardRef((props, ref) => {
|
|
|
34
37
|
return (<NativeView {...nativeProps} ref={ref} source={parseSource(props.source)} slaves={props.slaves?.map((slave) => ({
|
|
35
38
|
...slave,
|
|
36
39
|
source: parseSource(slave.source),
|
|
37
|
-
}))} onEncounteredError={onEncounteredError} onPositionChanged={onPositionChanged} onESAdded={onESAdded}
|
|
40
|
+
}))} onEncounteredError={onEncounteredError} onPositionChanged={onPositionChanged} onESAdded={onESAdded} onDialogDisplay={({ nativeEvent: dialog }) => {
|
|
41
|
+
const alertButtons = [
|
|
42
|
+
{
|
|
43
|
+
text: dialog.action1Text,
|
|
44
|
+
onPress: () => ref.current?.postAction(1),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
text: dialog.action2Text,
|
|
48
|
+
onPress: () => ref.current?.postAction(2),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
text: dialog.cancelText,
|
|
52
|
+
onPress: () => ref.current?.dismiss(),
|
|
53
|
+
style: "cancel",
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
const visibleButtons = alertButtons.filter((button) => button.text);
|
|
57
|
+
Alert.alert(dialog.title, dialog.text, visibleButtons);
|
|
58
|
+
}} onFirstPlay={onFirstPlay}/>);
|
|
38
59
|
});
|
|
39
60
|
export default LibVlcPlayerView;
|
|
40
61
|
//# 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,
|
|
1
|
+
{"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport {\n forwardRef,\n useImperativeHandle,\n useRef,\n type ComponentType,\n} from \"react\";\nimport { Alert, AlertButton } from \"react-native\";\n\nimport {\n LibVlcPlayerViewNativeProps,\n LibVlcPlayerViewProps,\n LibVlcPlayerViewRef,\n type NativeEvent,\n type Error,\n type Position,\n type MediaTracks,\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, forwardedRef) => {\n const nativeProps = convertNativeProps(props);\n const ref = useRef<LibVlcPlayerViewRef | null>(null);\n\n useImperativeHandle(forwardedRef, () => ref.current!);\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 onESAdded = ({ nativeEvent }: NativeEvent<MediaTracks>) => {\n if (props.onESAdded) {\n props.onESAdded(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 onESAdded={onESAdded}\n onDialogDisplay={({ nativeEvent: dialog }) => {\n const alertButtons: AlertButton[] = [\n {\n text: dialog.action1Text,\n onPress: () => ref.current?.postAction(1),\n },\n {\n text: dialog.action2Text,\n onPress: () => ref.current?.postAction(2),\n },\n {\n text: dialog.cancelText,\n onPress: () => ref.current?.dismiss(),\n style: \"cancel\",\n },\n ];\n\n const visibleButtons = alertButtons.filter((button) => button.text);\n\n Alert.alert(dialog.title, dialog.text, visibleButtons);\n }}\n onFirstPlay={onFirstPlay}\n />\n );\n },\n);\n\nexport default LibVlcPlayerView;\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import MobileVLCKit
|
|
2
|
+
|
|
3
|
+
extension LibVlcPlayerView: VLCCustomDialogRendererProtocol {
|
|
4
|
+
func showError(
|
|
5
|
+
withTitle _: String,
|
|
6
|
+
message _: String
|
|
7
|
+
) {}
|
|
8
|
+
|
|
9
|
+
func showLogin(
|
|
10
|
+
withTitle _: String,
|
|
11
|
+
message _: String,
|
|
12
|
+
defaultUsername _: String?,
|
|
13
|
+
askingForStorage _: Bool,
|
|
14
|
+
withReference _: NSValue
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
func showQuestion(
|
|
18
|
+
withTitle title: String,
|
|
19
|
+
message: String,
|
|
20
|
+
type _: VLCDialogQuestionType,
|
|
21
|
+
cancel: String?,
|
|
22
|
+
action1String: String?,
|
|
23
|
+
action2String: String?,
|
|
24
|
+
withReference dialogReference: NSValue
|
|
25
|
+
) {
|
|
26
|
+
reference = dialogReference
|
|
27
|
+
|
|
28
|
+
let dialog = Dialog(
|
|
29
|
+
title: title,
|
|
30
|
+
text: message,
|
|
31
|
+
cancelText: cancel,
|
|
32
|
+
action1Text: action1String,
|
|
33
|
+
action2Text: action2String
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
onDialogDisplay(dialog)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func showProgress(
|
|
40
|
+
withTitle _: String,
|
|
41
|
+
message _: String,
|
|
42
|
+
isIndeterminate _: Bool,
|
|
43
|
+
position _: Float,
|
|
44
|
+
cancel _: String?,
|
|
45
|
+
withReference _: NSValue
|
|
46
|
+
) {}
|
|
47
|
+
|
|
48
|
+
func updateProgress(
|
|
49
|
+
withReference _: NSValue,
|
|
50
|
+
message _: String?,
|
|
51
|
+
position _: Float
|
|
52
|
+
) {}
|
|
53
|
+
|
|
54
|
+
func cancelDialog(withReference _: NSValue) {
|
|
55
|
+
reference = nil
|
|
56
|
+
question = nil
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -8,6 +8,7 @@ private let endReachedEvent = "onEndReached"
|
|
|
8
8
|
private let encounteredErrorEvent = "onEncounteredError"
|
|
9
9
|
private let positionChangedEvent = "onPositionChanged"
|
|
10
10
|
private let esAddedEvent = "onESAdded"
|
|
11
|
+
private let dialogDisplayEvent = "onDialogDisplay"
|
|
11
12
|
private let firstPlayEvent = "onFirstPlay"
|
|
12
13
|
private let backgroundEvent = "onBackground"
|
|
13
14
|
|
|
@@ -20,6 +21,7 @@ let playerEvents = [
|
|
|
20
21
|
encounteredErrorEvent,
|
|
21
22
|
positionChangedEvent,
|
|
22
23
|
esAddedEvent,
|
|
24
|
+
dialogDisplayEvent,
|
|
23
25
|
firstPlayEvent,
|
|
24
26
|
backgroundEvent,
|
|
25
27
|
]
|
|
@@ -110,6 +112,14 @@ public class LibVlcPlayerModule: Module {
|
|
|
110
112
|
AsyncFunction("seek") { (view: LibVlcPlayerView, position: Float) in
|
|
111
113
|
view.seek(position)
|
|
112
114
|
}
|
|
115
|
+
|
|
116
|
+
AsyncFunction("postAction") { (view: LibVlcPlayerView, action: Int) in
|
|
117
|
+
view.postAction(action)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
AsyncFunction("dismiss") { (view: LibVlcPlayerView) in
|
|
121
|
+
view.dismiss()
|
|
122
|
+
}
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
OnAppEntersBackground {
|
|
@@ -10,14 +10,19 @@ let minPlayerVolume: Int = 0
|
|
|
10
10
|
let maxPlayerVolume: Int = 100
|
|
11
11
|
let playerVolumeStep: Int = 10
|
|
12
12
|
|
|
13
|
+
let dialogCustomUI: Bool = true
|
|
14
|
+
|
|
13
15
|
class LibVlcPlayerView: ExpoView {
|
|
14
16
|
private let playerView = UIView()
|
|
15
17
|
|
|
16
18
|
var mediaPlayer: VLCMediaPlayer?
|
|
17
|
-
|
|
19
|
+
var question: VLCDialogProvider?
|
|
20
|
+
var reference: NSValue?
|
|
18
21
|
|
|
19
22
|
var mediaLength: Int32 = 0
|
|
20
23
|
private var oldVolume: Int = maxPlayerVolume
|
|
24
|
+
|
|
25
|
+
private var shouldCreate: Bool = false
|
|
21
26
|
var firstPlay: Bool = false
|
|
22
27
|
|
|
23
28
|
let onBuffering = EventDispatcher()
|
|
@@ -28,6 +33,7 @@ class LibVlcPlayerView: ExpoView {
|
|
|
28
33
|
let onEncounteredError = EventDispatcher()
|
|
29
34
|
let onPositionChanged = EventDispatcher()
|
|
30
35
|
let onESAdded = EventDispatcher()
|
|
36
|
+
let onDialogDisplay = EventDispatcher()
|
|
31
37
|
let onFirstPlay = EventDispatcher()
|
|
32
38
|
let onBackground = EventDispatcher()
|
|
33
39
|
|
|
@@ -63,6 +69,10 @@ class LibVlcPlayerView: ExpoView {
|
|
|
63
69
|
mediaPlayer!.drawable = playerView
|
|
64
70
|
mediaPlayer!.delegate = self
|
|
65
71
|
|
|
72
|
+
let library = mediaPlayer!.libraryInstance
|
|
73
|
+
question = VLCDialogProvider(library: library, customUI: dialogCustomUI)
|
|
74
|
+
question!.customRenderer = self
|
|
75
|
+
|
|
66
76
|
guard let url = URL(string: source) else {
|
|
67
77
|
let error = ["error": "Invalid source, media could not be set"]
|
|
68
78
|
onEncounteredError(error)
|
|
@@ -75,11 +85,13 @@ class LibVlcPlayerView: ExpoView {
|
|
|
75
85
|
|
|
76
86
|
mediaPlayer!.play()
|
|
77
87
|
|
|
78
|
-
shouldCreate = false
|
|
79
88
|
firstPlay = true
|
|
89
|
+
shouldCreate = false
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
func destroyPlayer() {
|
|
93
|
+
reference = nil
|
|
94
|
+
question = nil
|
|
83
95
|
mediaPlayer?.media = nil
|
|
84
96
|
mediaPlayer?.delegate = nil
|
|
85
97
|
mediaPlayer?.drawable = nil
|
|
@@ -375,6 +387,18 @@ class LibVlcPlayerView: ExpoView {
|
|
|
375
387
|
}
|
|
376
388
|
}
|
|
377
389
|
}
|
|
390
|
+
|
|
391
|
+
func postAction(_ action: Int) {
|
|
392
|
+
if let questionDialog = question, let dialogReference = reference {
|
|
393
|
+
questionDialog.postAction(Int32(action), forDialogReference: dialogReference)
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
func dismiss() {
|
|
398
|
+
if let questionDialog = question, let dialogReference = reference {
|
|
399
|
+
questionDialog.dismissDialog(withReference: dialogReference)
|
|
400
|
+
}
|
|
401
|
+
}
|
|
378
402
|
}
|
|
379
403
|
|
|
380
404
|
private extension Array where Element == String {
|
|
@@ -14,7 +14,9 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
|
|
|
14
14
|
|
|
15
15
|
let mediaInfo = getMediaInfo()
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
if mediaInfo.length != 0.0 {
|
|
18
|
+
onFirstPlay(mediaInfo)
|
|
19
|
+
}
|
|
18
20
|
|
|
19
21
|
firstPlay = false
|
|
20
22
|
}
|
|
@@ -38,7 +40,10 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
|
|
|
38
40
|
}
|
|
39
41
|
case .error:
|
|
40
42
|
let error = ["error": "Player encountered an error"]
|
|
43
|
+
|
|
41
44
|
onEncounteredError(error)
|
|
45
|
+
|
|
46
|
+
firstPlay = true
|
|
42
47
|
case .esAdded:
|
|
43
48
|
if !firstPlay {
|
|
44
49
|
let mediaTracks = getMediaTracks()
|
|
@@ -53,7 +58,16 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
|
|
|
53
58
|
func mediaPlayerTimeChanged(_: Notification) {
|
|
54
59
|
if let player = mediaPlayer {
|
|
55
60
|
let position = ["position": player.position]
|
|
61
|
+
|
|
56
62
|
onPositionChanged(position)
|
|
63
|
+
|
|
64
|
+
if mediaLength == 0 {
|
|
65
|
+
let mediaInfo = getMediaInfo()
|
|
66
|
+
|
|
67
|
+
if mediaInfo.length != 0.0 {
|
|
68
|
+
onFirstPlay(mediaInfo)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
57
71
|
}
|
|
58
72
|
}
|
|
59
73
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
|
|
3
|
+
struct Dialog: Record {
|
|
4
|
+
@Field
|
|
5
|
+
var title: String = ""
|
|
6
|
+
|
|
7
|
+
@Field
|
|
8
|
+
var text: String = ""
|
|
9
|
+
|
|
10
|
+
@Field
|
|
11
|
+
var cancelText: String? = ""
|
|
12
|
+
|
|
13
|
+
@Field
|
|
14
|
+
var action1Text: String? = ""
|
|
15
|
+
|
|
16
|
+
@Field
|
|
17
|
+
var action2Text: String? = ""
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -27,6 +27,20 @@ export interface LibVlcPlayerViewRef {
|
|
|
27
27
|
* @returns A promise which resolves to `void`
|
|
28
28
|
*/
|
|
29
29
|
readonly seek: (position: number) => Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Posts an answer to the current `Dialog` when displayed
|
|
32
|
+
*
|
|
33
|
+
* @param action - Must be either `1` or `2`
|
|
34
|
+
*
|
|
35
|
+
* @returns A promise which resolves to `void`
|
|
36
|
+
*/
|
|
37
|
+
readonly postAction: (action: 1 | 2) => Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Dismisses the current `Dialog` when displayed
|
|
40
|
+
*
|
|
41
|
+
* @returns A promise which resolves to `void`
|
|
42
|
+
*/
|
|
43
|
+
readonly dismiss: () => Promise<void>;
|
|
30
44
|
}
|
|
31
45
|
|
|
32
46
|
export type LibVlcSource = string | number | null;
|
|
@@ -68,65 +82,80 @@ export type AudioMixingMode =
|
|
|
68
82
|
| "auto"
|
|
69
83
|
| "doNotMix";
|
|
70
84
|
|
|
85
|
+
export interface NativeEvent<T> {
|
|
86
|
+
nativeEvent: T;
|
|
87
|
+
}
|
|
88
|
+
|
|
71
89
|
/**
|
|
72
90
|
* @hidden
|
|
73
91
|
*/
|
|
74
|
-
|
|
92
|
+
type BufferingListener = () => void;
|
|
75
93
|
|
|
76
94
|
/**
|
|
77
95
|
* @hidden
|
|
78
96
|
*/
|
|
79
|
-
|
|
97
|
+
type PlayingListener = () => void;
|
|
80
98
|
|
|
81
99
|
/**
|
|
82
100
|
* @hidden
|
|
83
101
|
*/
|
|
84
|
-
|
|
102
|
+
type PausedListener = () => void;
|
|
85
103
|
|
|
86
104
|
/**
|
|
87
105
|
* @hidden
|
|
88
106
|
*/
|
|
89
|
-
|
|
107
|
+
type StoppedListener = () => void;
|
|
90
108
|
|
|
91
109
|
/**
|
|
92
110
|
* @hidden
|
|
93
111
|
*/
|
|
94
|
-
|
|
112
|
+
type EndReachedListener = () => void;
|
|
95
113
|
|
|
96
114
|
/**
|
|
97
115
|
* @hidden
|
|
98
116
|
*/
|
|
99
|
-
|
|
117
|
+
type EncounteredErrorListener = (event: NativeEvent<Error>) => void;
|
|
100
118
|
|
|
101
119
|
export type Error = { error: string };
|
|
102
120
|
|
|
103
121
|
/**
|
|
104
122
|
* @hidden
|
|
105
123
|
*/
|
|
106
|
-
|
|
107
|
-
nativeEvent: Position;
|
|
108
|
-
}) => void;
|
|
124
|
+
type PositionChangedListener = (event: NativeEvent<Position>) => void;
|
|
109
125
|
|
|
110
126
|
export type Position = { position: number };
|
|
111
127
|
|
|
112
128
|
/**
|
|
113
129
|
* @hidden
|
|
114
130
|
*/
|
|
115
|
-
|
|
131
|
+
type ESAddedListener = (event: NativeEvent<MediaTracks>) => void;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @hidden
|
|
135
|
+
*/
|
|
136
|
+
type DialogDisplayListener = (event: NativeEvent<Dialog>) => void;
|
|
116
137
|
|
|
117
138
|
/**
|
|
118
139
|
* @hidden
|
|
119
140
|
*/
|
|
120
|
-
|
|
141
|
+
interface Dialog {
|
|
142
|
+
title: string;
|
|
143
|
+
text: string;
|
|
144
|
+
cancelText?: string;
|
|
145
|
+
action1Text?: string;
|
|
146
|
+
action2Text?: string;
|
|
147
|
+
}
|
|
121
148
|
|
|
122
149
|
/**
|
|
123
150
|
* @hidden
|
|
124
151
|
*/
|
|
125
|
-
|
|
152
|
+
type FirstPlayListener = (event: NativeEvent<MediaInfo>) => void;
|
|
126
153
|
|
|
127
154
|
/**
|
|
128
155
|
* @hidden
|
|
129
156
|
*/
|
|
157
|
+
type BackgroundListener = () => void;
|
|
158
|
+
|
|
130
159
|
export interface LibVlcPlayerViewNativeProps {
|
|
131
160
|
ref?: React.Ref<LibVlcPlayerViewRef>;
|
|
132
161
|
source?: LibVlcSource;
|
|
@@ -151,6 +180,7 @@ export interface LibVlcPlayerViewNativeProps {
|
|
|
151
180
|
onEncounteredError?: EncounteredErrorListener;
|
|
152
181
|
onPositionChanged?: PositionChangedListener;
|
|
153
182
|
onESAdded?: ESAddedListener;
|
|
183
|
+
onDialogDisplay?: DialogDisplayListener;
|
|
154
184
|
onFirstPlay?: FirstPlayListener;
|
|
155
185
|
onBackground?: BackgroundListener;
|
|
156
186
|
}
|
package/src/LibVlcPlayerView.tsx
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { requireNativeView } from "expo";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
forwardRef,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useRef,
|
|
6
|
+
type ComponentType,
|
|
7
|
+
} from "react";
|
|
8
|
+
import { Alert, AlertButton } from "react-native";
|
|
3
9
|
|
|
4
10
|
import {
|
|
5
11
|
LibVlcPlayerViewNativeProps,
|
|
6
12
|
LibVlcPlayerViewProps,
|
|
7
13
|
LibVlcPlayerViewRef,
|
|
14
|
+
type NativeEvent,
|
|
8
15
|
type Error,
|
|
9
16
|
type Position,
|
|
10
17
|
type MediaTracks,
|
|
@@ -19,8 +26,11 @@ const NativeView: ComponentType<LibVlcPlayerViewNativeProps> =
|
|
|
19
26
|
let loggedRenderingChildrenWarning: boolean = false;
|
|
20
27
|
|
|
21
28
|
const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
22
|
-
(props,
|
|
29
|
+
(props, forwardedRef) => {
|
|
23
30
|
const nativeProps = convertNativeProps(props);
|
|
31
|
+
const ref = useRef<LibVlcPlayerViewRef | null>(null);
|
|
32
|
+
|
|
33
|
+
useImperativeHandle(forwardedRef, () => ref.current!);
|
|
24
34
|
|
|
25
35
|
// @ts-expect-error
|
|
26
36
|
if (nativeProps.children && !loggedRenderingChildrenWarning) {
|
|
@@ -30,25 +40,25 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
|
30
40
|
loggedRenderingChildrenWarning = true;
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
const onEncounteredError = ({ nativeEvent }:
|
|
43
|
+
const onEncounteredError = ({ nativeEvent }: NativeEvent<Error>) => {
|
|
34
44
|
if (props.onEncounteredError) {
|
|
35
45
|
props.onEncounteredError(nativeEvent);
|
|
36
46
|
}
|
|
37
47
|
};
|
|
38
48
|
|
|
39
|
-
const onPositionChanged = ({ nativeEvent }:
|
|
49
|
+
const onPositionChanged = ({ nativeEvent }: NativeEvent<Position>) => {
|
|
40
50
|
if (props.onPositionChanged) {
|
|
41
51
|
props.onPositionChanged(nativeEvent);
|
|
42
52
|
}
|
|
43
53
|
};
|
|
44
54
|
|
|
45
|
-
const onESAdded = ({ nativeEvent }:
|
|
55
|
+
const onESAdded = ({ nativeEvent }: NativeEvent<MediaTracks>) => {
|
|
46
56
|
if (props.onESAdded) {
|
|
47
57
|
props.onESAdded(nativeEvent);
|
|
48
58
|
}
|
|
49
59
|
};
|
|
50
60
|
|
|
51
|
-
const onFirstPlay = ({ nativeEvent }:
|
|
61
|
+
const onFirstPlay = ({ nativeEvent }: NativeEvent<MediaInfo>) => {
|
|
52
62
|
if (props.onFirstPlay) {
|
|
53
63
|
props.onFirstPlay(nativeEvent);
|
|
54
64
|
}
|
|
@@ -66,6 +76,27 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
|
|
|
66
76
|
onEncounteredError={onEncounteredError}
|
|
67
77
|
onPositionChanged={onPositionChanged}
|
|
68
78
|
onESAdded={onESAdded}
|
|
79
|
+
onDialogDisplay={({ nativeEvent: dialog }) => {
|
|
80
|
+
const alertButtons: AlertButton[] = [
|
|
81
|
+
{
|
|
82
|
+
text: dialog.action1Text,
|
|
83
|
+
onPress: () => ref.current?.postAction(1),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
text: dialog.action2Text,
|
|
87
|
+
onPress: () => ref.current?.postAction(2),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
text: dialog.cancelText,
|
|
91
|
+
onPress: () => ref.current?.dismiss(),
|
|
92
|
+
style: "cancel",
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const visibleButtons = alertButtons.filter((button) => button.text);
|
|
97
|
+
|
|
98
|
+
Alert.alert(dialog.title, dialog.text, visibleButtons);
|
|
99
|
+
}}
|
|
69
100
|
onFirstPlay={onFirstPlay}
|
|
70
101
|
/>
|
|
71
102
|
);
|