NewPipe/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java

220 lines
8.0 KiB
Java
Raw Normal View History

package org.schabi.newpipe.player.helper;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v4.media.MediaMetadataCompat;
2019-10-07 07:54:31 +02:00
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
2019-10-07 07:54:31 +02:00
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media.session.MediaButtonReceiver;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
2020-09-10 20:36:52 +02:00
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.player.mediasession.MediaSessionCallback;
import org.schabi.newpipe.player.mediasession.PlayQueueNavigator;
import org.schabi.newpipe.player.mediasession.PlayQueuePlaybackController;
import java.util.Optional;
public class MediaSessionManager {
2020-09-10 20:36:52 +02:00
private static final String TAG = MediaSessionManager.class.getSimpleName();
public static final boolean DEBUG = MainActivity.DEBUG;
@NonNull
private final MediaSessionCompat mediaSession;
@NonNull
private final MediaSessionConnector sessionConnector;
private int lastTitleHashCode;
private int lastArtistHashCode;
private long lastDuration;
2020-09-03 22:04:58 +02:00
private int lastAlbumArtHashCode;
public MediaSessionManager(@NonNull final Context context,
@NonNull final Player player,
@NonNull final MediaSessionCallback callback) {
2020-09-10 20:36:52 +02:00
mediaSession = new MediaSessionCompat(context, TAG);
mediaSession.setActive(true);
2020-09-10 20:36:52 +02:00
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
2020-09-03 22:04:58 +02:00
.setState(PlaybackStateCompat.STATE_NONE, -1, 1)
.setActions(PlaybackStateCompat.ACTION_SEEK_TO
| PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE // was play and pause now play/pause
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
| PlaybackStateCompat.ACTION_SET_REPEAT_MODE
| PlaybackStateCompat.ACTION_STOP)
.build());
2020-09-10 20:36:52 +02:00
sessionConnector = new MediaSessionConnector(mediaSession);
sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback));
sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback));
sessionConnector.setPlayer(player);
}
@Nullable
@SuppressWarnings("UnusedReturnValue")
public KeyEvent handleMediaButtonIntent(final Intent intent) {
return MediaButtonReceiver.handleIntent(mediaSession, intent);
}
public MediaSessionCompat.Token getSessionToken() {
2020-09-10 20:36:52 +02:00
return mediaSession.getSessionToken();
}
/**
* sets the Metadata - if required.
*
* @param title {@link MediaMetadataCompat#METADATA_KEY_TITLE}
* @param artist {@link MediaMetadataCompat#METADATA_KEY_ARTIST}
* @param optAlbumArt {@link MediaMetadataCompat#METADATA_KEY_ALBUM_ART}
* @param duration {@link MediaMetadataCompat#METADATA_KEY_DURATION}
* - should be a negative value for unknown durations, e.g. for livestreams
*/
public void setMetadata(@NonNull final String title,
@NonNull final String artist,
@NonNull final Optional<Bitmap> optAlbumArt,
final long duration
) {
if (DEBUG) {
Log.d(TAG, "setMetadata called:"
+ " t: " + title
+ " a: " + artist
+ " thumb: " + (
optAlbumArt.isPresent()
? optAlbumArt.get().hashCode()
: "<none>")
+ " d: " + duration);
2021-09-24 15:00:37 +02:00
}
if (!mediaSession.isActive()) {
if (DEBUG) {
Log.d(TAG, "setMetadata: mediaSession not active - exiting");
2021-09-24 15:00:37 +02:00
}
return;
2021-09-24 15:00:37 +02:00
}
2021-09-24 23:55:06 +02:00
if (!checkIfMetadataShouldBeSet(title, artist, optAlbumArt, duration)) {
2021-09-24 15:00:37 +02:00
if (DEBUG) {
Log.d(TAG, "setMetadata: No update required - exiting");
2021-09-24 15:00:37 +02:00
}
2021-09-24 23:55:06 +02:00
return;
}
2021-09-24 15:00:37 +02:00
2021-09-24 23:55:06 +02:00
if (DEBUG) {
Log.d(TAG, "setMetadata: N_Metadata update:"
+ " t: " + title
+ " a: " + artist
+ " thumb: " + (
optAlbumArt.isPresent()
? optAlbumArt.get().hashCode()
: "<none>")
+ " d: " + duration);
}
2021-09-24 23:55:06 +02:00
final MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
if (optAlbumArt.isPresent()) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, optAlbumArt.get());
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, optAlbumArt.get());
}
2021-09-24 23:55:06 +02:00
mediaSession.setMetadata(builder.build());
2021-09-24 23:55:06 +02:00
lastTitleHashCode = title.hashCode();
lastArtistHashCode = artist.hashCode();
lastDuration = duration;
if (optAlbumArt.isPresent()) {
lastAlbumArtHashCode = optAlbumArt.get().hashCode();
}
}
private boolean checkIfMetadataShouldBeSet(
@NonNull final String title,
@NonNull final String artist,
@NonNull final Optional<Bitmap> optAlbumArt,
final long duration
) {
// Check if the values have changed since the last time
if (title.hashCode() != lastTitleHashCode
|| artist.hashCode() != lastArtistHashCode
|| duration != lastDuration
|| (optAlbumArt.isPresent() && optAlbumArt.get().hashCode() != lastAlbumArtHashCode)
) {
if (DEBUG) {
Log.d(TAG,
"checkIfMetadataShouldBeSet: true - reason: changed values since last");
2020-05-15 15:05:20 +02:00
}
return true;
}
2021-09-24 23:55:06 +02:00
2021-09-25 00:04:53 +02:00
// Check if the currently set metadata is valid
if (getMetadataTitle() == null
|| getMetadataArtist() == null
2021-09-25 00:04:53 +02:00
// Note that the duration can be <= 0 for live streams
) {
if (DEBUG) {
if (getMetadataTitle() == null) {
Log.d(TAG,
"N_getMetadataTitle: title == null");
} else if (getMetadataArtist() == null) {
Log.d(TAG,
"N_getMetadataArtist: artist == null");
}
2020-05-15 15:05:20 +02:00
}
return true;
}
2021-09-24 23:55:06 +02:00
// If we got an album art check if the current set AlbumArt is null
if (optAlbumArt.isPresent() && getMetadataAlbumArt() == null) {
2020-05-15 15:05:20 +02:00
if (DEBUG) {
2021-10-10 20:30:56 +02:00
Log.d(TAG, "N_getMetadataAlbumArt: thumb == null");
2020-05-15 15:05:20 +02:00
}
return true;
}
// Default - no update required
return false;
}
2021-10-10 20:30:56 +02:00
@Nullable
private Bitmap getMetadataAlbumArt() {
return mediaSession.getController().getMetadata()
.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART);
}
2021-10-10 20:30:56 +02:00
@Nullable
private String getMetadataTitle() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_TITLE);
}
2021-10-10 20:30:56 +02:00
@Nullable
private String getMetadataArtist() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_ARTIST);
}
/**
2020-01-03 14:29:04 +01:00
* Should be called on player destruction to prevent leakage.
*/
public void dispose() {
2020-09-10 20:36:52 +02:00
sessionConnector.setPlayer(null);
sessionConnector.setQueueNavigator(null);
mediaSession.setActive(false);
mediaSession.release();
}
}