Add seek buttons for videos longer than 30s.
This commit is contained in:
parent
7f4e964ec8
commit
32fbbf2b55
5 changed files with 36 additions and 13 deletions
|
@ -9,6 +9,8 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
|
@ -85,7 +87,7 @@ public abstract class MediaPreviewFragment extends Fragment {
|
|||
public void pause() {
|
||||
}
|
||||
|
||||
public @Nullable View getPlaybackControls() {
|
||||
public @Nullable PlayerControlView getPlaybackControls() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.fragment.app.viewModels
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import com.google.android.exoplayer2.ui.PlayerControlView
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
@ -199,8 +200,7 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
|||
*/
|
||||
private fun bindLoadedState(currentState: MediaPreviewV2State) {
|
||||
val currentItem: MediaDatabase.MediaRecord = currentState.mediaRecords[currentState.position]
|
||||
val currentFragment: Fragment? = childFragmentManager.findFragmentByTag("f${currentState.position}")
|
||||
val playbackControls = (currentFragment as? MediaPreviewFragment)?.playbackControls
|
||||
|
||||
val albumThumbnailMedia = if (currentState.allMediaInAlbumRail) {
|
||||
currentState.mediaRecords.map { it.toMedia() }
|
||||
} else {
|
||||
|
@ -209,11 +209,7 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
|||
.map { it.toMedia() }
|
||||
}
|
||||
val caption = currentItem.attachment?.caption
|
||||
if (albumThumbnailMedia.size <= 1 && caption == null && playbackControls == null) {
|
||||
binding.mediaPreviewDetailsContainer.visibility = View.GONE
|
||||
} else {
|
||||
binding.mediaPreviewDetailsContainer.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
binding.mediaPreviewAlbumRail.visibility = if (albumThumbnailMedia.size <= 1) View.GONE else View.VISIBLE
|
||||
(binding.mediaPreviewAlbumRail.adapter as MediaRailAdapter).setMedia(albumThumbnailMedia, currentState.position)
|
||||
binding.mediaPreviewAlbumRail.smoothScrollToPosition(currentState.position)
|
||||
|
@ -221,13 +217,19 @@ class MediaPreviewV2Fragment : Fragment(R.layout.fragment_media_preview_v2), Med
|
|||
binding.mediaPreviewCaptionContainer.visibility = if (caption == null) View.GONE else View.VISIBLE
|
||||
binding.mediaPreviewCaption.text = caption
|
||||
|
||||
val fragmentTag = "f${currentState.position}"
|
||||
val currentFragment: Fragment? = childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
val playbackControls: PlayerControlView? = (currentFragment as? MediaPreviewFragment)?.playbackControls
|
||||
if (albumThumbnailMedia.size <= 1 && caption == null && playbackControls == null) {
|
||||
binding.mediaPreviewDetailsContainer.visibility = View.GONE
|
||||
} else {
|
||||
binding.mediaPreviewDetailsContainer.visibility = View.VISIBLE
|
||||
}
|
||||
binding.mediaPreviewPlaybackControlsContainer.removeAllViews()
|
||||
if (playbackControls != null) {
|
||||
val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
playbackControls.layoutParams = params
|
||||
binding.mediaPreviewPlaybackControlsContainer.removeAllViews()
|
||||
binding.mediaPreviewPlaybackControlsContainer.addView(playbackControls)
|
||||
} else {
|
||||
binding.mediaPreviewPlaybackControlsContainer.removeAllViews()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import android.view.ViewGroup;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner;
|
||||
|
@ -17,10 +19,14 @@ import org.thoughtcrime.securesms.mms.VideoSlide;
|
|||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.video.VideoPlayer;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
||||
|
||||
private static final String TAG = Log.tag(VideoMediaPreviewFragment.class);
|
||||
|
||||
private static final Long MINIMUM_DURATION_FOR_SKIP_MS = TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS);
|
||||
|
||||
private VideoPlayer videoView;
|
||||
private boolean isVideoGif;
|
||||
|
||||
|
@ -90,6 +96,15 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
return itemView;
|
||||
}
|
||||
|
||||
private void updateSkipButtonState() {
|
||||
final PlayerControlView playbackControls = getPlaybackControls();
|
||||
if (playbackControls != null) {
|
||||
boolean shouldShowSkipButtons = videoView.getDuration() > MINIMUM_DURATION_FOR_SKIP_MS;
|
||||
playbackControls.setShowFastForwardButton(shouldShowSkipButtons);
|
||||
playbackControls.setShowRewindButton(shouldShowSkipButtons);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
@ -127,8 +142,9 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getPlaybackControls() {
|
||||
public PlayerControlView getPlaybackControls() {
|
||||
return videoView != null && !isVideoGif ? videoView.getControlView() : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ public class VideoPlayer extends FrameLayout {
|
|||
super.setOnClickListener(l);
|
||||
}
|
||||
|
||||
public @Nullable View getControlView() {
|
||||
public @Nullable PlayerControlView getControlView() {
|
||||
return this.exoControls;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ class SimpleExoPlayerPool(context: Context) : ExoPlayerPool<ExoPlayer>(MAXIMUM_R
|
|||
override fun createPlayer(): ExoPlayer {
|
||||
return ExoPlayer.Builder(context)
|
||||
.setMediaSourceFactory(mediaSourceFactory)
|
||||
.setSeekBackIncrementMs(SEEK_INTERVAL.inWholeMilliseconds)
|
||||
.setSeekForwardIncrementMs(SEEK_INTERVAL.inWholeMilliseconds)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,7 @@ class SimpleExoPlayerPool(context: Context) : ExoPlayerPool<ExoPlayer>(MAXIMUM_R
|
|||
private const val MAXIMUM_RESERVED_PLAYERS = 1
|
||||
private const val MAXIMUM_SUPPORTED_PLAYBACK_PRE_23 = 6
|
||||
private const val MAXIMUM_SUPPORTED_PLAYBACK_PRE_23_LOW_MEM = 3
|
||||
private val SEEK_INTERVAL = 15.seconds
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue