extended-vlc-player 0.1.3 → 0.1.4

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.
@@ -1,15 +1,3 @@
1
- // Top-level build file for the `extended-vlc-player` local Expo Module.
2
- buildscript {
3
- repositories {
4
- google()
5
- mavenCentral()
6
- }
7
- dependencies {
8
- classpath 'com.android.tools.build:gradle'
9
- classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin'
10
- }
11
- }
12
-
13
1
  apply plugin: 'com.android.library'
14
2
  apply plugin: 'kotlin-android'
15
3
  apply plugin: 'expo-module-gradle-plugin'
@@ -20,8 +8,8 @@ version = '0.1.0'
20
8
  android {
21
9
  namespace 'expo.modules.extendedvlcplayer'
22
10
  defaultConfig {
23
- minSdkVersion (findProperty('expo.minSdkVersion') ?: 26).toInteger()
24
- targetSdkVersion (findProperty('expo.targetSdkVersion') ?: 34).toInteger()
11
+ versionCode 1
12
+ versionName '0.1.0'
25
13
  }
26
14
  // The libVLC .so files ship native code for four ABIs. The Expo app
27
15
  // already filters to its own ABIs in android/app/build.gradle; the host
@@ -32,5 +20,5 @@ android {
32
20
  }
33
21
 
34
22
  dependencies {
35
- implementation 'org.videolan.android:libvlc:3.6.0'
23
+ implementation 'org.videolan.android:libvlc-all:3.6.0'
36
24
  }
@@ -24,7 +24,7 @@ class ExtendedVlcPlayerModule : Module() {
24
24
 
25
25
  AsyncFunction("isPictureInPictureSupported") {
26
26
  Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
27
- appContext.activity?.application?.packageManager?.hasSystemFeature(
27
+ appContext.currentActivity?.application?.packageManager?.hasSystemFeature(
28
28
  android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE
29
29
  ) == true
30
30
  }
@@ -76,7 +76,7 @@ class ExtendedVlcPlayerModule : Module() {
76
76
  }
77
77
 
78
78
  AsyncFunction("startPictureInPicture") { instanceId: Int ->
79
- val activity = appContext.activity ?: return@AsyncFunction false
79
+ val activity = appContext.currentActivity ?: return@AsyncFunction false
80
80
  val session = PlayerRegistry.session(instanceId) ?: return@AsyncFunction false
81
81
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return@AsyncFunction false
82
82
  val params = PictureInPictureParams.Builder()
@@ -49,9 +49,10 @@ class PlayerSession(
49
49
  init {
50
50
  surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
51
51
  override fun surfaceCreated(holder: SurfaceHolder) {
52
- mediaPlayer.vout.setVideoSurface(holder.surface, surfaceView.holder)
52
+ val vout = mediaPlayer.getVLCVout()
53
+ vout.setVideoView(surfaceView)
53
54
  if (!isAttached) {
54
- mediaPlayer.attachViews(arrayOf<Any>(surfaceView).toJavaArray())
55
+ vout.attachViews()
55
56
  isAttached = true
56
57
  }
57
58
  mediaPlayer.play()
@@ -60,36 +61,40 @@ class PlayerSession(
60
61
  override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
61
62
 
62
63
  override fun surfaceDestroyed(holder: SurfaceHolder) {
63
- mediaPlayer.vout.setVideoSurface(null, null)
64
+ val vout = mediaPlayer.getVLCVout()
65
+ if (vout.areViewsAttached()) {
66
+ vout.detachViews()
67
+ }
68
+ isAttached = false
64
69
  }
65
70
  })
66
71
 
67
72
  mediaPlayer.setEventListener { event ->
68
73
  when (event.type) {
69
- MediaPlayer.Event.Playing -> onPlaying?.invoke(mapOf("duration" to (event.durationMs / 1000.0)))
74
+ MediaPlayer.Event.Playing -> onPlaying?.invoke(mapOf("duration" to durationSeconds()))
70
75
  MediaPlayer.Event.Paused -> onPaused?.invoke(emptyMap())
71
76
  MediaPlayer.Event.Stopped -> onEnded?.invoke()
72
77
  MediaPlayer.Event.EndReached -> onEnded?.invoke()
73
78
  MediaPlayer.Event.EncounteredError -> onError?.invoke(
74
79
  mapOf(
75
- "message" to (event.escapedVlcError ?: "libVLC error"),
80
+ "message" to "libVLC error",
76
81
  "code" to "VLC_ERROR",
77
82
  "domain" to "libVLC"
78
83
  )
79
84
  )
80
- MediaPlayer.Event.Buffering -> onBuffering?.invoke(mapOf("isBuffering" to event.buffering.toDouble() < 100.0))
85
+ MediaPlayer.Event.Buffering -> onBuffering?.invoke(mapOf("isBuffering" to (event.getBuffering() < 100.0f)))
81
86
  MediaPlayer.Event.Opening -> onLoad?.invoke(
82
87
  mapOf(
83
- "duration" to (event.durationMs / 1000.0),
88
+ "duration" to durationSeconds(),
84
89
  "audioTracks" to emptyList<Map<String, Any>>(),
85
90
  "textTracks" to emptyList<Map<String, Any>>()
86
91
  )
87
92
  )
88
93
  MediaPlayer.Event.TimeChanged -> onProgress?.invoke(
89
94
  mapOf(
90
- "currentTime" to (event.timeChanged / 1000.0),
91
- "duration" to (event.durationMs / 1000.0),
92
- "position" to (if (event.durationMs > 0) event.timeChanged.toDouble() / event.durationMs else 0.0)
95
+ "currentTime" to (event.getTimeChanged() / 1000.0),
96
+ "duration" to durationSeconds(),
97
+ "position" to (if (mediaPlayer.getLength() > 0) event.getTimeChanged().toDouble() / mediaPlayer.getLength() else 0.0)
93
98
  )
94
99
  )
95
100
  }
@@ -103,6 +108,8 @@ class PlayerSession(
103
108
  mediaPlayer.media = media
104
109
  }
105
110
 
111
+ private fun durationSeconds(): Double = mediaPlayer.getLength() / 1000.0
112
+
106
113
  fun play() = mediaPlayer.play()
107
114
  fun pause() = mediaPlayer.pause()
108
115
  fun stop() = mediaPlayer.stop()
@@ -163,6 +170,3 @@ class PlayerSession(
163
170
  libVlc.release()
164
171
  }
165
172
  }
166
-
167
- // Helper to convert Kotlin Array to Java Array (libVLC's attachViews is Java).
168
- private inline fun <reified T> Array<out T>.toJavaArray(): Array<T> = this as Array<T>
package/app.plugin.js CHANGED
@@ -65,7 +65,7 @@ function withIosPods(config, options) {
65
65
  // ---- iOS Info.plist -------------------------------------------------------
66
66
 
67
67
  const INFOPLIST_TAG = 'extended-vlc-player-info-plist';
68
- const INFOPLIST_AUDIO_SESSION = '# extended-vlc-player: keep audio session active for PiP and background playback';
68
+ const INFOPLIST_AUDIO_SESSION = '// extended-vlc-player: keep audio session active for PiP and background playback';
69
69
 
70
70
  function withIosInfoPlist(config) {
71
71
  return withInfoPlist(config, (infoPlist) => {
@@ -80,7 +80,7 @@ function withIosInfoPlist(config) {
80
80
  // ---- Android build.gradle ------------------------------------------------
81
81
 
82
82
  const GRADLE_TAG = 'extended-vlc-player-gradle';
83
- const GRADLE_VLC = (vlcVersion) => ` implementation "org.videolan.android:libvlc:${vlcVersion}"`;
83
+ const GRADLE_VLC = (vlcVersion) => ` implementation "org.videolan.android:libvlc-all:${vlcVersion}"`;
84
84
 
85
85
  function withAndroidGradle(config, options) {
86
86
  const vlcVersion = (options?.android?.libVlcVersion || '3.6.0').toString();
@@ -24,6 +24,8 @@ Pod::Spec.new do |s|
24
24
  s.source_files = '**/*.{h,m,mm,swift}'
25
25
  s.pod_target_xcconfig = {
26
26
  'DEFINES_MODULE' => 'YES',
27
+ 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++20',
28
+ 'CLANG_CXX_LIBRARY' => 'libc++',
27
29
  'SWIFT_OBJC_INTERFACE_HEADER_NAME' => 'ExtendedVlcPlayer-Swift.h',
28
30
  'OTHER_SWIFT_FLAGS' => '$(inherited) -D COCOAPODS -Xfrontend -module-name -Xfrontend ExtendedVlcPlayer',
29
31
  # The host app's Podfile already enables use_frameworks! :linkage => :static
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "extended-vlc-player",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "React Native video player built on MobileVLCKit (iOS) and libVLC (Android) with true iOS Picture-in-Picture via AVSampleBufferDisplayLayer bridge.",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",