diff --git a/.gitmodules b/.gitmodules index e806f30bf..552a758f6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f777a97..53b3d8295 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/ExoPlayer b/ExoPlayer deleted file mode 160000 index fef2bb3af..000000000 --- a/ExoPlayer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fef2bb3af622f235d98549ffe2efd8f7f7d2aa41 diff --git a/app/build.gradle b/app/build.gradle index 8870a165b..7f77e603d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt b/app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt index c73af2c73..b3bb1cf2f 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/ImageModule.kt @@ -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() -} diff --git a/app/src/main/java/org/oxycblt/auxio/image/extractor/CoverExtractor.kt b/app/src/main/java/org/oxycblt/auxio/image/extractor/CoverExtractor.kt index 1c2bb113d..83bd50fd5 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/extractor/CoverExtractor.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/extractor/CoverExtractor.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/image/extractor/ExtractorModule.kt b/app/src/main/java/org/oxycblt/auxio/image/extractor/ExtractorModule.kt new file mode 100644 index 000000000..91adba89e --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/image/extractor/ExtractorModule.kt @@ -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 . + */ + +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() +} diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt index 60586d9ee..7e31400ff 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt index 1a553211c..2a096c789 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TextTags.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TextTags.kt index 9b486c623..cecd572ba 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TextTags.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TextTags.kt @@ -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. diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackModule.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackModule.kt index 55233002d..36fb9a0ee 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackModule.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackModule.kt @@ -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)) - } -} diff --git a/app/src/main/java/org/oxycblt/auxio/playback/replaygain/ReplayGainAudioProcessor.kt b/app/src/main/java/org/oxycblt/auxio/playback/replaygain/ReplayGainAudioProcessor.kt index e9015c8d5..fafe5266c 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/replaygain/ReplayGainAudioProcessor.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/replaygain/ReplayGainAudioProcessor.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index a03f231fd..e6ae6a8d0 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/SystemModule.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/SystemModule.kt new file mode 100644 index 000000000..47b052761 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/SystemModule.kt @@ -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 . + */ + +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)) + } +} diff --git a/media b/media new file mode 160000 index 000000000..e01f3be06 --- /dev/null +++ b/media @@ -0,0 +1 @@ +Subproject commit e01f3be069d30d933f3812cf3b51ece791d67510 diff --git a/settings.gradle b/settings.gradle index df2dcbd45..4595c06e6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ include ':app' rootProject.name = "Auxio" -gradle.ext.exoplayerModulePrefix = 'exoplayer-' -apply from: file("ExoPlayer/core_settings.gradle") \ No newline at end of file +gradle.ext.androidxMediaModulePrefix = 'media-' +apply from: file("media/core_settings.gradle") \ No newline at end of file