mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2024-11-10 12:47:26 +01:00
Support Streamable.
This commit is contained in:
parent
35cbd24318
commit
1abc703d7e
@ -167,6 +167,16 @@ class AppModule {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("streamable")
|
||||
@Singleton
|
||||
Retrofit provideStreamableRetrofit(@Named("default") OkHttpClient okHttpClient) {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(APIUtils.STREAMABLE_API_BASE_URI)
|
||||
.addConverterFactory(ScalarsConverterFactory.create())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("default")
|
||||
@Singleton
|
||||
|
@ -0,0 +1,57 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import ml.docilealligator.infinityforreddit.apis.StreamableAPI;
|
||||
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class FetchStreamableVideo {
|
||||
public interface FetchStreamableVideoListener {
|
||||
void success(StreamableVideo streamableVideo);
|
||||
void failed();
|
||||
}
|
||||
|
||||
public static void fetchStreamableVideo(Executor executor, Handler handler, Retrofit streamableRetrofit,
|
||||
String videoUrl, FetchStreamableVideoListener fetchStreamableVideoListener) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
Response<String> response = streamableRetrofit.create(StreamableAPI.class).getStreamableData(videoUrl).execute();
|
||||
if (response.isSuccessful()) {
|
||||
JSONObject jsonObject = new JSONObject(response.body());
|
||||
String title = jsonObject.getString(JSONUtils.TITLE_KEY);
|
||||
JSONObject filesObject = jsonObject.getJSONObject(JSONUtils.FILES_KEY);
|
||||
StreamableVideo.Media mp4 = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_KEY));
|
||||
StreamableVideo.Media mp4Mobile = parseMedia(filesObject.getJSONObject(JSONUtils.MP4_MOBILE_KEY));
|
||||
handler.post(() -> fetchStreamableVideoListener.success(new StreamableVideo(title, mp4, mp4Mobile)));
|
||||
} else {
|
||||
handler.post(fetchStreamableVideoListener::failed);
|
||||
}
|
||||
} catch (IOException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static StreamableVideo.Media parseMedia(JSONObject jsonObject) {
|
||||
try {
|
||||
return new StreamableVideo.Media(
|
||||
jsonObject.getString(JSONUtils.URL_KEY),
|
||||
jsonObject.getInt(JSONUtils.WIDTH_KEY),
|
||||
jsonObject.getInt(JSONUtils.HEIGHT_KEY));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class StreamableVideo {
|
||||
public String title;
|
||||
@Nullable
|
||||
public Media mp4;
|
||||
@Nullable
|
||||
public Media mp4Mobile;
|
||||
|
||||
public StreamableVideo(String title, @Nullable Media mp4, @Nullable Media mp4Mobile) {
|
||||
this.title = title;
|
||||
this.mp4 = mp4;
|
||||
this.mp4Mobile = mp4Mobile;
|
||||
}
|
||||
|
||||
public static class Media {
|
||||
public String url;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public Media(String url, int width, int height) {
|
||||
this.url = url;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
}
|
@ -51,6 +51,7 @@ public class LinkResolverActivity extends AppCompatActivity {
|
||||
private static final String RPAN_BROADCAST_PATTERN = "/rpan/r/[\\w-]+/\\w+/?\\w+/?";
|
||||
private static final String WIKI_PATTERN = "/[rR]/[\\w-]+/(wiki|w)?(?:/\\w+)+";
|
||||
private static final String GOOGLE_AMP_PATTERN = "/amp/s/amp.reddit.com/.*";
|
||||
private static final String STREAMABLE_PATTERN = "/\\w+/?";
|
||||
|
||||
@Inject
|
||||
@Named("default")
|
||||
@ -270,12 +271,22 @@ public class LinkResolverActivity extends AppCompatActivity {
|
||||
deepLinkError(uri);
|
||||
}
|
||||
} else if (authority.contains("google.com")) {
|
||||
if ( path.matches(GOOGLE_AMP_PATTERN) ) {
|
||||
String url = path.substring(11, path.length()); // skipping past amp straight to reddit
|
||||
if (path.matches(GOOGLE_AMP_PATTERN)) {
|
||||
String url = path.substring(11);
|
||||
handleUri(Uri.parse("https://" + url));
|
||||
} else {
|
||||
deepLinkError(uri);
|
||||
}
|
||||
} else if (authority.equals("streamable.com")) {
|
||||
if (path.matches(STREAMABLE_PATTERN)) {
|
||||
String shortCode = segments.get(0);
|
||||
Intent intent = new Intent(this, ViewVideoActivity.class);
|
||||
intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_STREAMABLE);
|
||||
intent.putExtra(ViewVideoActivity.EXTRA_STREAMABLE_SHORT_CODE, shortCode);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
deepLinkError(uri);
|
||||
}
|
||||
} else {
|
||||
deepLinkError(uri);
|
||||
}
|
||||
|
@ -82,8 +82,10 @@ import app.futured.hauler.LockableNestedScrollView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks;
|
||||
import ml.docilealligator.infinityforreddit.FetchStreamableVideo;
|
||||
import ml.docilealligator.infinityforreddit.Infinity;
|
||||
import ml.docilealligator.infinityforreddit.R;
|
||||
import ml.docilealligator.infinityforreddit.StreamableVideo;
|
||||
import ml.docilealligator.infinityforreddit.apis.VReddIt;
|
||||
import ml.docilealligator.infinityforreddit.bottomsheetfragments.PlaybackSpeedBottomSheetFragment;
|
||||
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
|
||||
@ -122,7 +124,9 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
public static final String EXTRA_VIDEO_TYPE = "EVT";
|
||||
public static final String EXTRA_GFYCAT_ID = "EGI";
|
||||
public static final String EXTRA_V_REDD_IT_URL = "EVRIU";
|
||||
public static final String EXTRA_STREAMABLE_SHORT_CODE = "ESSC";
|
||||
public static final String EXTRA_IS_NSFW = "EIN";
|
||||
public static final int VIDEO_TYPE_STREAMABLE = 5;
|
||||
public static final int VIDEO_TYPE_V_REDD_IT = 4;
|
||||
public static final int VIDEO_TYPE_DIRECT = 3;
|
||||
public static final int VIDEO_TYPE_REDGIFS = 2;
|
||||
@ -175,7 +179,6 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
private boolean wasPlaying;
|
||||
private boolean isDownloading = false;
|
||||
private boolean isMute = false;
|
||||
private String postTitle;
|
||||
private boolean isNSFW;
|
||||
private long resumePosition = -1;
|
||||
private int videoType;
|
||||
@ -183,6 +186,7 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
private boolean isHd;
|
||||
private Integer originalOrientation;
|
||||
private int playbackSpeed = 100;
|
||||
private boolean useBottomAppBar;
|
||||
|
||||
@Inject
|
||||
@Named("no_oauth")
|
||||
@ -200,6 +204,10 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
@Named("vReddIt")
|
||||
Retrofit vReddItRetrofit;
|
||||
|
||||
@Inject
|
||||
@Named("streamable")
|
||||
Retrofit streamableRetrofit;
|
||||
|
||||
@Inject
|
||||
@Named("default")
|
||||
SharedPreferences mSharedPreferences;
|
||||
@ -281,7 +289,7 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
boolean useBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false);
|
||||
useBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false);
|
||||
if (useBottomAppBar) {
|
||||
getSupportActionBar().hide();
|
||||
bottomAppBar.setVisibility(View.VISIBLE);
|
||||
@ -345,7 +353,6 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
});
|
||||
|
||||
Intent intent = getIntent();
|
||||
postTitle = intent.getStringExtra(EXTRA_POST_TITLE);
|
||||
isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false);
|
||||
if (savedInstanceState == null) {
|
||||
resumePosition = intent.getLongExtra(EXTRA_PROGRESS_SECONDS, -1);
|
||||
@ -377,18 +384,8 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (postTitle != null) {
|
||||
if (useBottomAppBar) {
|
||||
titleTextView.setText(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", postTitle)));
|
||||
} else {
|
||||
setTitle(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", postTitle)));
|
||||
}
|
||||
} else {
|
||||
if (!useBottomAppBar) {
|
||||
setTitle("");
|
||||
}
|
||||
}
|
||||
String postTitle = intent.getStringExtra(EXTRA_POST_TITLE);
|
||||
setSmallTitle(postTitle);
|
||||
|
||||
playerControlView.setVisibilityListener(visibility -> {
|
||||
switch (visibility) {
|
||||
@ -476,7 +473,25 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
}
|
||||
setPlaybackSpeed(Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_PLAYBACK_SPEED, "100")));
|
||||
|
||||
if (videoType == VIDEO_TYPE_V_REDD_IT) {
|
||||
if (videoType == VIDEO_TYPE_STREAMABLE) {
|
||||
if (savedInstanceState != null) {
|
||||
videoDownloadUrl = savedInstanceState.getString(VIDEO_DOWNLOAD_URL_STATE);
|
||||
} else {
|
||||
videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL);
|
||||
}
|
||||
|
||||
String shortCode = intent.getStringExtra(EXTRA_STREAMABLE_SHORT_CODE);
|
||||
videoFileName = "Streamable-" + shortCode + ".mp4";
|
||||
if (mVideoUri == null) {
|
||||
loadStreamableVideo(shortCode, savedInstanceState);
|
||||
} else {
|
||||
dataSourceFactory = new CacheDataSourceFactory(mSimpleCache,
|
||||
new DefaultDataSourceFactory(ViewVideoActivity.this,
|
||||
Util.getUserAgent(ViewVideoActivity.this, "Infinity")));
|
||||
player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri));
|
||||
preparePlayer(savedInstanceState);
|
||||
}
|
||||
} else if (videoType == VIDEO_TYPE_V_REDD_IT) {
|
||||
loadVReddItVideo(savedInstanceState);
|
||||
} else if (videoType == VIDEO_TYPE_GFYCAT || videoType == VIDEO_TYPE_REDGIFS) {
|
||||
if (savedInstanceState != null) {
|
||||
@ -531,6 +546,20 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void setSmallTitle(String title) {
|
||||
if (title != null) {
|
||||
if (useBottomAppBar) {
|
||||
titleTextView.setText(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title)));
|
||||
} else {
|
||||
setTitle(Html.fromHtml(String.format("<font color=\"#FFFFFF\"><small>%s</small></font>", title)));
|
||||
}
|
||||
} else {
|
||||
if (!useBottomAppBar) {
|
||||
setTitle("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void preparePlayer(Bundle savedInstanceState) {
|
||||
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.LOOP_VIDEO, true)) {
|
||||
player.setRepeatMode(Player.REPEAT_MODE_ALL);
|
||||
@ -688,7 +717,7 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
}
|
||||
loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false);
|
||||
} else {
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
if (post.getVideoUrl() != null) {
|
||||
mVideoUri = Uri.parse(post.getVideoUrl());
|
||||
subredditName = post.getSubredditName();
|
||||
@ -727,6 +756,34 @@ public class ViewVideoActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void loadStreamableVideo(String shortCode, Bundle savedInstanceState) {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
FetchStreamableVideo.fetchStreamableVideo(mExecutor, new Handler(), streamableRetrofit, shortCode,
|
||||
new FetchStreamableVideo.FetchStreamableVideoListener() {
|
||||
@Override
|
||||
public void success(StreamableVideo streamableVideo) {
|
||||
if (streamableVideo.mp4 == null && streamableVideo.mp4Mobile == null) {
|
||||
Toast.makeText(ViewVideoActivity.this, R.string.fetch_streamable_video_failed, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
setSmallTitle(streamableVideo.title);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
videoDownloadUrl = streamableVideo.mp4 == null ? streamableVideo.mp4Mobile.url : streamableVideo.mp4.url;
|
||||
mVideoUri = Uri.parse(videoDownloadUrl);
|
||||
dataSourceFactory = new CacheDataSourceFactory(mSimpleCache,
|
||||
new DefaultDataSourceFactory(ViewVideoActivity.this,
|
||||
Util.getUserAgent(ViewVideoActivity.this, "Infinity")));
|
||||
preparePlayer(savedInstanceState);
|
||||
player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed() {
|
||||
Toast.makeText(ViewVideoActivity.this, R.string.fetch_streamable_video_failed, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.view_video_activity, menu);
|
||||
|
@ -0,0 +1,10 @@
|
||||
package ml.docilealligator.infinityforreddit.apis;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
public interface StreamableAPI {
|
||||
@GET("videos/{shortcode}")
|
||||
Call<String> getStreamableData(@Path("shortcode") String shortCode);
|
||||
}
|
@ -23,6 +23,7 @@ public class APIUtils {
|
||||
public static final String IMGUR_API_BASE_URI = "https://api.imgur.com/3/";
|
||||
public static final String PUSHSHIFT_API_BASE_URI = "https://api.pushshift.io/";
|
||||
public static final String STRAPI_BASE_URI = "https://strapi.reddit.com";
|
||||
public static final String STREAMABLE_API_BASE_URI = "https://api.streamable.com";
|
||||
|
||||
public static final String CLIENT_ID_KEY = "client_id";
|
||||
public static final String CLIENT_ID = "NOe2iKrPPzwscA";
|
||||
|
@ -173,4 +173,6 @@ public class JSONUtils {
|
||||
public static final String CONTENT_MD_KEY = "content_md";
|
||||
public static final String CAPTION_KEY = "caption";
|
||||
public static final String CAPTION_URL_KEY = "outbound_url";
|
||||
public static final String FILES_KEY = "files";
|
||||
public static final String MP4_MOBILE_KEY = "mp4-mobile";
|
||||
}
|
||||
|
@ -988,6 +988,7 @@
|
||||
<string name="fetch_gfycat_video_failed">Fetch Gfycat video failed</string>
|
||||
<string name="fetch_redgifs_video_failed">Fetch Redgifs video failed</string>
|
||||
<string name="fetching_video_info_please_wait">Fetching video info. Please wait.</string>
|
||||
<string name="fetch_streamable_video_failed">Fetch Streamable video failed</string>
|
||||
|
||||
<string name="error_fetching_imgur_media">Cannot load images</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user