all: switch to media3
Move everything over to the media3 library instead of ExoPlayer. Media3 is worse in every way. It labels half of ExoPlayer as "unsafe" because it thinks that it's garbage uwu "helpful" abstractions are perfectly servicable when in reality they are a pile of garbage filled with insane performance issues, race conditions, and a seeming lack of awareness to the sheer absurdity of android's media APIs. It is absolutely horrible, but ExoPlayer will stop being maintained soon and I will have to move over for further maintenance.
This commit is contained in:
parent
c6c3816bfc
commit
c1e4d0f10e
16 changed files with 175 additions and 126 deletions
7
.gitmodules
vendored
7
.gitmodules
vendored
|
@ -1,4 +1,3 @@
|
|||
[submodule "ExoPlayer"]
|
||||
path = ExoPlayer
|
||||
url = https://github.com/OxygenCobalt/ExoPlayer.git
|
||||
branch = auxio
|
||||
[submodule "media"]
|
||||
path = media
|
||||
url = https://github.com/OxygenCobalt/media.git
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## dev
|
||||
|
||||
#### What's Fixed
|
||||
- Fixed issue where vorbis comments in the form of `metadata_block_picture` (lowercase) would not
|
||||
be parsed as images
|
||||
|
||||
## 3.0.5
|
||||
|
||||
#### What's Fixed
|
||||
- Fixed inconsistent corner radius on widget
|
||||
- Fixed crash that would occur due to intelligent sort name functionality
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit fef2bb3af622f235d98549ffe2efd8f7f7d2aa41
|
|
@ -119,8 +119,8 @@ dependencies {
|
|||
// --- THIRD PARTY ---
|
||||
|
||||
// Exoplayer (Vendored)
|
||||
implementation project(":exoplayer-library-core")
|
||||
implementation project(":exoplayer-extension-ffmpeg")
|
||||
implementation project(":media-lib-exoplayer")
|
||||
implementation project(":media-lib-decoder-ffmpeg")
|
||||
|
||||
// Image loading
|
||||
implementation 'io.coil-kt:coil-base:2.2.2'
|
||||
|
|
|
@ -18,16 +18,10 @@
|
|||
|
||||
package org.oxycblt.auxio.image
|
||||
|
||||
import android.content.Context
|
||||
import coil.ImageLoader
|
||||
import coil.request.CachePolicy
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
import org.oxycblt.auxio.image.extractor.*
|
||||
|
||||
@Module
|
||||
|
@ -35,33 +29,3 @@ import org.oxycblt.auxio.image.extractor.*
|
|||
interface ImageModule {
|
||||
@Binds fun settings(imageSettings: ImageSettingsImpl): ImageSettings
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class CoilModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun imageLoader(
|
||||
@ApplicationContext context: Context,
|
||||
songFactory: AlbumCoverFetcher.SongFactory,
|
||||
albumFactory: AlbumCoverFetcher.AlbumFactory,
|
||||
artistFactory: ArtistImageFetcher.Factory,
|
||||
genreFactory: GenreImageFetcher.Factory,
|
||||
playlistFactory: PlaylistImageFetcher.Factory
|
||||
) =
|
||||
ImageLoader.Builder(context)
|
||||
.components {
|
||||
// Add fetchers for Music components to make them usable with ImageRequest
|
||||
add(MusicKeyer())
|
||||
add(songFactory)
|
||||
add(albumFactory)
|
||||
add(artistFactory)
|
||||
add(genreFactory)
|
||||
add(playlistFactory)
|
||||
}
|
||||
// Use our own crossfade with error drawable support
|
||||
.transitionFactory(ErrorCrossfadeTransitionFactory())
|
||||
// Not downloading anything, so no disk-caching
|
||||
.diskCachePolicy(CachePolicy.DISABLED)
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ package org.oxycblt.auxio.image.extractor
|
|||
|
||||
import android.content.Context
|
||||
import android.media.MediaMetadataRetriever
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.MediaMetadata
|
||||
import com.google.android.exoplayer2.MetadataRetriever
|
||||
import com.google.android.exoplayer2.metadata.flac.PictureFrame
|
||||
import com.google.android.exoplayer2.metadata.id3.ApicFrame
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.exoplayer.MetadataRetriever
|
||||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import androidx.media3.extractor.metadata.flac.PictureFrame
|
||||
import androidx.media3.extractor.metadata.id3.ApicFrame
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.InputStream
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
* ExtractorModule.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.image.extractor
|
||||
|
||||
import android.content.Context
|
||||
import coil.ImageLoader
|
||||
import coil.request.CachePolicy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class ExtractorModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun imageLoader(
|
||||
@ApplicationContext context: Context,
|
||||
songFactory: AlbumCoverFetcher.SongFactory,
|
||||
albumFactory: AlbumCoverFetcher.AlbumFactory,
|
||||
artistFactory: ArtistImageFetcher.Factory,
|
||||
genreFactory: GenreImageFetcher.Factory,
|
||||
playlistFactory: PlaylistImageFetcher.Factory
|
||||
) =
|
||||
ImageLoader.Builder(context)
|
||||
.components {
|
||||
// Add fetchers for Music components to make them usable with ImageRequest
|
||||
add(MusicKeyer())
|
||||
add(songFactory)
|
||||
add(albumFactory)
|
||||
add(artistFactory)
|
||||
add(genreFactory)
|
||||
add(playlistFactory)
|
||||
}
|
||||
// Use our own crossfade with error drawable support
|
||||
.transitionFactory(ErrorCrossfadeTransitionFactory())
|
||||
// Not downloading anything, so no disk-caching
|
||||
.diskCachePolicy(CachePolicy.DISABLED)
|
||||
.build()
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
package org.oxycblt.auxio.music.metadata
|
||||
|
||||
import com.google.android.exoplayer2.MetadataRetriever
|
||||
import androidx.media3.exoplayer.MetadataRetriever
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.yield
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
package org.oxycblt.auxio.music.metadata
|
||||
|
||||
import androidx.core.text.isDigitsOnly
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.MetadataRetriever
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.exoplayer.MetadataRetriever
|
||||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import androidx.media3.exoplayer.source.TrackGroupArray
|
||||
import java.util.concurrent.Future
|
||||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.music.device.RawSong
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
|
||||
package org.oxycblt.auxio.music.metadata
|
||||
|
||||
import com.google.android.exoplayer2.metadata.Metadata
|
||||
import com.google.android.exoplayer2.metadata.id3.InternalFrame
|
||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame
|
||||
import com.google.android.exoplayer2.metadata.vorbis.VorbisComment
|
||||
import androidx.media3.common.Metadata
|
||||
import androidx.media3.extractor.metadata.id3.InternalFrame
|
||||
import androidx.media3.extractor.metadata.id3.TextInformationFrame
|
||||
import androidx.media3.extractor.metadata.vorbis.VorbisComment
|
||||
|
||||
/**
|
||||
* Processing wrapper for [Metadata] that allows organized access to text-based audio tags.
|
||||
|
|
|
@ -18,25 +18,9 @@
|
|||
|
||||
package org.oxycblt.auxio.playback
|
||||
|
||||
import android.content.Context
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory
|
||||
import com.google.android.exoplayer2.extractor.flac.FlacExtractor
|
||||
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor
|
||||
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor
|
||||
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor
|
||||
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor
|
||||
import com.google.android.exoplayer2.extractor.ogg.OggExtractor
|
||||
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor
|
||||
import com.google.android.exoplayer2.extractor.wav.WavExtractor
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||
import com.google.android.exoplayer2.upstream.ContentDataSource
|
||||
import com.google.android.exoplayer2.upstream.DataSource
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||
|
@ -50,35 +34,3 @@ interface PlaybackModule {
|
|||
fun stateManager(playbackManager: PlaybackStateManagerImpl): PlaybackStateManager
|
||||
@Binds fun settings(playbackSettings: PlaybackSettingsImpl): PlaybackSettings
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class ExoPlayerModule {
|
||||
@Provides
|
||||
fun mediaSourceFactory(
|
||||
dataSourceFactory: DataSource.Factory,
|
||||
extractorsFactory: ExtractorsFactory
|
||||
): MediaSource.Factory = ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
|
||||
|
||||
@Provides
|
||||
fun dataSourceFactory(@ApplicationContext context: Context) =
|
||||
// We only ever open conte tURIs, so only provide those data sources.
|
||||
DataSource.Factory { ContentDataSource(context) }
|
||||
|
||||
@Provides
|
||||
fun extractorsFactory() = ExtractorsFactory {
|
||||
// Define our own extractors so we can exclude non-audio parsers.
|
||||
// Ordering is derived from the DefaultExtractorsFactory's optimized ordering:
|
||||
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ.
|
||||
arrayOf(
|
||||
FlacExtractor(),
|
||||
WavExtractor(),
|
||||
FragmentedMp4Extractor(),
|
||||
Mp4Extractor(),
|
||||
OggExtractor(),
|
||||
MatroskaExtractor(),
|
||||
// Enable constant bitrate seeking so that certain MP3s/AACs are seekable
|
||||
AdtsExtractor(AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
|
||||
Mp3Extractor(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
package org.oxycblt.auxio.playback.replaygain
|
||||
|
||||
import com.google.android.exoplayer2.C
|
||||
import com.google.android.exoplayer2.Format
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.Tracks
|
||||
import com.google.android.exoplayer2.audio.AudioProcessor
|
||||
import com.google.android.exoplayer2.audio.BaseAudioProcessor
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.Format
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.Tracks
|
||||
import androidx.media3.common.audio.AudioProcessor
|
||||
import androidx.media3.exoplayer.audio.BaseAudioProcessor
|
||||
import java.nio.ByteBuffer
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.pow
|
||||
|
|
|
@ -26,18 +26,14 @@ import android.content.IntentFilter
|
|||
import android.media.AudioManager
|
||||
import android.media.audiofx.AudioEffect
|
||||
import android.os.IBinder
|
||||
import com.google.android.exoplayer2.C
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.RenderersFactory
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes
|
||||
import com.google.android.exoplayer2.audio.AudioCapabilities
|
||||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer
|
||||
import com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import androidx.media3.common.*
|
||||
import androidx.media3.decoder.ffmpeg.FfmpegAudioRenderer
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.exoplayer.RenderersFactory
|
||||
import androidx.media3.exoplayer.audio.AudioCapabilities
|
||||
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer
|
||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector
|
||||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
* SystemModule.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.playback.system
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.datasource.ContentDataSource
|
||||
import androidx.media3.datasource.DataSource
|
||||
import androidx.media3.exoplayer.source.MediaSource
|
||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
||||
import androidx.media3.extractor.ExtractorsFactory
|
||||
import androidx.media3.extractor.flac.FlacExtractor
|
||||
import androidx.media3.extractor.mkv.MatroskaExtractor
|
||||
import androidx.media3.extractor.mp3.Mp3Extractor
|
||||
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
|
||||
import androidx.media3.extractor.mp4.Mp4Extractor
|
||||
import androidx.media3.extractor.ogg.OggExtractor
|
||||
import androidx.media3.extractor.ts.AdtsExtractor
|
||||
import androidx.media3.extractor.wav.WavExtractor
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class SystemModule {
|
||||
@Provides
|
||||
fun mediaSourceFactory(
|
||||
dataSourceFactory: DataSource.Factory,
|
||||
extractorsFactory: ExtractorsFactory
|
||||
): MediaSource.Factory = ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
|
||||
|
||||
@Provides
|
||||
fun dataSourceFactory(@ApplicationContext context: Context) =
|
||||
// We only ever open conte tURIs, so only provide those data sources.
|
||||
DataSource.Factory { ContentDataSource(context) }
|
||||
|
||||
@Provides
|
||||
fun extractorsFactory() = ExtractorsFactory {
|
||||
// Define our own extractors so we can exclude non-audio parsers.
|
||||
// Ordering is derived from the DefaultExtractorsFactory's optimized ordering:
|
||||
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ.
|
||||
arrayOf(
|
||||
FlacExtractor(),
|
||||
WavExtractor(),
|
||||
FragmentedMp4Extractor(),
|
||||
Mp4Extractor(),
|
||||
OggExtractor(),
|
||||
MatroskaExtractor(),
|
||||
// Enable constant bitrate seeking so that certain MP3s/AACs are seekable
|
||||
AdtsExtractor(AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
|
||||
Mp3Extractor(Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING))
|
||||
}
|
||||
}
|
1
media
Submodule
1
media
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e01f3be069d30d933f3812cf3b51ece791d67510
|
|
@ -1,4 +1,4 @@
|
|||
include ':app'
|
||||
rootProject.name = "Auxio"
|
||||
gradle.ext.exoplayerModulePrefix = 'exoplayer-'
|
||||
apply from: file("ExoPlayer/core_settings.gradle")
|
||||
gradle.ext.androidxMediaModulePrefix = 'media-'
|
||||
apply from: file("media/core_settings.gradle")
|
Loading…
Reference in a new issue