Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions flutter_vlc_player/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -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<String> options) {
this.options = options;
libVLC = new LibVLC(context, options);
Expand All @@ -147,14 +139,9 @@ private void setupVlcMediaPlayer() {
public void onEvent(MediaPlayer.Event event) {
HashMap<String, Object> 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();
Comment thread
naylinndev marked this conversation as resolved.
//
switch (event.type) {

Expand All @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -346,7 +325,7 @@ float getPlaybackSpeed() {
return mediaPlayer.getRate();
}

void seekTo(int location) {
void seekTo(long location) {
if (mediaPlayer == null) return;

mediaPlayer.setTime(location);
Expand All @@ -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<Integer, String> getSpuTracks() {
if (mediaPlayer == null) return new HashMap<Integer, String>();

MediaPlayer.TrackDescription[] spuTracks = mediaPlayer.getSpuTracks();
HashMap<Integer, String> 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<Integer, String>(); // 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<Integer, String> getAudioTracks() {
if (mediaPlayer == null) return new HashMap<Integer, String>();

MediaPlayer.TrackDescription[] audioTracks = mediaPlayer.getAudioTracks();
HashMap<Integer, String> 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<Integer, String>(); // 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<Integer, String> getVideoTracks() {
if (mediaPlayer == null) return new HashMap<Integer, String>();

MediaPlayer.TrackDescription[] videoTracks = mediaPlayer.getVideoTracks();
HashMap<Integer, String> 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<Integer, String>(); // 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
}
Comment thread
naylinndev marked this conversation as resolved.

void setVideoScale(float scale) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -564,9 +499,7 @@ public void onEvent(RendererDiscoverer.Event event) {
} catch (Exception ex) {
rendererDiscoverer.setEventListener(null);
}

}

}

void stopRendererScanning() {
Expand All @@ -582,7 +515,6 @@ void stopRendererScanning() {
rendererDiscoverers.clear();
rendererItems.clear();
//
// return back to default output
if (mediaPlayer != null) {
mediaPlayer.pause();
mediaPlayer.setRenderer(null);
Expand Down Expand Up @@ -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)) {
Expand All @@ -629,32 +560,33 @@ 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) {
if (debug) {
Log.d(TAG, message);
}
}

}
}
2 changes: 1 addition & 1 deletion flutter_vlc_player/example/android/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Loading