Skip to content

Commit

Permalink
local playback done
Browse files Browse the repository at this point in the history
  • Loading branch information
kshivang committed Sep 30, 2019
1 parent b1dc83d commit 6094983
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 33 deletions.
4 changes: 1 addition & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'

// Picasso
implementation 'com.squareup.picasso:picasso:2.71828'

// Glide
implementation 'com.github.bumptech.glide:glide:4.9.0'

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.squareup.picasso.Picasso
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import java.lang.Exception
Expand Down Expand Up @@ -66,7 +65,8 @@ class AudioPlayerActivity : AppCompatActivity(), GoonjPlayer {

private fun onPlayingTrackChange(currentItem: Track) {
if (knownTrack.id != currentItem.id) {
Picasso.get().load(currentItem.imageUrl).into(audioPlayerAlbumArtIV)
// Picasso.get().load(currentItem.imageUrl).into(audioPlayerAlbumArtIV)
currentItem.load { audioPlayerAlbumArtIV.setImageBitmap(it) }
audioPlayerAlbumTitleTv.text = currentItem.title
audioPlayerAlbumArtistTv.text = currentItem.artistName
}
Expand Down
34 changes: 29 additions & 5 deletions app/src/main/java/ai/rever/goonjexample/GoonjExampleApp.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package ai.rever.goonjexample

import ai.rever.goonj.Goonj
import ai.rever.goonj.models.Track
import android.app.Application
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.*
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition

class GoonjExampleApp: Application(), LifecycleObserver {

Expand All @@ -22,7 +26,8 @@ class GoonjExampleApp: Application(), LifecycleObserver {

Goonj.initialize(this)
.setPendingIntentForNotification(pendingIntent)
.addOnTrackComplete { }
.addOnTrackComplete(::onTrackComplete)
.setImageLoader(::imageLoader)
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
Expand All @@ -31,5 +36,24 @@ class GoonjExampleApp: Application(), LifecycleObserver {

Goonj.unregister()
}

private fun imageLoader(track: Track, callback: (Bitmap?) -> Unit) {
Glide.with(this).asBitmap().load(track.imageUrl)
.into(object : CustomTarget<Bitmap>(){
override fun onResourceReady(resource: Bitmap,
transition: Transition<in Bitmap>?) {
callback(resource)
}

override fun onLoadCleared(placeholder: Drawable?) {
callback(placeholder?.toBitmap())
}
})

}

private fun onTrackComplete(track: Track) {

}
}

2 changes: 0 additions & 2 deletions goonj/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ dependencies {

implementation 'com.google.android.gms:play-services-cast-framework:17.1.0'


// Architecture components
implementation 'android.arch.work:work-runtime-ktx:1.0.1'
implementation "android.arch.persistence.room:runtime:1.1.1"
Expand All @@ -66,7 +65,6 @@ dependencies {
api "io.reactivex.rxjava2:rxkotlin:2.4.0"
api 'io.reactivex.rxjava2:rxandroid:2.1.1'


// Exo LocalAudioPlayer
implementation 'com.google.android.exoplayer:exoplayer-core:2.10.3'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.3'
Expand Down
8 changes: 7 additions & 1 deletion goonj/src/main/java/ai/rever/goonj/Goonj.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Bitmap
import android.os.IBinder
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
Expand All @@ -27,7 +28,7 @@ object Goonj {

internal val appContext get() = weakContext?.get()
private var weakContext: WeakReference<Context>? = null

internal var imageLoader: ((Track, (Bitmap?) -> Unit) -> Unit)? = null
private var holderGoonjPlayerServiceInterface:
WeakReference<GoonjPlayerServiceInterface?>? = null

Expand Down Expand Up @@ -64,6 +65,11 @@ object Goonj {
return this
}

fun setImageLoader(imageLoader: (Track, (Bitmap?) -> Unit) -> Unit): Goonj {
this.imageLoader = imageLoader
return this
}

fun setPendingIntentForNotification(intent: Intent): Goonj {
run {
GoonjNotificationManager.pendingIntent = intent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ai.rever.goonj.manager

import ai.rever.goonj.Goonj
import ai.rever.goonj.R
import ai.rever.goonj.models.defaultBitmap
import ai.rever.goonj.util.PLAYBACK_CHANNEL_ID
import ai.rever.goonj.util.PLAYBACK_NOTIFICATION_ID
import android.app.Notification
Expand Down Expand Up @@ -63,10 +62,13 @@ object GoonjNotificationManager {

@Nullable
override fun getCurrentLargeIcon(player: Player, callback: PlayerNotificationManager.BitmapCallback): Bitmap? {
// Todo load image from async using glide or picasso give to callback

return Goonj.appContext?.defaultBitmap
val track = GoonjPlayerManager.trackList[player.currentWindowIndex]
track.load {
callback.onBitmap(it)
}
return track.bitmap
}

}

private val notificationListener = object : PlayerNotificationManager.NotificationListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ internal object GoonjPlayerManager {
internal fun addTrack(track: Track, index: Int = mTrackList.size) {
track.trackState.index = index
mTrackList.add(index, track)

player?.enqueue(track, index)
}

Expand Down
42 changes: 37 additions & 5 deletions goonj/src/main/java/ai/rever/goonj/models/Track.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package ai.rever.goonj.models

import ai.rever.goonj.Goonj
import ai.rever.goonj.Goonj.appContext
import ai.rever.goonj.GoonjPlayerState
import ai.rever.goonj.R
import android.content.Context
import android.graphics.Bitmap
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.MediaMetadataCompat
import android.os.Bundle
import android.os.Parcelable
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import androidx.mediarouter.media.MediaItemStatus
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
Expand Down Expand Up @@ -85,6 +86,8 @@ data class Track (var url: String = "",
@Ignore
var extras: Bundle? = null,
@Ignore
var bitmap: Bitmap? = null,
@Ignore
val trackState: TrackState = TrackState()
): Parcelable {

Expand Down Expand Up @@ -114,20 +117,49 @@ data class Track (var url: String = "",

val mediaDescription: MediaDescriptionCompat get() {
val extras = Bundle()


val mediaDescriptionBuilder = MediaDescriptionCompat.Builder()
.setMediaId(id)
.setTitle(title)
.setDescription(artistName)
.setExtras(extras)

val bitmap = appContext?.defaultBitmap
extras.putParcelable(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
extras.putParcelable(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, bitmap)
if (bitmap != null) {
mediaDescriptionBuilder.setIconBitmap(bitmap)

extras.putParcelable(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
extras.putParcelable(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, appContext?.defaultBitmap)

mediaDescriptionBuilder.setIconBitmap(bitmap)
} else {
val bitmap = appContext?.defaultBitmap

extras.putParcelable(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
extras.putParcelable(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, bitmap)

mediaDescriptionBuilder.setIconBitmap(bitmap)
}

return mediaDescriptionBuilder.build()
}

fun load(callback: (Bitmap?) -> Unit) {
if (bitmap != null) {
callback(bitmap)
}

val imageLoader = Goonj.imageLoader
if (imageLoader == null) {
bitmap = appContext?.defaultBitmap
callback(bitmap)
return
}

imageLoader(this) {
bitmap = it
callback(it)
}
}
}


Expand Down
28 changes: 18 additions & 10 deletions goonj/src/main/java/ai/rever/goonj/player/LocalAudioPlayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@ package ai.rever.goonj.player
import ai.rever.goonj.Goonj.appContext
import ai.rever.goonj.GoonjPlayerState
import ai.rever.goonj.R
import ai.rever.goonj.analytics.*
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.session.MediaSessionCompat
import androidx.core.net.toUri
import ai.rever.goonj.analytics.ExoPlayerAnalyticsListenerImp
import ai.rever.goonj.analytics.ExoPlayerEvenListenerImp
import ai.rever.goonj.download.DownloadUtil
import ai.rever.goonj.interfaces.AudioPlayer
import ai.rever.goonj.models.Track
import ai.rever.goonj.manager.GoonjNotificationManager.playerNotificationManager
import ai.rever.goonj.manager.GoonjPlayerManager
import ai.rever.goonj.models.Track
import ai.rever.goonj.util.MEDIA_SESSION_TAG
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.session.MediaSessionCompat
import android.util.Log
import com.google.android.exoplayer2.*
import androidx.core.net.toUri
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.ExoPlayerFactory
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator
import com.google.android.exoplayer2.source.*
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
Expand All @@ -27,6 +32,9 @@ import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.plusAssign
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit

class LocalAudioPlayer: AudioPlayer {
Expand Down Expand Up @@ -133,7 +141,8 @@ class LocalAudioPlayer: AudioPlayer {
}

private fun updateCurrentlyPlayingTrack() {
val currentTrack = trackList[player.currentWindowIndex]
if (trackList.isEmpty()) return
val currentTrack = trackList[player.currentWindowIndex]
val lastKnownTrack = GoonjPlayerManager.currentPlayingTrack.value

if (player.contentDuration > 0) {
Expand Down Expand Up @@ -219,8 +228,7 @@ class LocalAudioPlayer: AudioPlayer {
}

override fun enqueue(track: Track, index : Int) {

val mediaSource = ProgressiveMediaSource.Factory(cacheDataSourceFactory)
val mediaSource = ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(track.url.toUri())

concatenatingMediaSource.addMediaSource(index, mediaSource)
Expand Down

0 comments on commit 6094983

Please sign in to comment.