Skip to content

Commit

Permalink
pass local subs files to external player not using http proxy
Browse files Browse the repository at this point in the history
add correct subtitles languages as names subs.name extra in the intent

nova-video-player/aos-AVP#1177
  • Loading branch information
courville committed May 8, 2024
1 parent 44924dd commit 33128ef
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 20 deletions.
1 change: 1 addition & 0 deletions res/xml/provider_paths.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
<external-path name="external_files" path="." />
<root-path name="storage_files" path="/storage/" />
<root-path name="mount_files" path="/mnt/" />
<external-cache-path name="subtitles" path="subtitles/" />
</paths>
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

package com.archos.mediacenter.video.browser.subtitlesmanager;

import static com.archos.filecorelibrary.FileUtils.getName;
import static com.archos.filecorelibrary.FileUtils.stripExtensionFromName;
import static com.archos.mediacenter.utils.ISO639codes.getLanguageNameForLetterCode;
import static com.archos.mediacenter.video.browser.subtitlesmanager.ISO639codes.getLanguageNameForLetterCode;
import static com.archos.mediacenter.utils.ISO639codes.isletterCode;

import android.content.Context;
Expand Down Expand Up @@ -135,11 +137,18 @@ public SubtitleManager(Context context, Listener listener){

private static List<String> prefetchedListOfSubs;

private static List<String> listOfLocalSubs;

public static List<String> getPreFetchedListOfSubs() {
log.debug("getPreFetchedListOfSubs: " + Arrays.toString(prefetchedListOfSubs.toArray()));
return prefetchedListOfSubs;
}

public static List<String> getListOfLocalSubs() {
log.debug("getListOfLocalSubs: " + Arrays.toString(listOfLocalSubs.toArray()));
return listOfLocalSubs;
}

public void preFetchHTTPSubtitlesAndPrepareUpnpSubs(final Uri upnpNiceUri, final Uri fileUri){
log.debug("preFetchHTTPSubtitlesAndPrepareUpnpSubs on " + upnpNiceUri + ", " + fileUri);
new Thread() {
Expand Down Expand Up @@ -235,6 +244,7 @@ public void run() {
}
}
else if(!"upnp".equals(fileUri.getScheme())&&UriUtils.isImplementedByFileCore(fileUri)&&!FileUtils.isLocal(fileUri)){
log.debug("preFetchHTTPSubtitlesAndPrepareUpnpSubs: fileUri is not local, trying to fetch subtitles from " + fileUri);
privatePrefetchSub(fileUri);
}

Expand Down Expand Up @@ -320,7 +330,7 @@ public void run() {
}

private static String stripExtension(Uri video){
final String videoFileName = FileUtils.getName(video);
final String videoFileName = getName(video);
final String videoExtension = MimeUtils.getExtension(videoFileName);
String filenameWithoutExtension ;
if (videoExtension!=null) { // may happen in UPnP
Expand Down Expand Up @@ -484,12 +494,14 @@ public List<SubtitleFile> listLocalAndRemotesSubtitles(Uri video, boolean addAll
}
// Remove duplicates due to the fact that the remote subtitles may have already been downloaded to the tmp folder
List<SubtitleFile> subListUnique = new LinkedList<SubtitleFile>();
listOfLocalSubs = new LinkedList<String>();
for (SubtitleFile f : subList) {
// this test checks if the file is already in the list via fileSize and fleName (it captures Subs/en.srt then it is renamed in privatePrefetchSub to videoName.en.srt)
// refer to equal() method for this
if (!subListUnique.contains(f)) {
log.debug("listLocalAndRemotesSubtitles: adding only unique " + f.mFile.getUri().toString() + " (" + f.mName +")");
subListUnique.add(f);
if (FileUtils.isLocal(f.mFile.getUri())) listOfLocalSubs.add(f.mFile.getUri().getPath());
} else {
log.debug("listLocalAndRemotesSubtitles: skipping duplicate " + f.mFile.getUri().toString() + " (" + f.mName +")");
}
Expand All @@ -501,7 +513,7 @@ public List<SubtitleFile> listLocalAndRemotesSubtitles(Uri video, boolean addAll
public static String getLanguage3(String basename) {
// extract the 2 or 3 letters language code in a string located at after the start of the string or character "_" or "." or "]" till the end of the string or till a closing ".HI"
// for some reason, some yts subtitles have a .HI at the end of the filename, and apparently this is not for Hindi but Hearing Impaired, note that they are preceded by SDH for Deaf and hard of Hearing
Pattern pattern = Pattern.compile("(?:[_\\-.\\]]|^)([a-zA-Z]{2,3})(\\.HI|$)");
Pattern pattern = Pattern.compile("(?:[_\\-.\\]]|^)([a-zA-Z]{2,3})(" + SEP + "(HI|SDH)|$)");
Matcher matcher = pattern.matcher(basename);
if (matcher.find()) {
return matcher.group(1);
Expand All @@ -510,6 +522,41 @@ public static String getLanguage3(String basename) {
}
}

private static final String SEP = "(^|[\\p{Punct}\\s]++|$)";

public static boolean isHearingImpaired(String input) {
if (input == null) return false;
// HI and SDH case sensitive for hearing impaired
String regex = ".*" + SEP + "(HI|SDH)" + SEP + ".*";
log.debug("isHearingImpaired: " + input + " -> " + input.matches(regex));
return input.matches(regex);
}

public static String getSubLanguageFromSubPath(Context context, String path) {
String subFilenameWithoutExtension = stripExtensionFromName(getName(path));
if (subFilenameWithoutExtension == null) return path;
// get 2 or 3 letter code for language
getLanguage3(subFilenameWithoutExtension);
String lang = switch (subFilenameWithoutExtension.toLowerCase()) {
case "simplified.chi" -> "s_chinese_simplified";
case "traditional.chi" -> "s_traditional_chinese";
case "brazilian.por" -> "s_brazilian";
case "latin american.spa" -> "s_spanish_la";
case "english" -> "eng";
default -> getLanguage3(subFilenameWithoutExtension);
};
// treat yts Simplified.chi.srt Traditional.chi.srt Latin American.spa.srt English.srt Brazilian.por.srt and reuse s_ special strings for this
String subLanguageName = null;
if (lang != null) {
// treat yts SDH and HI as hearing impaired e.g. SDH.eng.HI.srt
if (isHearingImpaired(subFilenameWithoutExtension))
subLanguageName = getLanguageNameForLetterCode(context, lang) + " (HI)";
else subLanguageName = getLanguageNameForLetterCode(context, lang);
} else subLanguageName = subFilenameWithoutExtension;
log.debug("getSubLanguageFromSubPath: " + path + " -> " + subLanguageName);
return subLanguageName;
}

public static boolean isSubtitleHearingImpaired(String basename) {
// extract the 2 or 3 letters language code in a string located at after the start of the string or character "_" or "." or "]" till the end of the string or till a closing ".HI"
// for some reason, some yts subtitles have a .HI at the end of the filename, and apparently this is not for Hindi but Hearing Impaired, note that they are preceded by SDH for Deaf and hard of Hearing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
", mPlayerUri " + mPlayerUri
);
// Some external video player api specs:
// vlc https://wiki.videolan.org/Android_Player_Intents/
// vlc https://wiki.videolan.org/Android_Player_Intents/ https://wiki.videolan.org/MediaControlAPI
// justplayer https://github.com/moneytoo/Player/issues/203
// mxplayer https://mx.j2inter.com/api
// mxplayer https://mx.j2inter.com/api https://sites.google.com/site/mxvpen/api
// mpv http://mpv-android.github.io/mpv-android/intent.html
// vimu https://www.vimu.tv/player-api
if (data != null) {
Expand Down
45 changes: 29 additions & 16 deletions src/main/java/com/archos/mediacenter/video/utils/PlayUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
* Created by vapillon on 15/04/15.
Expand Down Expand Up @@ -190,7 +191,14 @@ private void startPlayer(Context context,

public void requestVideoDb() {
log.debug("requestVideoDb: list subtitles");
listOfSubtitles = SubtitleManager.getPreFetchedListOfSubs();
if (FileUtils.isLocal(mVideo.getUri())) {
// provide local list of subs
listOfSubtitles = SubtitleManager.getListOfLocalSubs();
} else {
// provide prefetched list of subs for remote shares
listOfSubtitles = SubtitleManager.getPreFetchedListOfSubs();
}
log.debug("requestVideoDb: listOfSubtitles " + Arrays.toString(listOfSubtitles.toArray()));
if(mIndexHelper==null)
mIndexHelper = new IndexHelper(mContext, null, 0);
mIndexHelper.requestVideoDb(mVideo.getUri(), -1,null, this, false, true);
Expand Down Expand Up @@ -234,7 +242,6 @@ public void onNoSubtitlesFound(Uri uri) {
public void onVideoDb(VideoDbInfo info, VideoDbInfo remoteInfo) {
int resumePos = -1;
if(info!=null||remoteInfo!=null) {

if (mResume != PlayerService.RESUME_NO) {
if(remoteInfo!=null&&info==null)
resumePos = remoteInfo.resume;
Expand Down Expand Up @@ -306,8 +313,12 @@ private void onResumeReady(Context context, Video video, final String mimeType,
// for mxplayer/justplayer http://mx.j2inter.com/api subs android.net.Uri[], subs.name String[], subs.filename String[]
Boolean subFound = false;
String subPath;
File subFile;
String subLanguage;
int n = 0;
List<Uri> MxSubPaths = new ArrayList<>();
List<String> MxSubNameList = new ArrayList<>();
List<String> MxSubFileList = new ArrayList<>();
Uri subUri;
if (listOfSubtitles != null) {
log.debug("onResumeReady: listOfSubtitles " + Arrays.toString(listOfSubtitles.toArray()));
Expand All @@ -319,24 +330,26 @@ private void onResumeReady(Context context, Video video, final String mimeType,
// find first external subtitle file and pass it to vlc
while (n < listOfSubtitles.size()) {
subPath = listOfSubtitles.get(n);
subUri = Uri.parse(subPath); // these files are in local nova cache not accessible from 3rd party players
try {
StreamOverHttp stream = new StreamOverHttp(subUri, mimeType);
dataUri = stream.getUri(subUri.getLastPathSegment());
// vlc
if (!subFound) intent.putExtra("subtitles_location", dataUri);
subFound = true;
// mxplayer/justplayer
MxSubPaths.add(dataUri);
log.debug("onResumeReady: adding external subtitle " + dataUri);
} catch (IOException e) {
log.error("onResumeReady: failed to start " + subUri + e);
}
subFile = new File(subPath);
subUri = FileProvider.getUriForFile(context, "org.courville.nova.provider", subFile);
subLanguage = SubtitleManager.getSubLanguageFromSubPath(context, subPath);
MxSubPaths.add(subUri);
MxSubNameList.add(subLanguage);
MxSubFileList.add(subPath);
log.debug("onResumeReady: subPath " + subPath + " -> subUri " + subUri + "-> subLanguage " + subLanguage);
n++;
}
Parcelable[] MxSubPathsParcelableArray = MxSubPaths.toArray(new Parcelable[0]);
log.trace("onResumeReady: subs passed to 3rd party player " + Arrays.toString(MxSubPathsParcelableArray));
if (! MxSubPaths.isEmpty()) intent.putExtra("subs", MxSubPathsParcelableArray);
if (! MxSubPaths.isEmpty()) {
intent.putExtra("subs", MxSubPathsParcelableArray);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("subs.name", MxSubNameList.toArray(new String[0]));
intent.putExtra("subs.file", MxSubFileList.toArray(new String[0]));
}
} else {
log.debug("onResumeReady: no sub files to inspect");

}
}
//this differs from the file uri for upnp
Expand Down

0 comments on commit 33128ef

Please sign in to comment.