Skip to content

Commit

Permalink
Replace ICU4J with chardet4j
Browse files Browse the repository at this point in the history
  • Loading branch information
moneytoo committed Dec 20, 2024
1 parent e886313 commit 171a2a8
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 87 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Just pause and resume playback once again.

### Why is the APK so big?

The APK available here contains native libraries for all supported architectures (`armeabi-v7a`/`armeabi-v7a-neon`/`arm64-v8a`/`x86`/`x86_64`), which is what takes the most space. Although Just Player relies mostly on device decoders, it packs _FFmpeg_ for some advanced features (video chapters and frame rate detection). The second largest dependency is [ICU4J](https://github.com/moneytoo/Player/issues/76) - 10 MB only for charset detection of subtitle files. 🤷
The APK available here contains native libraries for all supported architectures (`armeabi-v7a`/`armeabi-v7a-neon`/`arm64-v8a`/`x86`/`x86_64`), which is what takes the most space. Although Just Player relies mostly on device decoders, it packs _FFmpeg_ for some advanced features (video chapters and frame rate detection).

Please note that installs and updates made through Google Play are significantly smaller thanks to Android App Bundles and delta updates.

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ android {
applicationId "com.brouken.player"
minSdkVersion 21
targetSdkVersion 34
versionCode 181
versionCode 182
versionName "0.${versionCode}"
archivesBaseName = "Just.Player.v${versionName}"
if (abiFilter) {
Expand Down Expand Up @@ -117,11 +117,11 @@ dependencies {
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
implementation "androidx.core:core:$androidxCoreVersion"
fullImplementation 'com.ibm.icu:icu4j:76.1'
fullImplementation 'com.arthenica:ffmpeg-kit-https:6.0-2.LTS'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.preference:preference:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.sigpwned:chardet4j:75.1.2'
implementation project(path: ':doubletapplayerview')
implementation project(path: ':android-file-chooser')
implementation fileTree(dir: "libs", include: ["lib-*.aar"])
Expand Down
70 changes: 0 additions & 70 deletions app/src/full/java/com/brouken/player/UtilsFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Build;

Expand All @@ -15,80 +14,11 @@
import com.arthenica.ffmpegkit.MediaInformation;
import com.arthenica.ffmpegkit.MediaInformationSession;
import com.arthenica.ffmpegkit.StreamInformation;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class UtilsFeature {

public static Uri convertToUTF(PlayerActivity activity, Uri subtitleUri) {
try {
String scheme = subtitleUri.getScheme();
if (scheme != null && scheme.toLowerCase().startsWith("http")) {
List<Uri> urls = new ArrayList<>();
urls.add(subtitleUri);
SubtitleFetcher subtitleFetcher = new SubtitleFetcher(activity, urls);
subtitleFetcher.start();
return null;
} else {
InputStream inputStream = activity.getContentResolver().openInputStream(subtitleUri);
return convertInputStreamToUTF(activity, subtitleUri, inputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
return subtitleUri;
}

public static Uri convertInputStreamToUTF(Context context, Uri subtitleUri, InputStream inputStream) {
try {
final CharsetDetector detector = new CharsetDetector();
final BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
detector.setText(bufferedInputStream);
final CharsetMatch charsetMatch = detector.detect();

if (!StandardCharsets.UTF_8.displayName().equals(charsetMatch.getName())) {
String filename = subtitleUri.getPath();
filename = filename.substring(filename.lastIndexOf("/") + 1);
final File file = new File(context.getCacheDir(), filename);
final BufferedReader bufferedReader = new BufferedReader(charsetMatch.getReader());
final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
char[] buffer = new char[512];
int num;
int pass = 0;
boolean success = true;
while ((num = bufferedReader.read(buffer)) != -1) {
bufferedWriter.write(buffer, 0, num);
pass++;
if (pass * 512 > 2_000_000) {
success = false;
break;
}
}
bufferedWriter.close();
bufferedReader.close();
if (success) {
subtitleUri = Uri.fromFile(file);
} else {
subtitleUri = null;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return subtitleUri;
}

private static MediaInformation getMediaInformation(final Activity activity, final Uri uri) {
String path;
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Expand Down
11 changes: 0 additions & 11 deletions app/src/lite/java/com/brouken/player/UtilsFeature.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
package com.brouken.player;

import android.content.Context;
import android.net.Uri;

import androidx.media3.ui.PlayerControlView;

import java.io.InputStream;

public class UtilsFeature {

public static Uri convertToUTF(PlayerActivity activity, Uri subtitleUri) {
return subtitleUri;
}

public static Uri convertInputStreamToUTF(Context context, Uri subtitleUri, InputStream inputStream) {
return subtitleUri;
}

public static boolean switchFrameRate(final PlayerActivity activity, final Uri uri, final boolean play) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/brouken/player/PlayerActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
private void handleSubtitles(Uri uri) {
// Convert subtitles to UTF-8 if necessary
SubtitleUtils.clearCache(this);
uri = UtilsFeature.convertToUTF(this, uri);
uri = Utils.convertToUTF(this, uri);
mPrefs.updateSubtitle(uri);
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/brouken/player/SubtitleFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public void onResponse(@NonNull Call call, @NonNull Response response) throws IO
}

InputStream inputStream = responseBody.byteStream();
Uri convertedSubtitleUri = UtilsFeature.convertInputStreamToUTF(activity, subtitleUri, inputStream);
Uri convertedSubtitleUri = Utils.convertInputStreamToUTF(activity, subtitleUri, inputStream);

if (convertedSubtitleUri == null) {
return;
Expand Down
65 changes: 64 additions & 1 deletion app/src/main/java/com/brouken/player/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,19 @@
import androidx.media3.common.MimeTypes;

import com.obsez.android.lib.filechooser.ChooserDialog;
import com.sigpwned.chardet4j.Chardet;
import com.sigpwned.chardet4j.io.DecodedInputStreamReader;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Expand Down Expand Up @@ -603,7 +611,7 @@ public void onChoosePath(String path, File pathFile) {
} else {
// Convert subtitles to UTF-8 if necessary
SubtitleUtils.clearCache(activity);
uri = UtilsFeature.convertToUTF(activity, uri);
uri = Utils.convertToUTF(activity, uri);

activity.mPrefs.updateSubtitle(uri);
}
Expand All @@ -625,6 +633,61 @@ public void onCancel(DialogInterface dialog) {
return true;
}

public static Uri convertToUTF(PlayerActivity activity, Uri subtitleUri) {
try {
String scheme = subtitleUri.getScheme();
if (scheme != null && scheme.toLowerCase().startsWith("http")) {
List<Uri> urls = new ArrayList<>();
urls.add(subtitleUri);
SubtitleFetcher subtitleFetcher = new SubtitleFetcher(activity, urls);
subtitleFetcher.start();
return null;
} else {
InputStream inputStream = activity.getContentResolver().openInputStream(subtitleUri);
return convertInputStreamToUTF(activity, subtitleUri, inputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
return subtitleUri;
}

public static Uri convertInputStreamToUTF(Context context, Uri subtitleUri, InputStream inputStream) {
try {
DecodedInputStreamReader decodedInputStreamReader = Chardet.decode(inputStream, StandardCharsets.UTF_8);
Charset charset = decodedInputStreamReader.charset();
if (!StandardCharsets.UTF_8.equals(charset)) {
String filename = subtitleUri.getPath();
filename = filename.substring(filename.lastIndexOf("/") + 1);
final File file = new File(context.getCacheDir(), filename);
final BufferedReader bufferedReader = new BufferedReader(decodedInputStreamReader);
final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
char[] buffer = new char[512];
int num;
int pass = 0;
boolean success = true;
while ((num = bufferedReader.read(buffer)) != -1) {
bufferedWriter.write(buffer, 0, num);
pass++;
if (pass * 512 > 2_000_000) {
success = false;
break;
}
}
bufferedWriter.close();
bufferedReader.close();
if (success) {
subtitleUri = Uri.fromFile(file);
} else {
subtitleUri = null;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return subtitleUri;
}

public static boolean isPiPSupported(Context context) {
PackageManager packageManager = context.getPackageManager();
if (BuildConfig.FLAVOR_distribution.equals("amazon") && packageManager.hasSystemFeature(FEATURE_FIRE_TV)) {
Expand Down

0 comments on commit 171a2a8

Please sign in to comment.