From f0335d96d221d821b59054df9b2c215c96ae23ed Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 29 Oct 2020 18:56:57 +0100 Subject: [PATCH] Fix issue #18 --- app/build.gradle | 5 +- .../fedilab/fedilabtube/PeertubeActivity.java | 188 +++++++++++------- app/src/main/res/layout/activity_peertube.xml | 11 +- ...l_view.xml => exo_player_control_view.xml} | 5 +- 4 files changed, 125 insertions(+), 84 deletions(-) rename app/src/main/res/layout/{exo_playback_control_view.xml => exo_player_control_view.xml} (96%) diff --git a/app/build.gradle b/app/build.gradle index b67f707..0de01da 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } \ No newline at end of file diff --git a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java index 003021d..ca0c3b3 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java +++ b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java @@ -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())); diff --git a/app/src/main/res/layout/activity_peertube.xml b/app/src/main/res/layout/activity_peertube.xml index 961d097..e0af41a 100644 --- a/app/src/main/res/layout/activity_peertube.xml +++ b/app/src/main/res/layout/activity_peertube.xml @@ -45,11 +45,20 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"> - + + + android:orientation="vertical">