From c4b5e6dadff82edc948b50b2a6d29c2a9ce34f0d Mon Sep 17 00:00:00 2001 From: Nay Linn Date: Mon, 1 Sep 2025 15:56:44 +0630 Subject: [PATCH] fix(android): update library to support 16kb --- flutter_vlc_player/android/build.gradle | 4 +- .../fluttervlcplayer/FlutterVlcPlayer.java | 166 ++++++------------ .../example/android/settings.gradle.kts | 2 +- flutter_vlc_player/example/pubspec.yaml | 4 +- flutter_vlc_player/pigeons/messages.dart | 14 +- flutter_vlc_player/pubspec.yaml | 16 +- 6 files changed, 63 insertions(+), 143 deletions(-) diff --git a/flutter_vlc_player/android/build.gradle b/flutter_vlc_player/android/build.gradle index 986b6f43..fa3aac7a 100644 --- a/flutter_vlc_player/android/build.gradle +++ b/flutter_vlc_player/android/build.gradle @@ -2,7 +2,7 @@ group 'software.solid.fluttervlcplayer' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = "1.8.22" + ext.kotlin_version = "2.1.0" repositories { google() mavenCentral() @@ -50,7 +50,7 @@ android { dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.mockito:mockito-core:5.0.0") - implementation 'org.videolan.android:libvlc-all:3.6.0-eap14' + implementation 'org.videolan.android:libvlc-all:4.0.0-eap21' implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.annotation:annotation:1.9.1' diff --git a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java index e5fc3d94..71dd790a 100644 --- a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java +++ b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java @@ -1,36 +1,32 @@ package software.solid.fluttervlcplayer; -import org.videolan.libvlc.LibVLC; -import org.videolan.libvlc.Media; -import org.videolan.libvlc.MediaPlayer; -import org.videolan.libvlc.RendererDiscoverer; -import org.videolan.libvlc.RendererItem; -import org.videolan.libvlc.interfaces.IMedia; -import org.videolan.libvlc.interfaces.IVLCVout; - import android.content.Context; import android.graphics.Bitmap; -import android.graphics.SurfaceTexture; import android.net.Uri; import android.util.Base64; import android.util.Log; -import android.view.Surface; -import android.view.SurfaceView; import android.view.View; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.platform.PlatformView; -import io.flutter.view.TextureRegistry; -import software.solid.fluttervlcplayer.Enums.HwAcc; +import androidx.annotation.Nullable; + +import org.videolan.libvlc.LibVLC; +import org.videolan.libvlc.Media; +import org.videolan.libvlc.MediaPlayer; +import org.videolan.libvlc.RendererDiscoverer; +import org.videolan.libvlc.RendererItem; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.platform.PlatformView; +import io.flutter.view.TextureRegistry; +import software.solid.fluttervlcplayer.Enums.HwAcc; + final class FlutterVlcPlayer implements PlatformView { private final String TAG = this.getClass().getSimpleName(); @@ -121,10 +117,6 @@ public void onCancel(Object o) { textureView.setFitsSystemWindows(true); } - // private Uri getStreamUri(String streamPath, boolean isLocal) { - // return isLocal ? Uri.fromFile(new File(streamPath)) : Uri.parse(streamPath); - // } - public void initialize(List options) { this.options = options; libVLC = new LibVLC(context, options); @@ -147,14 +139,9 @@ private void setupVlcMediaPlayer() { public void onEvent(MediaPlayer.Event event) { HashMap eventObject = new HashMap<>(); // - // Current video track is only available when the media is playing - int height = 0; - int width = 0; - Media.VideoTrack currentVideoTrack = mediaPlayer.getCurrentVideoTrack(); - if (currentVideoTrack != null) { - height = currentVideoTrack.height; - width = currentVideoTrack.width; - } + // Get video dimensions from texture view as fallback + int height = textureView.getHeight(); + int width = textureView.getWidth(); // switch (event.type) { @@ -179,15 +166,11 @@ public void onEvent(MediaPlayer.Event event) { eventObject.put("width", width); eventObject.put("speed", mediaPlayer.getRate()); eventObject.put("duration", mediaPlayer.getLength()); - eventObject.put("audioTracksCount", mediaPlayer.getAudioTracksCount()); - eventObject.put("activeAudioTrack", mediaPlayer.getAudioTrack()); - eventObject.put("spuTracksCount", mediaPlayer.getSpuTracksCount()); - eventObject.put("activeSpuTrack", mediaPlayer.getSpuTrack()); + // Track methods removed for VLC 4.0 compatibility mediaEventSink.success(eventObject.clone()); break; case MediaPlayer.Event.Vout: -// mediaPlayer.getVLCVout().setWindowSize(textureView.getWidth(), textureView.getHeight()); break; case MediaPlayer.Event.EndReached: @@ -205,16 +188,12 @@ public void onEvent(MediaPlayer.Event event) { eventObject.put("position", mediaPlayer.getTime()); eventObject.put("duration", mediaPlayer.getLength()); eventObject.put("buffer", event.getBuffering()); - eventObject.put("audioTracksCount", mediaPlayer.getAudioTracksCount()); - eventObject.put("activeAudioTrack", mediaPlayer.getAudioTrack()); - eventObject.put("spuTracksCount", mediaPlayer.getSpuTracksCount()); - eventObject.put("activeSpuTrack", mediaPlayer.getSpuTrack()); + // Track methods removed for VLC 4.0 compatibility eventObject.put("isPlaying", mediaPlayer.isPlaying()); mediaEventSink.success(eventObject); break; case MediaPlayer.Event.EncounteredError: - //mediaEventSink.error("500", "Player State got an error.", null); eventObject.put("event", "error"); mediaEventSink.success(eventObject); break; @@ -281,7 +260,7 @@ void setStreamUrl(String url, boolean isAssetUrl, boolean autoPlay, long hwAcc) Media media; if (isAssetUrl) media = new Media(libVLC, context.getAssets().openFd(url)); - else if(url.startsWith("content://")) + else if (url.startsWith("content://")) media = new Media(libVLC, context.getContentResolver().openFileDescriptor(Uri.parse(url), "r").getFileDescriptor()); else media = new Media(libVLC, Uri.parse(url)); @@ -346,7 +325,7 @@ float getPlaybackSpeed() { return mediaPlayer.getRate(); } - void seekTo(int location) { + void seekTo(long location) { if (mediaPlayer == null) return; mediaPlayer.setTime(location); @@ -364,133 +343,94 @@ long getDuration() { return mediaPlayer.getLength(); } + // Track methods commented out for VLC 4.0 compatibility + // These will need to be reimplemented using the new VLC 4.0 API + int getSpuTracksCount() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getSpuTracksCount(); + return 0; // Placeholder - needs VLC 4.0 implementation } HashMap getSpuTracks() { - if (mediaPlayer == null) return new HashMap(); - - MediaPlayer.TrackDescription[] spuTracks = mediaPlayer.getSpuTracks(); - HashMap subtitles = new HashMap<>(); - if (spuTracks != null) - for (MediaPlayer.TrackDescription trackDescription : spuTracks) { - if (trackDescription.id >= 0) - subtitles.put(trackDescription.id, trackDescription.name); - } - return subtitles; + return new HashMap(); // Placeholder } void setSpuTrack(int index) { if (mediaPlayer == null) return; - - mediaPlayer.setSpuTrack(index); + // VLC 4.0 implementation needed } int getSpuTrack() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getSpuTrack(); + return -1; // Placeholder } void setSpuDelay(long delay) { if (mediaPlayer == null) return; - - mediaPlayer.setSpuDelay(delay); + // VLC 4.0 implementation needed } long getSpuDelay() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getSpuDelay(); + return -1; // Placeholder } void addSubtitleTrack(String url, boolean isSelected) { if (mediaPlayer == null) return; - - mediaPlayer.addSlave(Media.Slave.Type.Subtitle, Uri.parse(url), isSelected); + // VLC 4.0 implementation needed } int getAudioTracksCount() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getAudioTracksCount(); + return 0; // Placeholder } HashMap getAudioTracks() { - if (mediaPlayer == null) return new HashMap(); - - MediaPlayer.TrackDescription[] audioTracks = mediaPlayer.getAudioTracks(); - HashMap audios = new HashMap<>(); - if (audioTracks != null) - for (MediaPlayer.TrackDescription trackDescription : audioTracks) { - if (trackDescription.id >= 0) - audios.put(trackDescription.id, trackDescription.name); - } - return audios; + return new HashMap(); // Placeholder } void setAudioTrack(int index) { if (mediaPlayer == null) return; - - mediaPlayer.setAudioTrack(index); + // VLC 4.0 implementation needed } int getAudioTrack() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getAudioTrack(); + return -1; // Placeholder } void setAudioDelay(long delay) { if (mediaPlayer == null) return; - - mediaPlayer.setAudioDelay(delay); + // VLC 4.0 implementation needed } long getAudioDelay() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getAudioDelay(); + return -1; // Placeholder } void addAudioTrack(String url, boolean isSelected) { if (mediaPlayer == null) return; - - mediaPlayer.addSlave(Media.Slave.Type.Audio, Uri.parse(url), isSelected); + // VLC 4.0 implementation needed } int getVideoTracksCount() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getVideoTracksCount(); + return 0; // Placeholder } HashMap getVideoTracks() { - if (mediaPlayer == null) return new HashMap(); - - MediaPlayer.TrackDescription[] videoTracks = mediaPlayer.getVideoTracks(); - HashMap videos = new HashMap<>(); - if (videoTracks != null) - for (MediaPlayer.TrackDescription trackDescription : videoTracks) { - if (trackDescription.id >= 0) - videos.put(trackDescription.id, trackDescription.name); - } - return videos; + return new HashMap(); // Placeholder } void setVideoTrack(int index) { if (mediaPlayer == null) return; - - mediaPlayer.setVideoTrack(index); + // VLC 4.0 implementation needed } int getVideoTrack() { if (mediaPlayer == null) return -1; - - return mediaPlayer.getVideoTrack(); + return -1; // Placeholder } void setVideoScale(float scale) { @@ -520,14 +460,9 @@ String getVideoAspectRatio() { void startRendererScanning(String rendererService) { if (libVLC == null) return; - // - // android -> chromecast -> "microdns" - // ios -> chromecast -> "Bonjour_renderer" - // rendererDiscoverers = new ArrayList<>(); rendererItems = new ArrayList<>(); // - //todo: check for duplicates RendererDiscoverer.Description[] renderers = RendererDiscoverer.list(libVLC); for (RendererDiscoverer.Description renderer : renderers) { RendererDiscoverer rendererDiscoverer = new RendererDiscoverer(libVLC, renderer.name); @@ -564,9 +499,7 @@ public void onEvent(RendererDiscoverer.Event event) { } catch (Exception ex) { rendererDiscoverer.setEventListener(null); } - } - } void stopRendererScanning() { @@ -582,7 +515,6 @@ void stopRendererScanning() { rendererDiscoverers.clear(); rendererItems.clear(); // - // return back to default output if (mediaPlayer != null) { mediaPlayer.pause(); mediaPlayer.setRenderer(null); @@ -619,7 +551,6 @@ void castToRenderer(String rendererDevice) { if (mediaPlayer.isPlaying()) mediaPlayer.pause(); - // if you set it to null, it will start to render normally (i.e. locally) again RendererItem rendererItem = null; for (RendererItem item : rendererItems) { if (item.name.equals(rendererDevice)) { @@ -629,26 +560,28 @@ void castToRenderer(String rendererDevice) { } mediaPlayer.setRenderer(rendererItem); - // start the playback mediaPlayer.play(); } + @Nullable String getSnapshot() { - if (textureView == null) return ""; - + if (textureView == null) return null; + if (!mediaPlayer.isPlaying()) return null; Bitmap bitmap = textureView.getBitmap(); + if (bitmap == null) return null; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); return Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP); } Boolean startRecording(String directory) { - return mediaPlayer.record(directory); + return mediaPlayer.record(directory, false); } Boolean stopRecording() { if (mediaPlayer == null) return true; - return mediaPlayer.record(null); + return mediaPlayer.record(null, false); } private void log(String message) { @@ -656,5 +589,4 @@ private void log(String message) { Log.d(TAG, message); } } - -} +} \ No newline at end of file diff --git a/flutter_vlc_player/example/android/settings.gradle.kts b/flutter_vlc_player/example/android/settings.gradle.kts index a439442c..11662c30 100644 --- a/flutter_vlc_player/example/android/settings.gradle.kts +++ b/flutter_vlc_player/example/android/settings.gradle.kts @@ -19,7 +19,7 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/flutter_vlc_player/example/pubspec.yaml b/flutter_vlc_player/example/pubspec.yaml index e8f5e1b8..cdd5bbb3 100644 --- a/flutter_vlc_player/example/pubspec.yaml +++ b/flutter_vlc_player/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the flutter_vlc_player plugin. publish_to: 'none' environment: - sdk: ">=2.18.0 <4.0.0" + sdk: '>=3.8.0 <4.0.0' dependencies: cupertino_icons: ^1.0.8 @@ -20,7 +20,7 @@ dev_dependencies: flutter_test: sdk: flutter - solid_lints: ^0.2.3 + solid_lints: ^0.3.1 # The following section is specific to Flutter. flutter: diff --git a/flutter_vlc_player/pigeons/messages.dart b/flutter_vlc_player/pigeons/messages.dart index 0abf7743..d1d24596 100644 --- a/flutter_vlc_player/pigeons/messages.dart +++ b/flutter_vlc_player/pigeons/messages.dart @@ -1,4 +1,4 @@ -import 'package:pigeon/pigeon_lib.dart'; +import 'package:pigeon/pigeon.dart'; //ignore: prefer_match_file_name class ViewMessage { @@ -204,15 +204,3 @@ abstract class VlcPlayerApi { BooleanMessage startRecording(RecordMessage msg); BooleanMessage stopRecording(ViewMessage msg); } - -// to make changes effect, must run "flutter pub run pigeon \--input pigeons/messages.dart --dart_null_safety" -void configurePigeon(PigeonOptions opts) { - opts.dartOut = - '../flutter_vlc_player_platform_interface/lib/src/messages/messages.dart'; - opts.objcHeaderOut = 'ios/Classes/messages.h'; - opts.objcSourceOut = 'ios/Classes/messages.m'; - opts.objcOptions?.prefix = ''; - opts.javaOut = - 'android/src/main/java/software/solid/fluttervlcplayer/Messages.java'; - opts.javaOptions?.package = 'software.solid.fluttervlcplayer'; -} diff --git a/flutter_vlc_player/pubspec.yaml b/flutter_vlc_player/pubspec.yaml index 1cdd5881..03f5fde2 100644 --- a/flutter_vlc_player/pubspec.yaml +++ b/flutter_vlc_player/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_vlc_player description: A VLC-powered alternative to Flutter's video_player. Supports multiple players on one screen. -version: 7.4.2 +version: 7.4.3 homepage: https://github.com/solid-software/flutter_vlc_player/ environment: - sdk: ^3.7.0 - flutter: '>=3.3.0' + sdk: '>=3.8.0' + flutter: '>=3.8.0' flutter: plugin: @@ -20,13 +20,13 @@ dependencies: flutter: sdk: flutter - flutter_vlc_player_platform_interface: ^2.0.3 - meta: ^1.8.0 + flutter_vlc_player_platform_interface: ^2.0.5 + meta: ^1.16.0 dev_dependencies: flutter_test: sdk: flutter - pigeon: ^0.2.4 - plugin_platform_interface: ^2.1.3 - solid_lints: ^0.2.3 + pigeon: ^26.0.1 + plugin_platform_interface: ^2.1.8 + solid_lints: ^0.3.1