diff --git a/app/src/fdroid_full/play/release-notes/en-US/default.txt b/app/src/fdroid_full/play/release-notes/en-US/default.txt index 0a9a515..07ba809 100644 --- a/app/src/fdroid_full/play/release-notes/en-US/default.txt +++ b/app/src/fdroid_full/play/release-notes/en-US/default.txt @@ -2,9 +2,11 @@ Added: - playback speed - video attributes (clickable tags) - update channel photo +- higher definition for video preview Changed: - Improve player +- Auto-play next video accessible in player Fixed: - video upload error diff --git a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java index 919c531..c3af373 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java +++ b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java @@ -192,6 +192,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd private int initialOrientation; private String currentResolution; private String currentCaption; + private boolean isRemote; public static void hideKeyboard(Activity activity) { if (activity != null && activity.getWindow() != null) { @@ -254,7 +255,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd Account account = new AccountDAO(PeertubeActivity.this, db).getAccountByToken(token); Helper.loadGiF(PeertubeActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, binding.myPp); } - + isRemote = false; TorrentOptions torrentOptions = new TorrentOptions.Builder() .saveLocation(getCacheDir()) .autoDownload(true) @@ -507,6 +508,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd super.onNewIntent(intent); Bundle b = intent.getExtras(); if (b != null) { + isRemote = false; peertubeInstance = b.getString("peertube_instance", Helper.getLiveInstance(PeertubeActivity.this)); videoUuid = b.getString("video_uuid", null); setRequestedOrientation(initialOrientation); @@ -595,7 +597,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd binding.peertubePlaylist.setVisibility(View.VISIBLE); binding.peertubeBookmark.setVisibility(View.GONE); TimelineVM feedsViewModel = new ViewModelProvider(PeertubeActivity.this).get(TimelineVM.class); - feedsViewModel.getVideo(sepiaSearch ? peertubeInstance : null, videoUuid, isMyVideo).observe(PeertubeActivity.this, this::manageVIewVideo); + if (!isRemote) { + feedsViewModel.getVideo(sepiaSearch ? peertubeInstance : null, videoUuid, isMyVideo).observe(PeertubeActivity.this, this::manageVIewVideo); + } CaptionsVM captionsViewModel = new ViewModelProvider(PeertubeActivity.this).get(CaptionsVM.class); captionsViewModel.getCaptions(sepiaSearch ? peertubeInstance : null, videoUuid).observe(PeertubeActivity.this, this::manageCaptions); new Thread(() -> { @@ -723,6 +727,50 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd @SuppressLint("ClickableViewAccessibility") public void manageVIewVideo(APIResponse apiResponse) { + if (!isRemote && apiResponse != null && apiResponse.getPeertubes().get(0).getErrorCode() == 1 && apiResponse.getPeertubes().get(0).getOriginUrl() != null) { + String url = apiResponse.getPeertubes().get(0).getOriginUrl(); + Pattern link = Pattern.compile("(https?://[\\da-z.-]+\\.[a-z.]{2,10})/videos/watch/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})(\\?start=(\\d+[hH])?(\\d+[mM])?(\\d+[sS])?)?$"); + Matcher matcherLink = link.matcher(url); + if (matcherLink.find()) { + String instance = matcherLink.group(1); + String uuid = matcherLink.group(2); + String hour = matcherLink.group(4); + String min = matcherLink.group(5); + String sec = matcherLink.group(6); + int hourInt, minInt, secInt; + int totalSeconds = 0; + if (hour != null) { + hourInt = Integer.parseInt(hour.replace("h", "")); + totalSeconds += 3600 * hourInt; + } + if (min != null) { + minInt = Integer.parseInt(min.replace("m", "")); + totalSeconds += 60 * minInt; + } + if (sec != null) { + secInt = Integer.parseInt(sec.replace("s", "")); + totalSeconds += secInt; + } + + if (instance != null && uuid != null) { + peertubeInstance = instance.replace("https://", "").replace("http://", ""); + sepiaSearch = true; // Sepia search flag is used because, at this time we don't know if the video is federated. + videoUuid = uuid; + peertube = new VideoData.Video(); + peertube.setUuid(uuid); + peertube.setEmbedUrl(url); + isRemote = true; + if (totalSeconds > 0) { + VideoData.UserHistory userHistory = new VideoData.UserHistory(); + userHistory.setCurrentTime(totalSeconds * 1000); + peertube.setUserHistory(userHistory); + } + TimelineVM viewModelTimeline = new ViewModelProvider(PeertubeActivity.this).get(TimelineVM.class); + viewModelTimeline.getVideo(peertubeInstance, peertube.getUuid(), false).observe(PeertubeActivity.this, this::manageVIewVideo); + } + } + return; + } if (apiResponse == null || (apiResponse.getError() != null) || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0) { Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); binding.loader.setVisibility(View.GONE); @@ -793,7 +841,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd SpannableString spannableString = new SpannableString(sb.toString()); for (String tag : tags) { String target = "#" + tag; - if (spannableString != null && spannableString.toString().contains(target)) { + if (spannableString.toString().contains(target)) { for (int startPosition = -1; (startPosition = spannableString.toString().indexOf(target, startPosition + 1)) != -1; startPosition++) { final int endPosition = startPosition + target.length(); if (endPosition <= spannableString.toString().length() && endPosition >= startPosition) { diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java b/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java index 0872325..274a0d7 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java +++ b/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java @@ -27,6 +27,8 @@ import android.webkit.MimeTypeMap; import androidx.documentfile.provider.DocumentFile; import org.jetbrains.annotations.NotNull; +import org.json.JSONException; +import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.File; @@ -1673,19 +1675,37 @@ public class RetrofitPeertubeAPI { APIResponse apiResponse = new APIResponse(); try { Response response = video.execute(); - if (response.isSuccessful()) { List videos = new ArrayList<>(); videos.add(response.body()); apiResponse.setPeertubes(videos); } else { - Error error = new Error(); - error.setStatusCode(response.code()); + if (response.errorBody() != null) { - error.setError(response.errorBody().string()); + String error = response.errorBody().string(); + if (error.contains("originUrl")) { + try { + JSONObject jsonObject = new JSONObject(error); + List videos = new ArrayList<>(); + VideoData.Video videoRedirect = new VideoData.Video(); + videoRedirect.setErrorCode(jsonObject.getInt("errorCode")); + videoRedirect.setOriginUrl(jsonObject.getString("originUrl")); + videos.add(videoRedirect); + apiResponse.setPeertubes(videos); + } catch (JSONException e) { + e.printStackTrace(); + } + } } else { - error.setError(_context.getString(R.string.toast_error)); + Error error = new Error(); + error.setStatusCode(response.code()); + if (response.errorBody() != null) { + error.setError(response.errorBody().string()); + } else { + error.setError(_context.getString(R.string.toast_error)); + } } + } } catch (IOException e) { Error error = new Error(); diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/data/VideoData.java b/app/src/main/java/app/fedilab/fedilabtube/client/data/VideoData.java index 2a8676e..7f95808 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/client/data/VideoData.java +++ b/app/src/main/java/app/fedilab/fedilabtube/client/data/VideoData.java @@ -43,6 +43,7 @@ public class VideoData { @SerializedName("data") public List