expo-libvlc-player 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,16 +43,16 @@ See the [example app](example/App.tsx) for additional usage.
43
43
 
44
44
  ### Player methods
45
45
 
46
- | Prop | Description | Params |
47
- | ------------------------ | ------------------------------------- | -------------------------------------- |
48
- | `play()` | Starts playback of the current player | |
49
- | `pause()` | Pauses playback of the current player | |
50
- | `stop()` | Stops playback of the current player | |
51
- | `seek(position: number)` | Sets position of the current player | Must be a float number between 0 and 1 |
46
+ | Method | Description | Params |
47
+ | --------- | ------------------------------------- | --------------------------------------------------- |
48
+ | `play()` | Starts playback of the current player | |
49
+ | `pause()` | Pauses playback of the current player | |
50
+ | `stop()` | Stops playback of the current player | |
51
+ | `seek()` | Sets position of the current player | `position` - Must be a float number between 0 and 1 |
52
52
 
53
53
  ### Player props
54
54
 
55
- The `VLCPlayerView` extends React Native `ViewProps` and implements it's own props:
55
+ The `VLCPlayerView` extends React Native `ViewProps` and implements it's own:
56
56
 
57
57
  | Prop | Description | Default |
58
58
  | ------------------ | ----------------------------------------------------------------------------------------- | -------- |
@@ -77,11 +77,11 @@ The `VLCPlayerView` extends React Native `ViewProps` and implements it's own pro
77
77
  | `onPlaying` | Called after the `Playing` player event | |
78
78
  | `onPaused` | Called after the `Paused` player event | |
79
79
  | `onStopped` | Called after the `Stopped` player event | |
80
+ | `onPositionChanged` | Called after the `PositionChanged` player event | `{ position: number }` |
80
81
  | `onEnded` | Called after the `EndReached` player event | |
81
82
  | `onRepeat` | Called after the player repeats the media | |
82
83
  | `onWarn` | Called after the player encounters a conflict | `{ warn: string }` |
83
84
  | `onError` | Called after the `EncounteredError` player event | `{ error: string }` |
84
- | `onPositionChanged` | Called after the `PositionChanged` player event | `{ position: number }` |
85
85
  | `onLoad` | Called after the `Buffering` player event | `{ width: number, height: number, aspectRatio: string, duration: number, tracks: object, seekable: boolean }` |
86
86
  | `onBackground` | Called after the player enters the background | |
87
87
 
@@ -4,7 +4,11 @@
4
4
  <option name="autoReloadType" value="NONE" />
5
5
  </component>
6
6
  <component name="ChangeListManager">
7
- <list default="true" id="ce1cf2d7-3e2c-41b3-ae06-62438ddceca7" name="Changes" comment="" />
7
+ <list default="true" id="ce1cf2d7-3e2c-41b3-ae06-62438ddceca7" name="Changes" comment="">
8
+ <change beforePath="$PROJECT_DIR$/src/main/java/expo/modules/libvlcplayer/VlcPlayerView.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/expo/modules/libvlcplayer/VlcPlayerView.kt" afterDir="false" />
9
+ <change beforePath="$PROJECT_DIR$/../example/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../example/App.tsx" afterDir="false" />
10
+ <change beforePath="$PROJECT_DIR$/../ios/VlcPlayerView.swift" beforeDir="false" afterPath="$PROJECT_DIR$/../ios/VlcPlayerView.swift" afterDir="false" />
11
+ </list>
8
12
  <option name="SHOW_DIALOG" value="false" />
9
13
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
14
  <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -52,7 +56,7 @@
52
56
  "android.gradle.sync.needed": "true",
53
57
  "cf.first.check.clang-format": "false",
54
58
  "cidr.known.project.marker": "true",
55
- "git-widget-placeholder": "0.1.0",
59
+ "git-widget-placeholder": "master",
56
60
  "ignore.virus.scanning.warn.message": "true",
57
61
  "kotlin-language-version-configured": "true",
