Support imgur gifv with audio (#602)

Support imgur gifv videos with audio.
This commit is contained in:
scria1000 2021-12-20 13:18:40 +00:00 committed by GitHub
parent 34127032de
commit a7b58cf0a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 19 deletions

View File

@ -261,6 +261,8 @@ public class LinkResolverActivity extends AppCompatActivity {
startActivity(intent); startActivity(intent);
} else if (path.endsWith("gifv")) { } else if (path.endsWith("gifv")) {
String url = uri.toString(); String url = uri.toString();
// Insecure imgur links won't load
url = url.replaceFirst("http://" , "https://");
url = url.substring(0, url.length() - 5) + ".mp4"; url = url.substring(0, url.length() - 5) + ".mp4";
Intent intent = new Intent(this, ViewVideoActivity.class); Intent intent = new Intent(this, ViewVideoActivity.class);
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT);

View File

@ -126,6 +126,7 @@ public class ViewVideoActivity extends AppCompatActivity {
public static final String EXTRA_V_REDD_IT_URL = "EVRIU"; public static final String EXTRA_V_REDD_IT_URL = "EVRIU";
public static final String EXTRA_STREAMABLE_SHORT_CODE = "ESSC"; public static final String EXTRA_STREAMABLE_SHORT_CODE = "ESSC";
public static final String EXTRA_IS_NSFW = "EIN"; public static final String EXTRA_IS_NSFW = "EIN";
public static final int VIDEO_TYPE_IMGUR = 7;
public static final int VIDEO_TYPE_STREAMABLE = 5; public static final int VIDEO_TYPE_STREAMABLE = 5;
public static final int VIDEO_TYPE_V_REDD_IT = 4; public static final int VIDEO_TYPE_V_REDD_IT = 4;
public static final int VIDEO_TYPE_DIRECT = 3; public static final int VIDEO_TYPE_DIRECT = 3;
@ -523,9 +524,13 @@ public class ViewVideoActivity extends AppCompatActivity {
player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri));
preparePlayer(savedInstanceState); preparePlayer(savedInstanceState);
} }
} else if (videoType == VIDEO_TYPE_DIRECT) { } else if (videoType == VIDEO_TYPE_DIRECT || videoType == VIDEO_TYPE_IMGUR) {
videoDownloadUrl = mVideoUri.toString(); videoDownloadUrl = mVideoUri.toString();
videoFileName = FilenameUtils.getName(videoDownloadUrl); if (videoType == VIDEO_TYPE_DIRECT) {
videoFileName = FilenameUtils.getName(videoDownloadUrl);
} else {
videoFileName = "imgur-" + FilenameUtils.getName(videoDownloadUrl);
}
// Produces DataSource instances through which media data is loaded. // Produces DataSource instances through which media data is loaded.
dataSourceFactory = new CacheDataSourceFactory(mSimpleCache, dataSourceFactory = new CacheDataSourceFactory(mSimpleCache,
new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity"))); new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")));

View File

