Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #90 from Atemu/player-queue-seekbar-markers
Browse files Browse the repository at this point in the history
PlayQueue: Mark SponsorBlock segments in seekbar
  • Loading branch information
polymorphicshade authored Aug 24, 2021
2 parents 6b564ad + a252a5b commit 2af884e
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
Expand All @@ -17,6 +18,7 @@

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
Expand Down Expand Up @@ -47,6 +49,7 @@

import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import static org.schabi.newpipe.util.SponsorBlockUtils.markSegments;
import static org.schabi.newpipe.util.external_communication.ShareUtils.shareText;

public final class PlayQueueActivity extends AppCompatActivity
Expand Down Expand Up @@ -225,6 +228,12 @@ public void onServiceConnected(final ComponentName name, final IBinder service)
} else {
buildComponents();
if (player != null) {
final PlayQueueItem item = player.getPlayQueue().getItem();
final Context context = getApplicationContext();
final SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context);
markSegments(item, queueControlBinding.seekBar, context, prefs);

player.setActivityListener(PlayQueueActivity.this);
}
}
Expand Down
104 changes: 2 additions & 102 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@
import org.schabi.newpipe.util.SponsorBlockMode;
import org.schabi.newpipe.util.VideoSegment;
import org.schabi.newpipe.views.ExpandableSurfaceView;
import org.schabi.newpipe.views.SeekBarMarker;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -192,6 +191,7 @@
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import static org.schabi.newpipe.util.Localization.containsCaseInsensitive;
import static org.schabi.newpipe.util.SponsorBlockUtils.markSegments;

public final class Player implements
EventListener,
Expand Down Expand Up @@ -2132,7 +2132,7 @@ private void onPrepared(final boolean playWhenReady) {
audioReactor.requestAudioFocus();
}

markSegments();
markSegments(currentItem, binding.playbackSeekBar, context, prefs);
}

private void onBlocked() {
Expand Down Expand Up @@ -4438,106 +4438,6 @@ public VideoSegment getSkippableSegment(final int progress) {
return null;
}

private void markSegments() {
binding.playbackSeekBar.clearMarkers();

if (currentItem == null) {
Log.w(TAG, "markSegments() - currentItem was null");
return;
}

final VideoSegment[] segments = currentItem.getVideoSegments();

if (segments == null || segments.length == 0) {
return;
}

for (final VideoSegment segment : segments) {
final Integer color = parseSegmentCategory(segment.category);

// if null, then this category should not be marked
if (color == null) {
continue;
}

final SeekBarMarker seekBarMarker =
new SeekBarMarker(segment.startTime, segment.endTime,
(int) simpleExoPlayer.getDuration(), color);
binding.playbackSeekBar.seekBarMarkers.add(seekBarMarker);
}

binding.playbackSeekBar.drawMarkers();
}

private Integer parseSegmentCategory(final String category) {
String key;
final String colorStr;
switch (category) {
case "sponsor":
key = context.getString(R.string.sponsor_block_category_sponsor_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_sponsor_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.sponsor_segment)
: Color.parseColor(colorStr);
}
break;
case "intro":
key = context.getString(R.string.sponsor_block_category_intro_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_intro_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.intro_segment)
: Color.parseColor(colorStr);
}
break;
case "outro":
key = context.getString(R.string.sponsor_block_category_outro_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_outro_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.outro_segment)
: Color.parseColor(colorStr);
}
break;
case "interaction":
key = context.getString(R.string.sponsor_block_category_interaction_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_interaction_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.interaction_segment)
: Color.parseColor(colorStr);
}
break;
case "selfpromo":
key = context.getString(R.string.sponsor_block_category_self_promo_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_self_promo_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.self_promo_segment)
: Color.parseColor(colorStr);
}
break;
case "music_offtopic":
key = context.getString(R.string.sponsor_block_category_non_music_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_non_music_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.non_music_segment)
: Color.parseColor(colorStr);
}
break;
}

return null;
}

protected void setBlockSponsorsButton(final ImageButton button) {
if (button == null) {
return;
Expand Down
115 changes: 115 additions & 0 deletions app/src/main/java/org/schabi/newpipe/util/SponsorBlockUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.text.TextUtils;
import android.util.Log;
Expand All @@ -18,6 +19,9 @@
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.views.MarkableSeekBar;
import org.schabi.newpipe.views.SeekBarMarker;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
Expand Down Expand Up @@ -195,4 +199,115 @@ private static String toSha256(final String videoId) {
return null;
}
}

static Integer parseSegmentCategory(
final String category,
final Context context,
final SharedPreferences prefs
) {
String key;
final String colorStr;
switch (category) {
case "sponsor":
key = context.getString(R.string.sponsor_block_category_sponsor_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_sponsor_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.sponsor_segment)
: Color.parseColor(colorStr);
}
break;
case "intro":
key = context.getString(R.string.sponsor_block_category_intro_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_intro_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.intro_segment)
: Color.parseColor(colorStr);
}
break;
case "outro":
key = context.getString(R.string.sponsor_block_category_outro_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_outro_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.outro_segment)
: Color.parseColor(colorStr);
}
break;
case "interaction":
key = context.getString(R.string.sponsor_block_category_interaction_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_interaction_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.interaction_segment)
: Color.parseColor(colorStr);
}
break;
case "selfpromo":
key = context.getString(R.string.sponsor_block_category_self_promo_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_self_promo_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.self_promo_segment)
: Color.parseColor(colorStr);
}
break;
case "music_offtopic":
key = context.getString(R.string.sponsor_block_category_non_music_key);
if (prefs.getBoolean(key, false)) {
key = context.getString(R.string.sponsor_block_category_non_music_color_key);
colorStr = prefs.getString(key, null);
return colorStr == null
? context.getResources().getColor(R.color.non_music_segment)
: Color.parseColor(colorStr);
}
break;
}

return null;
}

public static void markSegments(
final PlayQueueItem currentItem,
final MarkableSeekBar seekBar,
final Context context,
final SharedPreferences prefs
) {
seekBar.clearMarkers();

if (currentItem == null) {
return;
}

final VideoSegment[] segments = currentItem.getVideoSegments();

if (segments == null || segments.length == 0) {
return;
}

for (final VideoSegment segment : segments) {
final Integer color = parseSegmentCategory(segment.category, context, prefs);

// if null, then this category should not be marked
if (color == null) {
continue;
}

// Duration is in seconds, we need millis
final int length = (int) currentItem.getDuration() * 1000;

final SeekBarMarker seekBarMarker =
new SeekBarMarker(segment.startTime, segment.endTime,
length, color);
seekBar.seekBarMarkers.add(seekBarMarker);
}

seekBar.drawMarkers();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@
tools:ignore="HardcodedText"
tools:text="1:06:29" />

<androidx.appcompat.widget.AppCompatSeekBar
<org.schabi.newpipe.views.FocusAwareSeekBar
android:id="@+id/seek_bar"
style="@style/Widget.AppCompat.SeekBar"
android:layout_width="0dp"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_player_queue_control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
tools:text="1:06:29" />


<androidx.appcompat.widget.AppCompatSeekBar
<org.schabi.newpipe.views.FocusAwareSeekBar
android:id="@+id/seek_bar"
style="@style/Widget.AppCompat.SeekBar"
android:layout_width="0dp"
Expand Down

0 comments on commit 2af884e

Please sign in to comment.