Allow seeking in video timeline.

This commit is contained in:
Nicholas Tinsley
2024-03-15 15:08:45 -04:00
committed by Cody Henthorne
parent b38865bdc7
commit c0cb2b5e12
5 changed files with 34 additions and 31 deletions

View File

@@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.video.VideoPlayer.PlayerCallback
import org.thoughtcrime.securesms.video.videoconverter.VideoThumbnailsRangeSelectorView
import org.thoughtcrime.securesms.video.videoconverter.VideoThumbnailsRangeSelectorView.PositionDragListener
import java.io.IOException
import kotlin.time.Duration.Companion.microseconds
class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragment {
private val sharedViewModel: MediaSelectionViewModel by viewModels(ownerProducer = { requireActivity() })
@@ -176,7 +177,7 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm
if (slide.hasVideo()) {
canEdit = true
try {
videoTimeLine.registerPlayerOnRangeChangeListener(this)
videoTimeLine.registerPlayerDragListener(this)
hud.visibility = View.VISIBLE
startPositionUpdates()
@@ -293,7 +294,8 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm
videoScanThrottle.publish {
player.pause()
player.playbackPosition = position
val milliseconds = position.microseconds.inWholeMilliseconds
player.playbackPosition = milliseconds
}
}

View File

@@ -543,8 +543,10 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment), Schedul
return
}
val uri = mediaItem.uri
videoTimeLine.unregisterPlayerOnRangeChangeListener()
videoTimeLine.setInput(uri)
val updatedInputInTimeline = videoTimeLine.setInput(uri)
if (updatedInputInTimeline) {
videoTimeLine.unregisterDragListener()
}
val size: Long = tryGetUriSize(requireContext(), uri, Long.MAX_VALUE)
val maxSend = sharedViewModel.getMediaConstraints().getVideoMaxSize(requireContext())
if (size > maxSend) {

View File

@@ -290,7 +290,7 @@ public class VideoPlayer extends FrameLayout {
public long getPlaybackPositionUs() {
if (this.exoPlayer != null) {
return TimeUnit.MILLISECONDS.toMicros(this.exoPlayer.getCurrentPosition()) + clippedStartUs;
return TimeUnit.MILLISECONDS.toMicros(this.exoPlayer.getCurrentPosition());
}
return -1L;
}

View File

@@ -55,7 +55,7 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
private long downMax;
private Thumb dragThumb;
private Thumb lastDragThumb;
private PositionDragListener playerOnRangeChangeListener;
private PositionDragListener playerDragListener;
private RangeDragListener editorOnRangeChangeListener;
@Px private int thumbSizePixels;
@Px private int thumbTouchRadius;
@@ -133,16 +133,16 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
invalidate();
}
public void registerPlayerOnRangeChangeListener(PositionDragListener playerOnRangeChangeListener) {
this.playerOnRangeChangeListener = playerOnRangeChangeListener;
public void registerPlayerDragListener(PositionDragListener playerDragListener) {
this.playerDragListener = playerDragListener;
}
public void registerEditorOnRangeChangeListener(RangeDragListener editorOnRangeChangeListener) {
this.editorOnRangeChangeListener = editorOnRangeChangeListener;
}
public void unregisterPlayerOnRangeChangeListener() {
this.playerOnRangeChangeListener = null;
public void unregisterDragListener() {
this.playerDragListener = null;
}
public void setActualPosition(long position) {
@@ -347,20 +347,15 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
}
if (actionMasked == MotionEvent.ACTION_MOVE) {
boolean changed = false;
long delta = pixelToDuration(event.getX() - xDown);
switch (dragThumb) {
case POSITION:
setDragPosition(downCursor + delta);
changed = true;
break;
case MIN:
changed = setMinValue(downMin + delta);
break;
case MAX:
changed = setMaxValue(downMax + delta);
break;
}
boolean changed = switch (dragThumb) {
case POSITION -> {
setDragPosition(pixelToDuration(event.getX()));
yield true;
}
case MIN -> setMinValue(downMin + delta);
case MAX -> setMaxValue(downMax + delta);
};
if (changed) {
if (dragThumb == Thumb.POSITION) {
onPositionDrag(dragPosition);
@@ -393,7 +388,7 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
return true;
}
private @Nullable Thumb closestThumb(@Px float x) {
private Thumb closestThumb(@Px float x) {
float midPoint = (right + left) / 2f;
Thumb possibleThumb = x < midPoint ? Thumb.MIN : Thumb.MAX;
int possibleThumbX = x < midPoint ? left : right;
@@ -402,7 +397,7 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
return possibleThumb;
}
return null;
return Thumb.POSITION;
}
private long pixelToDuration(float pixel) {
@@ -431,14 +426,14 @@ public final class VideoThumbnailsRangeSelectorView extends VideoThumbnailsView
}
private void onPositionDrag(long position) {
if (playerOnRangeChangeListener != null) {
playerOnRangeChangeListener.onPositionDrag(position);
if (playerDragListener != null) {
playerDragListener.onPositionDrag(position);
}
}
private void onEndPositionDrag(long position) {
if (playerOnRangeChangeListener != null) {
playerOnRangeChangeListener.onEndPositionDrag(position);
if (playerDragListener != null) {
playerDragListener.onEndPositionDrag(position);
}
}

View File

@@ -59,9 +59,12 @@ abstract public class VideoThumbnailsView extends View {
super(context, attrs, defStyleAttr);
}
public void setInput(@NonNull Uri uri) throws IOException {
/**
* @return Whether or not the current URI was changed.
*/
public boolean setInput(@NonNull Uri uri) throws IOException {
if (uri.equals(this.currentUri)) {
return;
return false;
}
this.currentUri = uri;
@@ -72,6 +75,7 @@ abstract public class VideoThumbnailsView extends View {
thumbnailsTask = null;
}
invalidate();
return true;
}
@Override