58
62
  "last_opened_file_path": "//wsl.localhost/Ubuntu/home/rarbit/dev/expo-libvlc-player/android",
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'expo.modules.libvlcplayer'
4
- version = '0.1.0'
4
+ version = '0.1.3'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -35,7 +35,7 @@ android {
35
35
  namespace "expo.modules.libvlcplayer"
36
36
  defaultConfig {
37
37
  versionCode 1
38
- versionName "0.1.0"
38
+ versionName "0.1.3"
39
39
  consumerProguardFiles("proguard-rules.pro")
40
40
  }
41
41
  lintOptions {
@@ -38,7 +38,7 @@ class AudioFocusManager(
38
38
  } ?: false
39
39
  }
40
40
 
41
- private var previousVolume: Int = MAX_PLAYER_VOLUME
41
+ private var userVolume: Int = MAX_PLAYER_VOLUME
42
42
 
43
43
  private fun playerRequiresFocus(player: MediaPlayer?): Boolean {
44
44
  val mPlayer = player ?: return false
@@ -193,7 +193,7 @@ class AudioFocusManager(
193
193
  appContext.mainQueue.launch {
194
194
  val volume = weakPlayer.getVolume() / 20
195
195
  weakPlayer.setVolume(volume)
196
- previousVolume = volume
196
+ userVolume = volume
197
197
  }
198
198
  }
199
199
  }
@@ -202,7 +202,7 @@ class AudioFocusManager(
202
202
  player?.let { weakPlayer ->
203
203
  if (weakPlayer.getVolume() > MIN_PLAYER_VOLUME) {
204
204
  appContext.mainQueue.launch {
205
- weakPlayer.setVolume(previousVolume)
205
+ weakPlayer.setVolume(userVolume)
206
206
  }
207
207
  }
208
208
  }
@@ -96,6 +96,10 @@ class VlcPlayerModule : Module() {
96
96
  view.setAutoplay(autoplay ?: true)
97
97
  }
98
98
 
99
+ OnViewDidUpdateProps { view: VlcPlayerView ->
100
+ view.createPlayer()
101
+ }
102
+
99
103
  OnViewDestroys { view: VlcPlayerView ->
100
104
  VlcPlayerManager.onViewDestroyed(view)
101
105
  VlcPlayerManager.unregisterView(view)
@@ -42,8 +42,9 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
42
42
 
43
43
  private var libVLC: LibVLC? = null
44
44
  internal var mediaPlayer: MediaPlayer? = null
45
+ internal var shouldCreate: Boolean = false
45
46
 
46
- private var previousVolume: Int = MAX_PLAYER_VOLUME
47
+ private var userVolume: Int = MAX_PLAYER_VOLUME
47
48
  private var repeat: Boolean = false
48
49
  private var autoplay: Boolean = true
49
50
 
@@ -67,6 +68,8 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
67
68
  }
68
69
 
69
70
  fun createPlayer() {
71
+ if (!shouldCreate) return
72
+
70
73
  destroyPlayer()
71
74
 
72
75
  libVLC = LibVLC(context, options)
@@ -78,52 +81,54 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
78
81
  Event.Buffering -> {
79
82
  onBuffering(mapOf())
80
83
 
81
- val audioTracks = Arguments.createArray()
84
+ if (player.getPosition() == 0f) {
85
+ val audioTracks = Arguments.createArray()
82
86
 
83
- if (player.getAudioTracksCount() > 0) {
84
- val audios = player.getAudioTracks()
87
+ if (player.getAudioTracksCount() > 0) {
88
+ val audios = player.getAudioTracks()
85
89
 
86
- audios.forEach { track ->
87
- if (track.id == -1) return@forEach
88
- val trackMap = Arguments.createMap()
89
- trackMap.putInt("id", track.id)
90
- trackMap.putString("name", track.name)
91
- audioTracks.pushMap(trackMap)
90
+ audios.forEach { track ->
91
+ if (track.id == -1) return@forEach
92
+ val trackMap = Arguments.createMap()
93
+ trackMap.putInt("id", track.id)
94
+ trackMap.putString("name", track.name)
95
+ audioTracks.pushMap(trackMap)
96
+ }
92
97
  }
93
- }
94
98
 
95
- val subtitleTracks = Arguments.createArray()
99
+ val subtitleTracks = Arguments.createArray()
96
100
 
97
- if (player.getSpuTracksCount() > 0) {
98
- val subtitles = player.getSpuTracks()
101
+ if (player.getSpuTracksCount() > 0) {
102
+ val subtitles = player.getSpuTracks()
99
103
 
100
- subtitles.forEach { track ->
101
- val trackMap = Arguments.createMap()
102
- trackMap.putInt("id", track.id)
103
- trackMap.putString("name", track.name)
104
- subtitleTracks.pushMap(trackMap)
104
+ subtitles.forEach { track ->
105
+ val trackMap = Arguments.createMap()
106
+ trackMap.putInt("id", track.id)
107
+ trackMap.putString("name", track.name)
108
+ subtitleTracks.pushMap(trackMap)
109
+ }
105
110
  }
106
- }
107
111
 
108
- val video = player.getCurrentVideoTrack()
109
- val ratio = player.getAspectRatio()
110
- val length = player.getLength()
111
- val tracks = Arguments.createMap().apply {
112
- putArray("audio", audioTracks)
113
- putArray("subtitle", subtitleTracks)
114
- }
115
- val seekable = player.isSeekable()
116
-
117
- val videoInfo = Arguments.createMap().apply {
118
- putInt("width", video?.width ?: 0)
119
- putInt("height", video?.height ?: 0)
120
- putString("aspectRatio", ratio)
121
- putDouble("duration", length.toDouble())
122
- putMap("tracks", tracks)
123
- putBoolean("seekable", seekable)
124
- }
112
+ val video = player.getCurrentVideoTrack()
113
+ val ratio = player.getAspectRatio()
114
+ val length = player.getLength()
115
+ val tracks = Arguments.createMap().apply {
116
+ putArray("audio", audioTracks)
117
+ putArray("subtitle", subtitleTracks)
118
+ }
119
+ val seekable = player.isSeekable()
120
+
121
+ val videoInfo = Arguments.createMap().apply {
122
+ putInt("width", video?.width ?: 0)
123
+ putInt("height", video?.height ?: 0)
124
+ putString("aspectRatio", ratio)
125
+ putDouble("duration", length.toDouble())
126
+ putMap("tracks", tracks)
127
+ putBoolean("seekable", seekable)
128
+ }
125
129
 
126
- onLoad(videoInfo)
130
+ onLoad(videoInfo)
131
+ }
127
132
  }
128
133
 
129
134
  Event.Playing -> {
@@ -144,6 +149,11 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
144
149
  onPositionChanged(mapOf("position" to position))
145
150
  }
146
151
 
152
+ Event.PositionChanged -> {
153
+ val position = mapOf("position" to event.positionChanged)
154
+ onPositionChanged(position)
155
+ }
156
+
147
157
  Event.EndReached -> {
148
158
  onEnded(mapOf())
149
159
 
@@ -160,11 +170,6 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
160
170
  val error = mapOf("error" to "Player encountered an error")
161
171
  onError(error)
162
172
  }
163
-
164
- Event.PositionChanged -> {
165
- val position = mapOf("position" to event.positionChanged)
166
- onPositionChanged(position)
167
- }
168
173
  }
169
174
  })
170
175
 
@@ -182,6 +187,8 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
182
187
  player.play()
183
188
  }
184
189
  }
