Last active
April 19, 2020 23:14
-
-
Save 0xcaff/c20e4ea226c33eb68a5cd9cbb80fbb96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2018 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.google.android.exoplayer.audiodemo; | |
import static com.google.android.exoplayer.audiodemo.C.MEDIA_SESSION_TAG; | |
import static com.google.android.exoplayer.audiodemo.C.PLAYBACK_CHANNEL_ID; | |
import static com.google.android.exoplayer.audiodemo.C.PLAYBACK_NOTIFICATION_ID; | |
import static com.google.android.exoplayer.audiodemo.Samples.SAMPLES; | |
import android.app.Notification; | |
import android.app.NotificationManager; | |
import android.app.PendingIntent; | |
import android.app.Service; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.graphics.Bitmap; | |
import android.os.Debug; | |
import android.os.IBinder; | |
import android.support.annotation.Nullable; | |
import android.support.v4.app.NotificationManagerCompat; | |
import android.support.v4.media.MediaDescriptionCompat; | |
import android.support.v4.media.session.MediaSessionCompat; | |
import com.google.android.exoplayer2.ExoPlayerFactory; | |
import com.google.android.exoplayer2.Player; | |
import com.google.android.exoplayer2.SimpleExoPlayer; | |
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; | |
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator; | |
import com.google.android.exoplayer2.source.ConcatenatingMediaSource; | |
import com.google.android.exoplayer2.source.ExtractorMediaSource; | |
import com.google.android.exoplayer2.source.MediaSource; | |
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; | |
import com.google.android.exoplayer2.ui.PlayerNotificationManager; | |
import com.google.android.exoplayer2.ui.PlayerNotificationManager.BitmapCallback; | |
import com.google.android.exoplayer2.ui.PlayerNotificationManager.MediaDescriptionAdapter; | |
import com.google.android.exoplayer2.ui.PlayerNotificationManager.NotificationListener; | |
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; | |
import com.google.android.exoplayer2.upstream.cache.CacheDataSource; | |
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory; | |
import com.google.android.exoplayer2.util.Log; | |
import com.google.android.exoplayer2.util.NotificationUtil; | |
import com.google.android.exoplayer2.util.Util; | |
public class AudioPlayerService extends Service { | |
private SimpleExoPlayer player; | |
private PlayerNotificationManager playerNotificationManager; | |
private MediaSessionCompat mediaSession; | |
private MediaSessionConnector mediaSessionConnector; | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
final Context context = this; | |
player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector()); | |
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory( | |
context, Util.getUserAgent(context, getString(R.string.application_name))); | |
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(); | |
for (Samples.Sample sample : SAMPLES) { | |
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory) | |
.createMediaSource(sample.uri); | |
concatenatingMediaSource.addMediaSource(mediaSource); | |
} | |
player.prepare(concatenatingMediaSource); | |
player.setPlayWhenReady(true); | |
NotificationUtil.createNotificationChannel( | |
context, | |
PLAYBACK_CHANNEL_ID, | |
R.string.playback_channel_name, | |
NotificationUtil.IMPORTANCE_LOW | |
); | |
MediaDescriptionAdapter descriptionAdapter = new MediaDescriptionAdapter() { | |
@Override | |
public String getCurrentContentTitle(Player player) { | |
return SAMPLES[player.getCurrentWindowIndex()].title; | |
} | |
@Nullable | |
@Override | |
public PendingIntent createCurrentContentIntent(Player player) { | |
return null; | |
} | |
@Nullable | |
@Override | |
public String getCurrentContentText(Player player) { | |
return SAMPLES[player.getCurrentWindowIndex()].description; | |
} | |
@Nullable | |
@Override | |
public Bitmap getCurrentLargeIcon(Player player, BitmapCallback callback) { | |
return Samples.getBitmap( | |
context, SAMPLES[player.getCurrentWindowIndex()].bitmapResource); | |
} | |
}; | |
PlayerNotificationManager.NotificationDispatcher notificationDispatcher = new PlayerNotificationManager.NotificationDispatcher() { | |
boolean foregrounded = false; | |
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(AudioPlayerService.this); | |
@Override | |
public void notify(int notificationId, Notification notification) { | |
if (player.getPlayWhenReady() && !foregrounded) { | |
Util.startForegroundService( | |
AudioPlayerService.this, | |
new Intent(context, AudioPlayerService.class) | |
); | |
startForeground(notificationId, notification); | |
foregrounded = true; | |
} else { | |
notificationManager.notify(notificationId, notification); | |
} | |
if (!player.getPlayWhenReady() && foregrounded) { | |
stopForeground(false); | |
foregrounded = false; | |
} | |
} | |
@Override | |
public void cancel(int notificationId) { | |
notificationManager.cancel(notificationId); | |
stopForeground(true); | |
stopSelf(); | |
foregrounded = false; | |
} | |
}; | |
playerNotificationManager = new PlayerNotificationManager( | |
context, | |
PLAYBACK_CHANNEL_ID, | |
PLAYBACK_NOTIFICATION_ID, | |
descriptionAdapter, | |
null, | |
null, | |
notificationDispatcher | |
); | |
playerNotificationManager.setOngoing(false); | |
playerNotificationManager.setPlayer(player); | |
mediaSession = new MediaSessionCompat(context, MEDIA_SESSION_TAG); | |
mediaSession.setActive(true); | |
playerNotificationManager.setMediaSessionToken(mediaSession.getSessionToken()); | |
mediaSessionConnector = new MediaSessionConnector(mediaSession); | |
mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) { | |
@Override | |
public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) { | |
return Samples.getMediaDescription(context, SAMPLES[windowIndex]); | |
} | |
}); | |
mediaSessionConnector.setPlayer(player, null); | |
} | |
@Override | |
public void onDestroy() { | |
mediaSession.release(); | |
mediaSessionConnector.setPlayer(null, null); | |
playerNotificationManager.setPlayer(null); | |
player.release(); | |
player = null; | |
super.onDestroy(); | |
} | |
@Nullable | |
@Override | |
public IBinder onBind(Intent intent) { | |
return null; | |
} | |
@Override | |
public int onStartCommand(Intent intent, int flags, int startId) { | |
return START_STICKY; | |
} | |
} |
Where is the playerView and when to attach it to the play in case of MainActivity as a Service ? because I instantiated it either in onCreate MainActivity or the AudioPlayerService and all the mainActivity UI doesnt' show at all !
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ciaranodc Yeah, I don't remember what state I left it in exactly: https://github.com/forte-music/android