@ -1657,7 +1657,10 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
if (canStartActivity) { if (canStartActivity) {
canStartActivity = false; canStartActivity = false;
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (mPost.isGfycat()) { if (mPost.isImgur()) {
intent.setData(Uri.parse(mPost.getVideoUrl()));
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR);
} else if (mPost.isGfycat()) {
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT);
intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId());
if (mPost.isLoadGfycatOrStreamableVideoSuccess()) { if (mPost.isLoadGfycatOrStreamableVideoSuccess()) {
@ -1882,7 +1885,10 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
canStartActivity = false; canStartActivity = false;
if (mPost.getPostType() == Post.VIDEO_TYPE) { if (mPost.getPostType() == Post.VIDEO_TYPE) {
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (mPost.isGfycat()) { if (mPost.isImgur()) {
intent.setData(Uri.parse(mPost.getVideoUrl()));
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR);
} else if (mPost.isGfycat()) {
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT);
intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId());
} else if (mPost.isRedgifs()) { } else if (mPost.isRedgifs()) {

View File

@ -1943,7 +1943,10 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
canStartActivity = false; canStartActivity = false;
if (post.getPostType() == Post.VIDEO_TYPE) { if (post.getPostType() == Post.VIDEO_TYPE) {
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (post.isGfycat()) { if (post.isImgur()) {
intent.setData(Uri.parse(post.getVideoUrl()));
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR);
} else if (post.isGfycat()) {
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT);
intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId());
} else if (post.isRedgifs()) { } else if (post.isRedgifs()) {
@ -2683,7 +2686,10 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
if (post != null) { if (post != null) {
markPostRead(post, true); markPostRead(post, true);
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (post.isGfycat()) { if (post.isImgur()) {
intent.setData(Uri.parse(post.getVideoUrl()));
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR);
} else if (post.isGfycat()) {
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT);
intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId());
if (post.isLoadGfycatOrStreamableVideoSuccess()) { if (post.isLoadGfycatOrStreamableVideoSuccess()) {
@ -3968,7 +3974,10 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
if (post != null) { if (post != null) {
markPostRead(post, true); markPostRead(post, true);
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (post.isGfycat()) { if (post.isImgur()) {
intent.setData(Uri.parse(post.getVideoUrl()));
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_IMGUR);
} else if (post.isGfycat()) {
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT);
intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId());
if (post.isLoadGfycatOrStreamableVideoSuccess()) { if (post.isLoadGfycatOrStreamableVideoSuccess()) {

View File

@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -400,20 +401,38 @@ public class ParsePost {
post.setVideoDownloadUrl(videoDownloadUrl); post.setVideoDownloadUrl(videoDownloadUrl);
} else if (data.has(JSONUtils.PREVIEW_KEY)) { } else if (data.has(JSONUtils.PREVIEW_KEY)) {
if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) { if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) {
//Gif video post (HLS)
int postType = Post.VIDEO_TYPE; int postType = Post.VIDEO_TYPE;
String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY) Uri uri = Uri.parse(url);
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString(); String authority = uri.getAuthority();
String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) // The hls stream inside REDDIT_VIDEO_PREVIEW_KEY can sometimes lack an audio track
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY); // This happens with imgur gifv that are actually mp4, even the official Reddit app has this bug
if (authority.contains("imgur.com") && url.endsWith(".gifv")) {
url = url.substring(0, url.length() - 5) + ".mp4";
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair, post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, nComments, upvoteRatio, flair, awards, nAwards, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost); archived, locked, saved, isCrosspost);
post.setPreviews(previews); post.setPreviews(previews);
post.setVideoUrl(videoUrl); post.setVideoUrl(url);
post.setVideoDownloadUrl(videoDownloadUrl); post.setVideoDownloadUrl(url);
post.setIsImgur(true);
} else {
//Gif video post (HLS)
String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, awards, nAwards, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost);
post.setPreviews(previews);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
}
} else { } else {
if (url.endsWith("jpg") || url.endsWith("png")) { if (url.endsWith("jpg") || url.endsWith("png")) {
//Image post //Image post
@ -449,6 +468,22 @@ public class ParsePost {
post.setPreviews(previews); post.setPreviews(previews);
post.setVideoUrl(url); post.setVideoUrl(url);
post.setVideoDownloadUrl(url); post.setVideoDownloadUrl(url);
} else if (url.endsWith("gifv") && Objects.equals(Uri.parse(url).getAuthority(), "i.imgur.com")) {
// Imgur gifv/mp4
int postType = Post.VIDEO_TYPE;
// Insecure imgur links won't load
url = url.replaceFirst("http://" , "https://");
url = url.substring(0, url.length() - 5) + ".mp4";
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, awards, nAwards,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost);
post.setPreviews(previews);
post.setVideoUrl(url);
post.setVideoDownloadUrl(url);
post.setIsImgur(true);
} else { } else {
if (url.contains(permalink)) { if (url.contains(permalink)) {
//Text post but with a preview //Text post but with a preview

View File

@ -52,6 +52,7 @@ public class Post implements Parcelable {
private String videoDownloadUrl; private String videoDownloadUrl;
private String gfycatId; private String gfycatId;
private String streamableShortCode; private String streamableShortCode;
private boolean isImgur;
private boolean isGfycat; private boolean isGfycat;
private boolean isRedgifs; private boolean isRedgifs;
private boolean isStreamable; private boolean isStreamable;
@ -175,6 +176,7 @@ public class Post implements Parcelable {
videoDownloadUrl = in.readString(); videoDownloadUrl = in.readString();
gfycatId = in.readString(); gfycatId = in.readString();
streamableShortCode = in.readString(); streamableShortCode = in.readString();
isImgur = in.readByte() != 0;
isGfycat = in.readByte() != 0; isGfycat = in.readByte() != 0;
isRedgifs = in.readByte() != 0; isRedgifs = in.readByte() != 0;
isStreamable = in.readByte() != 0; isStreamable = in.readByte() != 0;
@ -333,6 +335,14 @@ public class Post implements Parcelable {
this.streamableShortCode = shortCode; this.streamableShortCode = shortCode;
} }
public void setIsImgur(boolean isImgur) {
this.isImgur = isImgur;
}
public boolean isImgur() {
return isImgur;
}
public boolean isGfycat() { public boolean isGfycat() {
return isGfycat; return isGfycat;
} }
@ -553,6 +563,7 @@ public class Post implements Parcelable {
parcel.writeString(videoDownloadUrl); parcel.writeString(videoDownloadUrl);
parcel.writeString(gfycatId); parcel.writeString(gfycatId);
parcel.writeString(streamableShortCode); parcel.writeString(streamableShortCode);
parcel.writeByte((byte) (isImgur ? 1 : 0));
parcel.writeByte((byte) (isGfycat ? 1 : 0)); parcel.writeByte((byte) (isGfycat ? 1 : 0));
parcel.writeByte((byte) (isRedgifs ? 1 : 0)); parcel.writeByte((byte) (isRedgifs ? 1 : 0));
parcel.writeByte((byte) (isStreamable ? 1 : 0)); parcel.writeByte((byte) (isStreamable ? 1 : 0));