190
+
191
+ shouldCreate = false
185
192
  }
186
193
 
187
194
  fun destroyPlayer() {
@@ -198,9 +205,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
198
205
  val old = field
199
206
  field = value
200
207
 
201
- if (value != old) {
202
- createPlayer()
203
- }
208
+ shouldCreate = value != old
204
209
  }
205
210
 
206
211
  fun setSubtitle(subtitle: ReadableMap?) {
@@ -224,14 +229,12 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
224
229
  val old = field
225
230
  field = value
226
231
 
227
- if (value != old) {
228
- createPlayer()
229
- }
232
+ shouldCreate = value != old
230
233
  }
231
234
 
232
235
  fun setVolume(volume: Int) {
233
236
  val newVolume = volume.coerceIn(MIN_PLAYER_VOLUME, MAX_PLAYER_VOLUME)
234
- previousVolume = newVolume
237
+ userVolume = newVolume
235
238
 
236
239
  mediaPlayer?.setVolume(newVolume)
237
240
  audioFocusManager.updateAudioFocus()
@@ -239,7 +242,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
239
242
 
240
243
  fun setMute(mute: Boolean) {
241
244
  val newVolume = if (!mute) {
242
- previousVolume.coerceIn(PLAYER_VOLUME_STEP, MAX_PLAYER_VOLUME)
245
+ userVolume.coerceIn(PLAYER_VOLUME_STEP, MAX_PLAYER_VOLUME)
243
246
  } else {
244
247
  MIN_PLAYER_VOLUME
245
248
  }
@@ -86,6 +86,10 @@ public class VlcPlayerModule: Module {
86
86
  view.setAutoplay(autoplay ?? true)
87
87
  }
88
88
 
89
+ OnViewDidUpdateProps { (view: VlcPlayerView) in
90
+ view.createPlayer()
91
+ }
92
+
89
93
  AsyncFunction("play") { (view: VlcPlayerView) in
90
94
  view.play()
91
95
  }
@@ -12,10 +12,11 @@ private let enableSubtitles = true
12
12
 
13
13
  class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
14
14
  var mediaPlayer: VLCMediaPlayer?
15
+ var shouldCreate: Bool = false
15
16
 
16
17
  private var uri: String = ""
17
18
  private var options: [String] = []
18
- private var previousVolume: Int = maxPlayerVolume
19
+ private var userVolume: Int = maxPlayerVolume
19
20
  private var shouldRepeat: Bool = false
20
21
  var audioMixingMode: AudioMixingMode = .auto
21
22
  var playInBackground: Bool = false
@@ -43,6 +44,33 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
43
44
  clipsToBounds = true
44
45
  }
45
46
 
47
+ func createPlayer() {
48
+ if !shouldCreate { return }
49
+
50
+ destroyPlayer()
51
+
52
+ mediaPlayer = VLCMediaPlayer(options: options)
53
+
54
+ if let player = mediaPlayer {
55
+ player.delegate = self
56
+ player.drawable = self
57
+
58
+ guard let url = URL(string: uri) else {
59
+ let error = ["error": "Invalid URI, media could not be set"]
60
+ onError(error)
61
+ return
62
+ }
63
+
64
+ player.media = VLCMedia(url: url)
65
+
66
+ if autoplay {
67
+ player.play()
68
+ }
69
+ }
70
+
71
+ shouldCreate = false
72
+ }
73
+
46
74
  func mediaPlayerStateChanged(_: Notification) {
47
75
  guard let player = mediaPlayer else { return }
48
76
 
@@ -50,58 +78,60 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
50
78
  case .buffering:
51
79
  onBuffering([:])
52
80
 
53
- var audioTracks: [[String: Any]] = []
81
+ if player.position == 0.0 {
82
+ var audioTracks: [[String: Any]] = []
83
+
84
+ if let audios = player.audioTrackNames as? [String] {
85
+ if let audioIndexes = player.audioTrackIndexes as? [NSNumber] {
86
+ for (index, name) in audios.enumerated() {
87
+ let trackId = audioIndexes[index].intValue
88
+ if trackId != -1 && name != "Disable" {
89
+ audioTracks.append([
90
+ "id": trackId,
91
+ "name": name,
92
+ ])
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ var subtitleTracks: [[String: Any]] = []
54
99
 
55
- if let audios = player.audioTrackNames as? [String] {
56
- if let audioIndexes = player.audioTrackIndexes as? [NSNumber] {
57
- for (index, name) in audios.enumerated() {
58
- let trackId = audioIndexes[index].intValue
59
- if trackId != -1 && name != "Disable" {
60
- audioTracks.append([
100
+ if let subtitles = player.videoSubTitlesNames as? [String] {
101
+ if let subtitleIndexes = player.videoSubTitlesIndexes as? [NSNumber] {
102
+ for (index, name) in subtitles.enumerated() {
103
+ let trackId = subtitleIndexes[index].intValue
104
+ subtitleTracks.append([
61
105
  "id": trackId,
62
106
  "name": name,
63
107
  ])
64
108
  }
65
109
  }
66
110
  }
67
- }
68
111
 
69
- var subtitleTracks: [[String: Any]] = []
70
-
71
- if let subtitles = player.videoSubTitlesNames as? [String] {
72
- if let subtitleIndexes = player.videoSubTitlesIndexes as? [NSNumber] {
73
- for (index, name) in subtitles.enumerated() {
74
- let trackId = subtitleIndexes[index].intValue
75
- subtitleTracks.append([
76
- "id": trackId,
77
- "name": name,
78
- ])
79
- }
112
+ let video = player.videoSize
113
+ let ratio = player.videoAspectRatio
114
+ var length = 0
115
+ if let media = player.media {
116
+ length = Int(media.length.intValue)
80
117
  }
118
+ let tracks = [
119
+ "audio": audioTracks,
120
+ "subtitle": subtitleTracks,
121
+ ]
122
+ let seekable = player.isSeekable
123
+
124
+ let videoInfo: [String: Any] = [
125
+ "width": Int(video.width),
126
+ "height": Int(video.height),
127
+ "aspectRatio": ratio,
128
+ "duration": Double(length),
129
+ "tracks": tracks,
130
+ "seekable": seekable,
131
+ ]
132
+
133
+ onLoad(videoInfo)
81
134
  }
82
-
83
- let video = player.videoSize
84
- let ratio = player.videoAspectRatio
85
- var length = 0
86
- if let media = player.media {
87
- length = Int(media.length.intValue)
88
- }
89
- let tracks = [
90
- "audio": audioTracks,
91
- "subtitle": subtitleTracks,
92
- ]
93
- let seekable = player.isSeekable
94
-
95
- let videoInfo: [String: Any] = [
96
- "width": Int(video.width),
97
- "height": Int(video.height),
98
- "aspectRatio": ratio,
99
- "duration": Double(length),
100
- "tracks": tracks,
101
- "seekable": seekable,
102
- ]
103
-
104
- onLoad(videoInfo)
105
135
  case .playing:
106
136
  onPlaying([:])
107
137
  VlcPlayerManager.shared.setAppropriateAudioSessionOrWarn()
@@ -139,29 +169,6 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
139
169
  onPositionChanged(position)
140
170
  }
141
171
 
142
- func createPlayer() {
143
- destroyPlayer()
144
-
145
- mediaPlayer = VLCMediaPlayer(options: options)
146
-
147
- if let player = mediaPlayer {
148
- player.delegate = self
149
- player.drawable = self
150
-
151
- guard let url = URL(string: uri) else {
152
- let error = ["error": "Invalid URI, media could not be set"]
153
- onError(error)
154
- return
155
- }
156
-
157
- player.media = VLCMedia(url: url)
158
-
159
- if autoplay {
160
- player.play()
161
- }
162
- }
163
- }
164
-
165
172
  func destroyPlayer() {
166
173
  if let player = mediaPlayer {
167
174
  player.stop()
@@ -173,9 +180,7 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
173
180
  let old = self.uri
174
181
  self.uri = uri
175
182
 
176
- if uri != old {
177
- createPlayer()
178
- }
183
+ shouldCreate = uri != old
179
184
  }
180
185
 
181
186
  func setSubtitle(_ subtitle: [String: Any]?) {
@@ -200,16 +205,14 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
200
205
  let old = self.options
201
206
  self.options = options
202
207
 
203
- if options != old {
204
- createPlayer()
205
- }
208
+ shouldCreate = options != old
206
209
  }
207
210
 
208
211
  func setVolume(_ volume: Int) {
209
212
  guard let player = mediaPlayer else { return }
210
213
 
211
214
  let newVolume = max(minPlayerVolume, min(maxPlayerVolume, volume))
212
- previousVolume = newVolume
215
+ userVolume = newVolume
213
216
 
214
217
  player.audio?.volume = Int32(newVolume)
215
218
  VlcPlayerManager.shared.setAppropriateAudioSessionOrWarn()
@@ -219,7 +222,7 @@ class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
219
222
  guard let player = mediaPlayer else { return }
220
223
 
221
224
  let newVolume = !mute ?
222
- max(playerVolumeStep, min(maxPlayerVolume, previousVolume)) :
225
+ max(playerVolumeStep, min(maxPlayerVolume, userVolume)) :
223
226
  minPlayerVolume
224
227
 
225
228
  player.audio?.volume = Int32(newVolume)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-libvlc-player",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "LibVLC Player for Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",