kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale-android
Update Exoplayer all the way to 2.18.1
rodzic
ef01386f16
commit
c27d2d0d55
|
@ -52,7 +52,7 @@ android {
|
|||
disable += listOf("MissingTranslation", "ExtraTranslation")
|
||||
}
|
||||
|
||||
compileSdk = 31
|
||||
compileSdk = 33
|
||||
|
||||
defaultConfig {
|
||||
|
||||
|
@ -62,7 +62,7 @@ android {
|
|||
versionName = androidGitVersion.name()
|
||||
|
||||
minSdk = 24
|
||||
targetSdk = 30
|
||||
targetSdk = 33
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
@ -167,21 +167,14 @@ dependencies {
|
|||
implementation("com.google.android.material:material:1.6.1")
|
||||
implementation("com.android.support.constraint:constraint-layout:2.0.4")
|
||||
|
||||
implementation("com.google.android.exoplayer:exoplayer-core:2.14.2")
|
||||
implementation("com.google.android.exoplayer:exoplayer-ui:2.14.2")
|
||||
implementation("com.google.android.exoplayer:extension-mediasession:2.14.2")
|
||||
implementation("com.google.android.exoplayer:exoplayer-core:2.18.1")
|
||||
implementation("com.google.android.exoplayer:exoplayer-ui:2.18.1")
|
||||
implementation("com.google.android.exoplayer:extension-mediasession:2.18.1")
|
||||
|
||||
implementation("io.insert-koin:koin-core:3.1.2")
|
||||
implementation("io.insert-koin:koin-android:3.1.2")
|
||||
testImplementation("io.insert-koin:koin-test:3.1.2")
|
||||
|
||||
implementation("com.github.PaulWoitaschek.ExoPlayer-Extensions:extension-opus:2.14.0") {
|
||||
isTransitive = false
|
||||
}
|
||||
implementation("com.github.PaulWoitaschek.ExoPlayer-Extensions:extension-flac:2.14.0") {
|
||||
isTransitive = false
|
||||
}
|
||||
|
||||
implementation("com.aliassadi:power-preference-lib:2.0.0")
|
||||
implementation("com.github.kittinunf.fuel:fuel:2.3.1")
|
||||
implementation("com.github.kittinunf.fuel:fuel-coroutines:2.3.1")
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
android:name=".activities.SplashActivity"
|
||||
android:launchMode="singleInstance"
|
||||
android:noHistory="true"
|
||||
android:screenOrientation="portrait">
|
||||
android:screenOrientation="portrait"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -61,7 +62,8 @@
|
|||
|
||||
<service
|
||||
android:name=".playback.PlayerService"
|
||||
android:foregroundServiceType="mediaPlayback">
|
||||
android:foregroundServiceType="mediaPlayback"
|
||||
android:exported="false">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
|
@ -80,7 +82,8 @@
|
|||
|
||||
</service>
|
||||
|
||||
<receiver android:name="androidx.media.session.MediaButtonReceiver">
|
||||
<receiver android:name="androidx.media.session.MediaButtonReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
</intent-filter>
|
||||
|
|
|
@ -228,8 +228,8 @@ class MainActivity : AppCompatActivity() {
|
|||
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW)
|
||||
item.actionView = View(this)
|
||||
item.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(item: MenuItem?) = false
|
||||
override fun onMenuItemActionCollapse(item: MenuItem?) = false
|
||||
override fun onMenuItemActionExpand(item: MenuItem) = false
|
||||
override fun onMenuItemActionCollapse(item: MenuItem) = false
|
||||
})
|
||||
|
||||
item.isChecked = !item.isChecked
|
||||
|
@ -359,7 +359,7 @@ class MainActivity : AppCompatActivity() {
|
|||
.alpha(0.0f)
|
||||
.setDuration(400)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animator: Animator?) {
|
||||
override fun onAnimationEnd(animator: Animator) {
|
||||
binding.nowPlaying.visibility = View.GONE
|
||||
}
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@ package audio.funkwhale.ffa.playback
|
|||
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_MUTABLE
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
|
@ -42,7 +43,7 @@ class MediaControlsManager(val context: Service, private val scope: CoroutineSco
|
|||
|
||||
scope.launch(Default) {
|
||||
val openIntent = Intent(context, MainActivity::class.java).apply { action = NOTIFICATION_ACTION_OPEN_QUEUE.toString() }
|
||||
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0)
|
||||
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, FLAG_MUTABLE)
|
||||
|
||||
val coverUrl = maybeNormalizeUrl(track.album?.cover())
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.support.v4.media.session.MediaSessionCompat
|
|||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import audio.funkwhale.ffa.utils.Command
|
||||
import audio.funkwhale.ffa.utils.CommandBus
|
||||
import com.google.android.exoplayer2.ControlDispatcher
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
|
||||
|
||||
|
@ -43,7 +42,7 @@ class MediaSession(private val context: Context) {
|
|||
MediaSessionConnector(session).also {
|
||||
it.setQueueNavigator(FFAQueueNavigator())
|
||||
|
||||
it.setMediaButtonEventHandler { _, _, intent ->
|
||||
it.setMediaButtonEventHandler { _, intent ->
|
||||
if (!active) {
|
||||
Intent(context, PlayerService::class.java).let { player ->
|
||||
player.action = intent.action
|
||||
|
@ -67,13 +66,14 @@ class MediaSession(private val context: Context) {
|
|||
}
|
||||
|
||||
class FFAQueueNavigator : MediaSessionConnector.QueueNavigator {
|
||||
override fun onSkipToQueueItem(player: Player, controlDispatcher: ControlDispatcher, id: Long) {
|
||||
override fun onSkipToQueueItem(player: Player, id: Long) {
|
||||
CommandBus.send(Command.PlayTrack(id.toInt()))
|
||||
}
|
||||
|
||||
override fun onCurrentWindowIndexChanged(player: Player) {}
|
||||
override fun onCurrentMediaItemIndexChanged(player: Player) {}
|
||||
|
||||
override fun onCommand(player: Player, controlDispatcher: ControlDispatcher, command: String, extras: Bundle?, cb: ResultReceiver?) = true
|
||||
override fun onCommand(player: Player, command: String, extras: Bundle?, cb: ResultReceiver?) =
|
||||
true
|
||||
|
||||
override fun getSupportedQueueNavigatorActions(player: Player): Long {
|
||||
return PlaybackStateCompat.ACTION_PLAY_PAUSE or
|
||||
|
@ -82,13 +82,13 @@ class FFAQueueNavigator : MediaSessionConnector.QueueNavigator {
|
|||
PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM
|
||||
}
|
||||
|
||||
override fun onSkipToNext(player: Player, controlDispatcher: ControlDispatcher) {
|
||||
override fun onSkipToNext(player: Player) {
|
||||
CommandBus.send(Command.NextTrack)
|
||||
}
|
||||
|
||||
override fun getActiveQueueItemId(player: Player?) = player?.currentWindowIndex?.toLong() ?: 0
|
||||
|
||||
override fun onSkipToPrevious(player: Player, controlDispatcher: ControlDispatcher) {
|
||||
override fun onSkipToPrevious(player: Player) {
|
||||
CommandBus.send(Command.PreviousTrack)
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,10 @@ class PinService : DownloadService(AppContext.NOTIFICATION_DOWNLOADS) {
|
|||
|
||||
override fun getScheduler(): Scheduler? = null
|
||||
|
||||
override fun getForegroundNotification(downloads: MutableList<Download>): Notification {
|
||||
override fun getForegroundNotification(
|
||||
downloads: MutableList<Download>,
|
||||
notMetRequirements: Int
|
||||
): Notification {
|
||||
val description =
|
||||
resources.getQuantityString(R.plurals.downloads_description, downloads.size, downloads.size)
|
||||
|
||||
|
|
|
@ -31,11 +31,10 @@ import audio.funkwhale.ffa.utils.log
|
|||
import audio.funkwhale.ffa.utils.maybeNormalizeUrl
|
||||
import audio.funkwhale.ffa.utils.onApi
|
||||
import com.google.android.exoplayer2.C
|
||||
import com.google.android.exoplayer2.ExoPlaybackException
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
|
||||
import com.google.android.exoplayer2.Tracks
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
|
@ -43,7 +42,6 @@ import kotlinx.coroutines.Dispatchers.Main
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koin.java.KoinJavaComponent.inject
|
||||
|
@ -136,6 +134,7 @@ class PlayerService : Service() {
|
|||
playWhenReady = false
|
||||
|
||||
playerEventListener = PlayerEventListener().also {
|
||||
|
||||
addListener(it)
|
||||
}
|
||||
}
|
||||
|
@ -419,9 +418,9 @@ class PlayerService : Service() {
|
|||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
inner class PlayerEventListener : Player.EventListener {
|
||||
inner class PlayerEventListener : Player.Listener {
|
||||
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
||||
super.onPlayerStateChanged(playWhenReady, playbackState)
|
||||
super.onPlayWhenReadyChanged(playWhenReady, playbackState)
|
||||
|
||||
EventBus.send(Event.StateChanged(playWhenReady))
|
||||
|
||||
|
@ -469,14 +468,11 @@ class PlayerService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onTracksChanged(
|
||||
trackGroups: TrackGroupArray,
|
||||
trackSelections: TrackSelectionArray
|
||||
) {
|
||||
super.onTracksChanged(trackGroups, trackSelections)
|
||||
override fun onTracksChanged(tracks: Tracks) {
|
||||
super.onTracksChanged(tracks)
|
||||
|
||||
if (queue.current != player.currentWindowIndex) {
|
||||
queue.current = player.currentWindowIndex
|
||||
if (queue.current != player.currentMediaItemIndex) {
|
||||
queue.current = player.currentMediaItemIndex
|
||||
mediaControlsManager.updateNotification(queue.current(), player.playWhenReady)
|
||||
}
|
||||
|
||||
|
@ -510,7 +506,7 @@ class PlayerService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onPlayerError(error: ExoPlaybackException) {
|
||||
override fun onPlayerError(error: PlaybackException) {
|
||||
EventBus.send(Event.PlaybackError(getString(R.string.error_playback)))
|
||||
|
||||
if (player.playWhenReady) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import audio.funkwhale.ffa.utils.FFACache
|
|||
import audio.funkwhale.ffa.utils.log
|
||||
import audio.funkwhale.ffa.utils.mustNormalizeUrl
|
||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||
import com.google.gson.Gson
|
||||
|
@ -37,9 +38,12 @@ class QueueManager(val context: Context) {
|
|||
dataSources.addMediaSources(
|
||||
metadata.map { track ->
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).setTag(track.title)
|
||||
.createMediaSource(Uri.parse(url))
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(
|
||||
MediaItem.Builder()
|
||||
.setTag(track.title)
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -63,8 +67,12 @@ class QueueManager(val context: Context) {
|
|||
val factory = cacheDataSourceFactoryProvider.create(context)
|
||||
val sources = tracks.map { track ->
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).setTag(track.title).createMediaSource(Uri.parse(url))
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(
|
||||
MediaItem.Builder()
|
||||
.setTag(track.title)
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
metadata = tracks.toMutableList()
|
||||
|
@ -84,7 +92,12 @@ class QueueManager(val context: Context) {
|
|||
val sources = missingTracks.map { track ->
|
||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url))
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(
|
||||
MediaItem.Builder()
|
||||
.setTag(track.title) // was this missing on purpose?!
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
metadata.addAll(tracks)
|
||||
|
@ -101,7 +114,12 @@ class QueueManager(val context: Context) {
|
|||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||
|
||||
if (metadata.indexOf(track) == -1) {
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.parse(url)).let {
|
||||
ProgressiveMediaSource.Factory(factory).createMediaSource(
|
||||
MediaItem.Builder()
|
||||
.setTag(track.title) // was this missing on purpose?!
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
).let {
|
||||
dataSources.addMediaSource(current + 1, it)
|
||||
metadata.add(current + 1, track)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ import audio.funkwhale.ffa.model.Track
|
|||
import audio.funkwhale.ffa.model.TracksCache
|
||||
import audio.funkwhale.ffa.model.TracksResponse
|
||||
import audio.funkwhale.ffa.utils.OAuth
|
||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||
import audio.funkwhale.ffa.utils.mustNormalizeUrl
|
||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||
import com.google.android.exoplayer2.offline.DownloadManager
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache
|
||||
import com.google.gson.reflect.TypeToken
|
||||
|
|
|
@ -7,8 +7,8 @@ import audio.funkwhale.ffa.model.TracksCache
|
|||
import audio.funkwhale.ffa.model.TracksResponse
|
||||
import audio.funkwhale.ffa.utils.OAuth
|
||||
import audio.funkwhale.ffa.utils.getMetadata
|
||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||
import audio.funkwhale.ffa.utils.mustNormalizeUrl
|
||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||
import com.google.android.exoplayer2.offline.Download
|
||||
import com.google.android.exoplayer2.offline.DownloadManager
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache
|
||||
|
|
|
@ -10,10 +10,8 @@ import audio.funkwhale.ffa.model.DownloadInfo
|
|||
import audio.funkwhale.ffa.repositories.Repository
|
||||
import com.github.kittinunf.fuel.core.FuelError
|
||||
import com.github.kittinunf.fuel.core.Request
|
||||
import com.github.kittinunf.fuel.core.ResponseDeserializable
|
||||
import com.google.android.exoplayer2.offline.Download
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.squareup.picasso.RequestCreator
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
|
@ -23,7 +21,6 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.openid.appauth.ClientSecretPost
|
||||
import java.io.Reader
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
|
|
@ -52,7 +52,7 @@ class NowPlayingView : MaterialCardView {
|
|||
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
gestureDetectorCallback = OnGestureDetection()
|
||||
gestureDetector = GestureDetector(context, gestureDetectorCallback)
|
||||
gestureDetector = GestureDetector(context, gestureDetectorCallback!!)
|
||||
|
||||
setOnTouchListener { _, motionEvent ->
|
||||
val ret = gestureDetector?.onTouchEvent(motionEvent) ?: false
|
||||
|
@ -128,8 +128,8 @@ class NowPlayingView : MaterialCardView {
|
|||
}
|
||||
|
||||
override fun onFling(
|
||||
firstMotionEvent: MotionEvent?,
|
||||
secondMotionEvent: MotionEvent?,
|
||||
firstMotionEvent: MotionEvent,
|
||||
secondMotionEvent: MotionEvent,
|
||||
velocityX: Float,
|
||||
velocityY: Float
|
||||
): Boolean {
|
||||
|
@ -195,7 +195,7 @@ class NowPlayingView : MaterialCardView {
|
|||
return true
|
||||
}
|
||||
|
||||
override fun onSingleTapUp(e: MotionEvent?): Boolean {
|
||||
override fun onSingleTapUp(e: MotionEvent): Boolean {
|
||||
layoutParams.let {
|
||||
if (height != minHeight) return true
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue