diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 35c8671..befc3c5 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 99f4b14..f5cba0f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,7 @@ - + + @@ -17,6 +18,8 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/mikkipastel/exoplayer18/AudioPlayerService.kt b/app/src/main/java/com/mikkipastel/exoplayer18/AudioPlayerService.kt new file mode 100644 index 0000000..73aba8a --- /dev/null +++ b/app/src/main/java/com/mikkipastel/exoplayer18/AudioPlayerService.kt @@ -0,0 +1,108 @@ +package com.mikkipastel.exoplayer18 + +import android.app.Notification +import android.app.PendingIntent +import android.app.Service +import android.content.Intent +import android.graphics.Bitmap +import android.os.IBinder +import com.google.android.exoplayer2.ExoPlayerFactory +import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.SimpleExoPlayer +import com.google.android.exoplayer2.source.ConcatenatingMediaSource +import com.google.android.exoplayer2.source.ExtractorMediaSource +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector +import com.google.android.exoplayer2.ui.PlayerNotificationManager +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory +import com.google.android.exoplayer2.util.Util +import com.mikkipastel.exoplayer18.C.PLAYBACK_CHANNEL_ID +import com.mikkipastel.exoplayer18.C.PLAYBACK_NOTIFICATION_ID +import com.mikkipastel.exoplayer18.Samples.SAMPLES + +class AudioPlayerService: Service() { + + lateinit var player: SimpleExoPlayer + + lateinit var playerNotificationManager: PlayerNotificationManager + + override fun onCreate() { + super.onCreate() + val context = this + + player = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector()) + + val dataSourceFactory = DefaultDataSourceFactory( + context, + Util.getUserAgent(context, "AudioDemo") + ) + + val concatenatingMediaSource = ConcatenatingMediaSource() + for (sample in SAMPLES) { + val mediaSource = ExtractorMediaSource.Factory(dataSourceFactory) + .createMediaSource(sample.uri) + concatenatingMediaSource.addMediaSource(mediaSource) + } + + player.prepare(concatenatingMediaSource) + player.playWhenReady = true + + playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel( + context, + PLAYBACK_CHANNEL_ID, + R.string.playback_channel_name, + PLAYBACK_NOTIFICATION_ID, + object: PlayerNotificationManager.MediaDescriptionAdapter { + override fun getCurrentContentTitle(player: Player?): String { + return SAMPLES[player!!.currentWindowIndex].title + } + + override fun createCurrentContentIntent(player: Player?): PendingIntent? { + return PendingIntent.getActivity( + context, + 0, + Intent(context, MainActivity::class.java), + PendingIntent.FLAG_UPDATE_CURRENT + ) + } + + override fun getCurrentContentText(player: Player?): String? { + return SAMPLES[player!!.currentWindowIndex].description + } + + override fun getCurrentLargeIcon(player: Player?, callback: PlayerNotificationManager.BitmapCallback?): Bitmap? { + return Samples.getBitmap( + context, SAMPLES[player!!.currentWindowIndex].bitmapResource) + } + + }) + + playerNotificationManager.apply { + setNotificationListener(object: PlayerNotificationManager.NotificationListener { + override fun onNotificationStarted(notificationId: Int, notification: Notification?) { + startForeground(notificationId, notification) + } + + override fun onNotificationCancelled(notificationId: Int) { + stopSelf() + } + + }) + setPlayer(player) + } + } + + override fun onDestroy() { + playerNotificationManager.setPlayer(null) + player.release() + super.onDestroy() + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + return START_STICKY + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/mikkipastel/exoplayer18/C.kt b/app/src/main/java/com/mikkipastel/exoplayer18/C.kt new file mode 100644 index 0000000..bf39742 --- /dev/null +++ b/app/src/main/java/com/mikkipastel/exoplayer18/C.kt @@ -0,0 +1,11 @@ +package com.mikkipastel.exoplayer18 + +object C { + + val PLAYBACK_CHANNEL_ID = "playback_channel" + val PLAYBACK_NOTIFICATION_ID = 1 + val MEDIA_SESSION_TAG = "audio_demo" + val DOWNLOAD_CHANNEL_ID = "download_channel" + val DOWNLOAD_NOTIFICATION_ID = 2 + +} \ No newline at end of file diff --git a/app/src/main/java/com/mikkipastel/exoplayer18/MainActivity.kt b/app/src/main/java/com/mikkipastel/exoplayer18/MainActivity.kt index 2705c77..7902da6 100644 --- a/app/src/main/java/com/mikkipastel/exoplayer18/MainActivity.kt +++ b/app/src/main/java/com/mikkipastel/exoplayer18/MainActivity.kt @@ -1,46 +1,28 @@ package com.mikkipastel.exoplayer18 import android.app.Activity +import android.content.Intent import android.os.Bundle -import com.google.android.exoplayer2.ExoPlayerFactory -import com.google.android.exoplayer2.SimpleExoPlayer -import com.google.android.exoplayer2.source.ExtractorMediaSource -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory +import android.widget.ArrayAdapter import com.google.android.exoplayer2.util.Util +import com.mikkipastel.exoplayer18.Samples.SAMPLES import kotlinx.android.synthetic.main.activity_main.* class MainActivity : Activity() { - private var player: SimpleExoPlayer? = null - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - } - - override fun onStart() { - super.onStart() - - player = ExoPlayerFactory.newSimpleInstance(this, DefaultTrackSelector()) - playerView.player = player + val intent = Intent(this, AudioPlayerService::class.java) + Util.startForegroundService(this, intent) - val dataSourceFactory = DefaultDataSourceFactory(this, - Util.getUserAgent(this, getString(R.string.app_name))) - val mediaSource = ExtractorMediaSource.Factory(dataSourceFactory) - .createMediaSource(Samples.MP4_URI) - - player?.prepare(mediaSource) - player?.playWhenReady = true + listview.adapter = ArrayAdapter( + this, + android.R.layout.simple_list_item_1, + emptyArray() + ) } - override fun onStop() { - super.onStop() - - playerView.player = null - player?.release() - player = null - } } diff --git a/app/src/main/java/com/mikkipastel/exoplayer18/Samples.kt b/app/src/main/java/com/mikkipastel/exoplayer18/Samples.kt index 35572e0..3186a94 100644 --- a/app/src/main/java/com/mikkipastel/exoplayer18/Samples.kt +++ b/app/src/main/java/com/mikkipastel/exoplayer18/Samples.kt @@ -1,11 +1,63 @@ package com.mikkipastel.exoplayer18 +import android.content.Context import android.net.Uri +import android.graphics.drawable.BitmapDrawable +import android.support.annotation.DrawableRes +import android.graphics.Bitmap +import android.support.v4.media.MediaDescriptionCompat +import android.support.v4.media.MediaMetadataCompat +import android.os.Bundle -class Samples { +object Samples { - companion object { - val MP4_URI = Uri.parse("https://storage.googleapis.com/exoplayer-test-media-0/firebase-animation.mp4") - val AD_TAG_URI = Uri.parse("https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&cmsid=496&vid=short_tencue&correlator=") + class Sample( + url: String, + val mediaId: String, + val title: String, + val description: String, + val bitmapResource: Int) { + + val uri: Uri = Uri.parse(url) + + override fun toString(): String { + return title + } + } + + val SAMPLES = arrayOf(Sample( + "http://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", + "audio_1", + "Jazz in Paris", + "Jazz for the masses", + R.drawable.album_art_1), Sample( + "http://storage.googleapis.com/automotive-media/The_Messenger.mp3", + "audio_2", + "The messenger", + "Hipster guide to London", + R.drawable.album_art_2), Sample( + "http://storage.googleapis.com/automotive-media/Talkies.mp3", + "audio_3", + "Talkies", + "If it talks like a duck and walks like a duck.", + R.drawable.album_art_3)) + + fun getMediaDescription(context: Context, sample: Sample): MediaDescriptionCompat { + val extras = Bundle() + val bitmap = getBitmap(context, sample.bitmapResource) + extras.putParcelable(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap) + extras.putParcelable(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, bitmap) + return MediaDescriptionCompat.Builder() + .setMediaId(sample.mediaId) + .setIconBitmap(bitmap) + .setTitle(sample.title) + .setDescription(sample.description) + .setExtras(extras) + .build() + } + + fun getBitmap(context: Context, @DrawableRes bitmapResource: Int): Bitmap { + return (context.resources.getDrawable(bitmapResource, context.theme) as BitmapDrawable).bitmap } + } \ No newline at end of file diff --git a/app/src/main/res/drawable/album_art_1.jpg b/app/src/main/res/drawable/album_art_1.jpg new file mode 100644 index 0000000..b7e1887 Binary files /dev/null and b/app/src/main/res/drawable/album_art_1.jpg differ diff --git a/app/src/main/res/drawable/album_art_2.jpg b/app/src/main/res/drawable/album_art_2.jpg new file mode 100644 index 0000000..223249e Binary files /dev/null and b/app/src/main/res/drawable/album_art_2.jpg differ diff --git a/app/src/main/res/drawable/album_art_3.jpg b/app/src/main/res/drawable/album_art_3.jpg new file mode 100644 index 0000000..8d5020c Binary files /dev/null and b/app/src/main/res/drawable/album_art_3.jpg differ diff --git a/app/src/main/res/drawable/ic_queue_music_24dp.xml b/app/src/main/res/drawable/ic_queue_music_24dp.xml new file mode 100644 index 0000000..cc56028 --- /dev/null +++ b/app/src/main/res/drawable/ic_queue_music_24dp.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f7c94b4..ce79eb8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,9 +3,14 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:src="@drawable/ic_queue_music_24dp" + android:scaleType="fitCenter" /> + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fa2c6c9..3a7a23a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ exoplayer18 + Playback + Download