This commit is contained in:
Thomas 2020-10-29 18:56:57 +01:00
parent 65f3886355
commit f0335d96d2
4 changed files with 125 additions and 84 deletions

View File

@ -111,8 +111,8 @@ dependencies {
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'com.github.GrenderG:Toasty:1.4.2'
implementation 'com.google.android.exoplayer:exoplayer:2.10.6'
implementation 'com.google.android.exoplayer:extension-mediasession:2.10.6'
implementation 'com.google.android.exoplayer:exoplayer:2.12.1'
implementation 'com.google.android.exoplayer:extension-mediasession:2.12.1'
implementation "com.github.mabbas007:TagsEditText:1.0.5"
implementation "com.github.bumptech.glide:glide:4.11.0"
annotationProcessor "com.github.bumptech.glide:compiler:4.11.0"
@ -128,5 +128,6 @@ dependencies {
implementation "io.github.kobakei:ratethisapp:1.2.0"
implementation 'com.github.HITGIF:TextFieldBoxes:1.4.5'
implementation 'com.github.vkay94:DoubleTapPlayerView:1.0.0'
}

View File

@ -66,9 +66,10 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.github.vkay94.dtpv.youtube.YouTubeOverlay;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.source.MediaSource;
@ -238,6 +239,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
if (mode == Helper.VIDEO_MODE_WEBVIEW) {
binding.webviewVideo.setVisibility(View.VISIBLE);
binding.mediaVideo.setVisibility(View.GONE);
binding.doubleTapPlayerView.setVisibility(View.GONE);
CustomWebview webview_video = Helper.initializeWebview(PeertubeActivity.this, R.id.webview_video, null);
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(PeertubeActivity.this, webview_video, binding.mainMediaFrame, binding.videoLayout);
@ -271,15 +273,33 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
binding.webviewVideo.loadUrl("https://" + peertubeInstance + "/videos/embed/" + videoUuid);
} else {
binding.webviewVideo.setVisibility(View.GONE);
binding.mediaVideo.setVisibility(View.VISIBLE);
binding.loader.setVisibility(View.VISIBLE);
}
if (mode != Helper.VIDEO_MODE_WEBVIEW) {
binding.mediaVideo.setControllerShowTimeoutMs(1000);
binding.mediaVideo.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
binding.doubleTapPlayerView.setControllerShowTimeoutMs(1000);
binding.doubleTapPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
initFullscreenDialog();
initFullscreenButton();
binding.doubleTapPlayerView
.setDoubleTapDelay(500);
binding.doubleTapPlayerView.setDoubleTapEnabled(true);
binding.mediaVideo.performListener(new YouTubeOverlay.PerformListener() {
@Override
public void onAnimationStart() {
binding.mediaVideo.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd() {
binding.mediaVideo.setVisibility(View.GONE);
}
}) .playerView(binding.doubleTapPlayerView).seekSeconds(10);
binding.doubleTapPlayerView.setPlayer(player);
binding.doubleTapPlayerView.controller(binding.mediaVideo);
if( player != null)
binding.mediaVideo.player(player);
}
flag_loading = true;
comments = new ArrayList<>();
@ -417,15 +437,22 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
Pattern link = Pattern.compile("(https?://[\\da-z.-]+\\.[a-z.]{2,10})/videos/watch/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
Matcher matcherLink = link.matcher(url);
if (matcherLink.find()) {
peertubeInstance = matcherLink.group(1).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 = matcherLink.group(2);
peertube = new VideoData.Video();
peertube.setUuid(matcherLink.group(2));
peertube.setEmbedUrl(url);
urlIntent = intent;
SearchVM viewModelSearch = new ViewModelProvider(PeertubeActivity.this).get(SearchVM.class);
viewModelSearch.getVideos("0", peertube.getEmbedUrl()).observe(PeertubeActivity.this, this::manageVIewVideos);
String instance = matcherLink.group(1);
String uuid = matcherLink.group(2);
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);
urlIntent = intent;
SearchVM viewModelSearch = new ViewModelProvider(PeertubeActivity.this).get(SearchVM.class);
viewModelSearch.getVideos("0", peertube.getEmbedUrl()).observe(PeertubeActivity.this, this::manageVIewVideos);
}else {
Helper.forwardToAnotherApp(PeertubeActivity.this, intent);
finish();
}
}else{
Helper.forwardToAnotherApp(PeertubeActivity.this, intent);
finish();
@ -436,8 +463,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void playVideo() {
if (player != null) {
player.release();
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
binding.mediaVideo.setPlayer(player);
player = new SimpleExoPlayer.Builder(PeertubeActivity.this).build();
binding.mediaVideo.player(player);
binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE);
player.setPlayWhenReady(autoPlay);
captions = null;
@ -682,27 +710,31 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
ProgressiveMediaSource videoSource;
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
binding.mediaVideo.setPlayer(player);
player = new SimpleExoPlayer.Builder(PeertubeActivity.this).build();
binding.mediaVideo.player(player);
binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE);
if (apiResponse.getPeertubes().get(0).getFiles() != null && apiResponse.getPeertubes().get(0).getFiles().size() > 0) {
if (video_cache == 0) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this,
Util.getUserAgent(PeertubeActivity.this, null), null);
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this)));
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem);
} else {
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this)));
.createMediaSource(mediaItem);
}
player.prepare(videoSource);
player.setMediaSource(videoSource);
} else {
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(apiResponse.getPeertubes().get(0).getStreamingPlaylists().get(0).getPlaylistUrl())).build();
HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(new DefaultHttpDataSourceFactory(System.getProperty("http.agent")))
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getStreamingPlaylists().get(0).getPlaylistUrl()));
player.prepare(hlsMediaSource);
.createMediaSource(mediaItem);
player.setMediaSource(hlsMediaSource);
}
player.prepare();
player.setPlayWhenReady(autoPlay);
}
@ -805,41 +837,41 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
if (player != null)
player.release();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory());
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this, trackSelector);
TrackSelector trackSelector = new DefaultTrackSelector(PeertubeActivity.this, new AdaptiveTrackSelection.Factory());
player = new SimpleExoPlayer.Builder(PeertubeActivity.this).setTrackSelector(trackSelector).build();
binding.mediaVideo.player(player);
ProgressiveMediaSource videoSource;
MediaSource subtitleSource = null;
Format subtitleFormat = Format.createTextSampleFormat(
null,
MimeTypes.TEXT_VTT,
Format.NO_VALUE,
itemsKeyLanguage[which]);
if (apiResponse.getPeertubes().get(0).getFiles() != null && apiResponse.getPeertubes().get(0).getFiles().size() > 0) {
if (video_cache == 0) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this,
Util.getUserAgent(PeertubeActivity.this, null), null);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this)));
if (uri != null)
subtitleSource = new SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(uri, subtitleFormat, C.TIME_UNSET);
.createMediaSource(mediaItem);
if (uri != null) {
MediaItem.Subtitle mediaSubtitle = new MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, itemsKeyLanguage[which]);
subtitleSource = new SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(mediaSubtitle, C.TIME_UNSET);
}
} else {
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this)));
if (uri != null)
subtitleSource = new SingleSampleMediaSource.Factory(cacheDataSourceFactory).createMediaSource(uri, subtitleFormat, C.TIME_UNSET);
.createMediaSource(mediaItem);
if (uri != null) {
MediaItem.Subtitle mediaSubtitle = new MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, itemsKeyLanguage[which], Format.NO_VALUE);
subtitleSource = new SingleSampleMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaSubtitle, C.TIME_UNSET);
}
}
binding.mediaVideo.setPlayer(player);
binding.doubleTapPlayerView.setPlayer(player);
if (which > 0 && subtitleSource != null) {
MergingMediaSource mergedSource =
new MergingMediaSource(videoSource, subtitleSource);
player.prepare(mergedSource);
} else {
player.prepare(videoSource);
player.setMediaSource(mergedSource);
}
player.prepare();
player.seekTo(0, position);
player.setPlayWhenReady(true);
}
@ -964,9 +996,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
MediaSessionCompat mediaSession = new MediaSessionCompat(this, getPackageName());
MediaSessionConnector mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
PlayerControlView controlView = binding.doubleTapPlayerView.findViewById(R.id.exo_controller);
controlView.hide();
binding.mediaVideo.setControllerAutoShow(false);
binding.doubleTapPlayerView.setControllerAutoShow(false);
mediaSession.setActive(true);
PictureInPictureParams params = new PictureInPictureParams.Builder().build();
enterPictureInPictureMode(params);
@ -1033,34 +1065,36 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
builderSingle.setAdapter(arrayAdapter, (dialog, which) -> {
String res = Objects.requireNonNull(arrayAdapter.getItem(which)).substring(0, Objects.requireNonNull(arrayAdapter.getItem(which)).length() - 1);
if (binding.mediaVideo != null) {
binding.loader.setVisibility(View.VISIBLE);
long position = player.getCurrentPosition();
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
TextView resolution = controlView.findViewById(R.id.resolution);
resolution.setText(String.format("%sp", res));
if (mode == Helper.VIDEO_MODE_NORMAL) {
if (player != null)
player.release();
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
binding.mediaVideo.setPlayer(player);
binding.loader.setVisibility(View.GONE);
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
ProgressiveMediaSource videoSource;
if (video_cache == 0) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this,
Util.getUserAgent(PeertubeActivity.this, null), null);
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(peertube.getFileUrl(res, PeertubeActivity.this)));
} else {
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this);
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(Uri.parse(peertube.getFileUrl(res, PeertubeActivity.this)));
}
player.prepare(videoSource);
player.seekTo(0, position);
player.setPlayWhenReady(true);
binding.loader.setVisibility(View.VISIBLE);
long position = player.getCurrentPosition();
PlayerControlView controlView = binding.doubleTapPlayerView.findViewById(R.id.exo_controller);
TextView resolution = controlView.findViewById(R.id.resolution);
resolution.setText(String.format("%sp", res));
if (mode == Helper.VIDEO_MODE_NORMAL) {
if (player != null)
player.release();
player = new SimpleExoPlayer.Builder(PeertubeActivity.this).build();
binding.mediaVideo.player(player);
binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE);
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
ProgressiveMediaSource videoSource;
if (video_cache == 0) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this,
Util.getUserAgent(PeertubeActivity.this, null), null);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(peertube.getFileUrl(res, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem);
} else {
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(peertube.getFileUrl(res, PeertubeActivity.this))).build();
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(mediaItem);
}
player.setMediaSource(videoSource);
player.prepare();
player.seekTo(0, position);
player.setPlayWhenReady(true);
}
});
@ -1088,8 +1122,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void openFullscreenDialog() {
((ViewGroup) binding.mediaVideo.getParent()).removeView(binding.mediaVideo);
fullScreenDialog.addContentView(binding.mediaVideo, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
((ViewGroup) binding.doubleTapPlayerView.getParent()).removeView(binding.doubleTapPlayerView);
fullScreenDialog.addContentView(binding.doubleTapPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_exit_24));
fullScreenMode = true;
@ -1204,8 +1238,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void closeFullscreenDialog() {
((ViewGroup) binding.mediaVideo.getParent()).removeView(binding.mediaVideo);
((FrameLayout) findViewById(R.id.main_media_frame)).addView(binding.mediaVideo);
((ViewGroup) binding.doubleTapPlayerView.getParent()).removeView(binding.doubleTapPlayerView);
((FrameLayout) findViewById(R.id.main_media_frame)).addView(binding.doubleTapPlayerView);
fullScreenMode = false;
fullScreenDialog.dismiss();
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_24));
@ -1213,7 +1247,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void initFullscreenButton() {
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
PlayerControlView controlView = binding.doubleTapPlayerView.findViewById(R.id.exo_controller);
fullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
View fullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button);
fullScreenButton.setOnClickListener(v -> {
@ -1239,7 +1273,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
private void initResolution() {
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
PlayerControlView controlView = binding.doubleTapPlayerView.findViewById(R.id.exo_controller);
TextView resolution = controlView.findViewById(R.id.resolution);
if (peertube.getFiles() != null && peertube.getFiles().size() > 0) {
resolution.setText(String.format("%s", Helper.defaultFile(PeertubeActivity.this, peertube.getFiles()).getResolutions().getLabel()));

View File

@ -45,11 +45,20 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.exoplayer2.ui.PlayerView
<com.github.vkay94.dtpv.DoubleTapPlayerView
android:id="@+id/doubleTapPlayerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:use_controller="true"
app:dtpv_controller="@+id/media_video" />
<com.github.vkay94.dtpv.youtube.YouTubeOverlay
android:id="@+id/media_video"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
app:yt_playerView="@+id/doubleTapPlayerView"
android:gravity="center" />
<app.fedilab.fedilabtube.webview.CustomWebview

View File

@ -10,15 +10,12 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#CC000000"
android:animateLayoutChanges="true"
android:layoutDirection="ltr"
android:orientation="vertical"
tools:targetApi="28">
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"