Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
47 changes: 25 additions & 22 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,52 +1,55 @@
group 'io.flutter.plugins.videoplayer'
group 'android'
version '1.0-SNAPSHOT'
def args = ["-Xlint:deprecation","-Xlint:unchecked","-Werror"]

def args = ["-Xlint:deprecation", "-Xlint:unchecked"]

buildscript {
ext.kotlin_version = '1.9.22'
repositories {
google()
jcenter()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:8.3.2'
}
}

rootProject.allprojects {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

project.getTasks().withType(JavaCompile){
tasks.withType(JavaCompile).configureEach {
options.compilerArgs.addAll(args)
}

apply plugin: 'com.android.library'

android {
compileSdkVersion 29
namespace 'com.lazyarts.vikram.cached_video_player'
compileSdk 34

defaultConfig {
minSdkVersion 16
minSdk 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
disable 'InvalidPackage'
}
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

dependencies {
implementation 'com.google.android.exoplayer:exoplayer-core:2.17.1'
implementation 'com.google.android.exoplayer:exoplayer-hls:2.17.1'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.17.1'
implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.17.1'
lint {
disable 'InvalidPackage'
}
}

dependencies {
implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1'
implementation 'com.google.android.exoplayer:exoplayer-hls:2.19.1'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.19.1'
implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.19.1'
}
3 changes: 1 addition & 2 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Wed Oct 17 09:04:56 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
14 changes: 14 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
rootProject.name = 'cached_video_player'

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()

localPropertiesFile.withReader("UTF-8") { reader ->
properties.load(reader)
}

def flutterSdkPath = properties.getProperty("flutter.sdk")
if (flutterSdkPath == null) {
throw new GradleException("flutter.sdk not set in local.properties")
}

apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import android.content.Context;

import androidx.annotation.NonNull;

import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
Expand All @@ -15,10 +17,9 @@

class CacheDataSourceFactory implements DataSource.Factory {
private final Context context;
private DefaultDataSource.Factory defaultDatasourceFactory;
private final long maxFileSize, maxCacheSize;

private DefaultHttpDataSource.Factory defaultHttpDataSourceFactory;
private final DefaultHttpDataSource.Factory defaultHttpDataSourceFactory;

CacheDataSourceFactory(Context context, long maxCacheSize, long maxFileSize) {
super();
Expand All @@ -35,11 +36,12 @@ void setHeaders(Map<String, String> httpHeaders) {
defaultHttpDataSourceFactory.setDefaultRequestProperties(httpHeaders);
}

@NonNull
@Override
public DataSource createDataSource() {
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build();

defaultDatasourceFactory = new DefaultDataSource.Factory(this.context, defaultHttpDataSourceFactory);
DefaultDataSource.Factory defaultDatasourceFactory = new DefaultDataSource.Factory(this.context, defaultHttpDataSourceFactory);
defaultDatasourceFactory.setTransferListener(bandwidthMeter);

SimpleCache simpleCache = SimpleCacheSingleton.getInstance(context, maxCacheSize).simpleCache;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.source.MediaSource;
Expand Down Expand Up @@ -47,13 +46,13 @@ final class CachedVideoPlayer {
private static final String FORMAT_HLS = "hls";
private static final String FORMAT_OTHER = "other";

private ExoPlayer exoPlayer;
private final ExoPlayer exoPlayer;

private Surface surface;

private final TextureRegistry.SurfaceTextureEntry textureEntry;

private QueuingEventSink eventSink = new QueuingEventSink();
private final QueuingEventSink eventSink = new QueuingEventSink();

private final EventChannel eventChannel;

Expand Down Expand Up @@ -114,45 +113,32 @@ private MediaSource buildMediaSource(
if (formatHint == null) {
type = Util.inferContentType(uri.getLastPathSegment());
} else {
switch (formatHint) {
case FORMAT_SS:
type = C.TYPE_SS;
break;
case FORMAT_DASH:
type = C.TYPE_DASH;
break;
case FORMAT_HLS:
type = C.TYPE_HLS;
break;
case FORMAT_OTHER:
type = C.TYPE_OTHER;
break;
default:
type = -1;
break;
}
}
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_DASH:
return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_OTHER:
return new ProgressiveMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(MediaItem.fromUri(uri));
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
type = switch (formatHint) {
case FORMAT_SS -> C.TYPE_SS;
case FORMAT_DASH -> C.TYPE_DASH;
case FORMAT_HLS -> C.TYPE_HLS;
case FORMAT_OTHER -> C.TYPE_OTHER;
default -> -1;
};
}
return switch (type) {
case C.TYPE_SS -> new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_DASH -> new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_HLS ->
new HlsMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(MediaItem.fromUri(uri));
case C.TYPE_OTHER ->
new ProgressiveMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(MediaItem.fromUri(uri));
default ->
throw new IllegalStateException("Unsupported type: " + type);
};
}

private void setupVideoPlayer(
Expand Down Expand Up @@ -212,9 +198,7 @@ public void onPlaybackStateChanged(final int playbackState) {
@Override
public void onPlayerError(@NonNull PlaybackException error) {
setBuffering(false);
if (eventSink != null) {
eventSink.error("VideoError", "Video player had error " + error, null);
}
eventSink.error("VideoError", "Video player had error " + error, null);
}
});
}
Expand All @@ -230,7 +214,7 @@ void sendBufferingUpdate() {

private static void setAudioAttributes(ExoPlayer exoPlayer, boolean isMixMode) {
exoPlayer.setAudioAttributes(
new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build(), !isMixMode);
new AudioAttributes.Builder().setContentType(com.google.android.exoplayer2.C.AUDIO_CONTENT_TYPE_MOVIE).build(), !isMixMode);
}

void play() {
Expand All @@ -253,9 +237,7 @@ void setVolume(double value) {
void setPlaybackSpeed(double value) {
// We do not need to consider pitch and skipSilence for now as we do not handle them and
// therefore never diverge from the default values.
final PlaybackParameters playbackParameters = new PlaybackParameters(((float) value));

exoPlayer.setPlaybackParameters(playbackParameters);
exoPlayer.setPlaybackSpeed((float) value);
}

void seekTo(int location) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import android.content.Context;
import android.os.Build;
import android.util.LongSparseArray;

import androidx.annotation.NonNull;

import io.flutter.FlutterInjector;
import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
Expand All @@ -31,7 +34,7 @@ public class CachedVideoPlayerPlugin implements FlutterPlugin, VideoPlayerApi {
private static final String TAG = "VideoPlayerPlugin";
private final LongSparseArray<CachedVideoPlayer> videoPlayers = new LongSparseArray<>();
private FlutterState flutterState;
private VideoPlayerOptions options = new VideoPlayerOptions();
private final VideoPlayerOptions options = new VideoPlayerOptions();

/** Register this with the v2 embedding for the plugin to respond to lifecycle callbacks. */
public CachedVideoPlayerPlugin() {}
Expand Down Expand Up @@ -62,20 +65,7 @@ public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registra
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {

if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
try {
HttpsURLConnection.setDefaultSSLSocketFactory(new CustomSSLSocketFactory());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
Log.w(
TAG,
"Failed to enable TLSv1.1 and TLSv1.2 Protocols for API level 19 and below.\n"
+ "For more information about Socket Security, please consult the following link:\n"
+ "https://developer.android.com/reference/javax/net/ssl/SSLSocket",
e);
}
}

final FlutterInjector injector = FlutterInjector.instance();
final FlutterInjector injector = FlutterInjector.instance();
this.flutterState =
new FlutterState(
binding.getApplicationContext(),
Expand All @@ -87,7 +77,7 @@ public void onAttachedToEngine(FlutterPluginBinding binding) {
}

@Override
public void onDetachedFromEngine(FlutterPluginBinding binding) {
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
if (flutterState == null) {
Log.wtf(TAG, "Detached from the engine before registering to it.");
}
Expand Down Expand Up @@ -142,7 +132,6 @@ public TextureMessage create(CreateMessage arg) {
null,
options);
} else {
@SuppressWarnings("unchecked")
Map<String, String> httpHeaders = arg.getHttpHeaders();
player =
new CachedVideoPlayer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import javax.net.ssl.SSLSocketFactory;

public class CustomSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory sslSocketFactory;
private final SSLSocketFactory sslSocketFactory;

public CustomSSLSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
Expand Down
Loading