mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2026-10-12 02:31:49 +00:00
Add chapter markers support to seekbar and update UI elements
This commit is contained in:
@@ -65,7 +65,9 @@ import org.schabi.newpipe.databinding.PlayerBinding;
|
||||
import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream.StreamSegment;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.views.ChaptersSeekBar;
|
||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||
import org.schabi.newpipe.ktx.AnimationType;
|
||||
import org.schabi.newpipe.player.Player;
|
||||
@@ -85,6 +87,7 @@ import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||
import org.schabi.newpipe.views.player.PlayerFastSeekOverlay;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -147,6 +150,9 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
private final SeekbarPreviewThumbnailHolder seekbarPreviewThumbnailHolder =
|
||||
new SeekbarPreviewThumbnailHolder();
|
||||
|
||||
@NonNull
|
||||
private List<StreamSegment> currentChapters = Collections.emptyList();
|
||||
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, setup, destroy
|
||||
@@ -589,6 +595,14 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
binding.currentSeekbarPreviewThumbnail,
|
||||
binding.subtitleView::getWidth);
|
||||
|
||||
// Chapter title tooltip
|
||||
if (!currentChapters.isEmpty()) {
|
||||
final StreamSegment chapter = getChapterAtMs(progress);
|
||||
if (chapter != null && chapter.getTitle() != null) {
|
||||
binding.currentChapterTitle.setText(chapter.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
adjustSeekbarPreviewContainer();
|
||||
}
|
||||
|
||||
@@ -642,6 +656,10 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
animate(binding.currentSeekbarPreviewThumbnail, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
if (!currentChapters.isEmpty()) {
|
||||
animate(binding.currentChapterTitle, true, DEFAULT_CONTROLS_DURATION,
|
||||
AnimationType.SCALE_AND_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // seekbar listener
|
||||
@@ -658,6 +676,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress()));
|
||||
animate(binding.currentDisplaySeek, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
animate(binding.currentSeekbarPreviewThumbnail, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
animate(binding.currentChapterTitle, false, 200, AnimationType.SCALE_AND_ALPHA);
|
||||
|
||||
if (player.getCurrentState() == STATE_PAUSED_SEEK) {
|
||||
player.changeState(STATE_BUFFERING);
|
||||
@@ -668,6 +687,25 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
|
||||
showControlsThenHide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chapter active at the given playback position, or {@code null} if
|
||||
* {@code currentChapters} is empty.
|
||||
*
|
||||
* @param positionMs playback position in milliseconds
|
||||
* @return the {@link StreamSegment} whose window contains {@code positionMs}
|
||||
*/
|
||||
@Nullable
|
||||
private StreamSegment getChapterAtMs(final long positionMs) {
|
||||
StreamSegment result = null;
|
||||
for (final StreamSegment seg : currentChapters) {
|
||||
if (seg.getStartTimeSeconds() * 1000L > positionMs) {
|
||||
break;
|
||||
}
|
||||
result = seg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
||||
@@ -1036,6 +1074,22 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
||||
binding.channelTextView.setText(info.getUploaderName());
|
||||
|
||||
this.seekbarPreviewThumbnailHolder.resetFrom(player.getContext(), info.getPreviewFrames());
|
||||
|
||||
// Chapter markers on seekbar
|
||||
currentChapters = info.getStreamSegments() != null
|
||||
? info.getStreamSegments() : Collections.emptyList();
|
||||
Log.d(TAG, "onMetadataChanged: seekBarClass="
|
||||
+ binding.playbackSeekBar.getClass().getSimpleName()
|
||||
+ " segments=" + currentChapters.size()
|
||||
+ " duration=" + info.getDuration());
|
||||
if (binding.playbackSeekBar instanceof ChaptersSeekBar) {
|
||||
((ChaptersSeekBar) binding.playbackSeekBar)
|
||||
.setChapters(currentChapters, info.getDuration());
|
||||
} else {
|
||||
Log.e(TAG, "onMetadataChanged: playbackSeekBar is NOT a ChaptersSeekBar! "
|
||||
+ "Check that player.xml was rebuilt.");
|
||||
}
|
||||
binding.currentChapterTitle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void updateStreamRelatedViews() {
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.schabi.newpipe.util.DeviceUtils;
|
||||
* (onStartTrackingTouch/onStopTrackingTouch), so existing code does not need to be changed to
|
||||
* work with it.
|
||||
*/
|
||||
public final class FocusAwareSeekBar extends AppCompatSeekBar {
|
||||
public class FocusAwareSeekBar extends AppCompatSeekBar {
|
||||
private NestedListener listener;
|
||||
|
||||
private ViewTreeObserver treeObserver;
|
||||
|
||||
@@ -415,6 +415,23 @@
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/currentChapterTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#60000000"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
tools:ignore="RtlHardcoded"
|
||||
tools:text="Introduction"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/currentDisplaySeek"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -467,7 +484,7 @@
|
||||
tools:text="1:06:29" />
|
||||
|
||||
|
||||
<org.schabi.newpipe.views.FocusAwareSeekBar
|
||||
<org.schabi.newpipe.views.ChaptersSeekBar
|
||||
android:id="@+id/playbackSeekBar"
|
||||
style="@style/Widget.AppCompat.SeekBar"
|
||||
android:layout_width="0dp"
|
||||
|
||||
Reference in New Issue
Block a user