playback: switch to ffmpeg extension
Switch to the FFMpeg ExoPlayer extension, which should enable support for ALAC while also retaining support for FLAC below Android 8.
This commit is contained in:
parent
c9ddda2ebd
commit
213409924b
15 changed files with 40 additions and 33 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
#### What's New
|
||||
- Added support for disc subtitles
|
||||
- Added support for ALAC files
|
||||
|
||||
#### What's Improved
|
||||
- Auxio will now accept zeroed track/disc numbers in the presence of non-zero total
|
||||
|
@ -11,6 +12,7 @@ track/disc fields
|
|||
- Music loading has been made slightly faster
|
||||
- Improved sort menu usability
|
||||
- Fall back to `TXXX:RELEASETYPE` on ID3v2 files
|
||||
- Switches and checkboxes have been mildly visually refreshed
|
||||
|
||||
#### What's Fixed
|
||||
- Fixed non-functioning "repeat all" repeat mode
|
||||
|
|
|
@ -127,7 +127,6 @@ dependencies {
|
|||
kapt "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
implementation "com.google.dagger:hilt-android:$hilt_version"
|
||||
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
|
||||
|
||||
// Testing
|
||||
debugImplementation "com.squareup.leakcanary:leakcanary-android:2.9.1"
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
|
|
|
@ -47,13 +47,13 @@ interface CachedSongsDao {
|
|||
@TypeConverters(CachedSong.Converters::class)
|
||||
data class CachedSong(
|
||||
/**
|
||||
* The ID of the [Song]'s audio file, obtained from MediaStore. Note that this ID is highly
|
||||
* The ID of the [RawSong]'s audio file, obtained from MediaStore. Note that this ID is highly
|
||||
* unstable and should only be used for accessing the audio file.
|
||||
*/
|
||||
@PrimaryKey var mediaStoreId: Long,
|
||||
/** @see RawSong.dateAdded */
|
||||
var dateAdded: Long,
|
||||
/** The latest date the [Song]'s audio file was modified, as a unix epoch timestamp. */
|
||||
/** The latest date the [RawSong]'s audio file was modified, as a unix epoch timestamp. */
|
||||
var dateModified: Long,
|
||||
/** @see RawSong.size */
|
||||
var size: Long? = null,
|
||||
|
|
|
@ -26,8 +26,6 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
import org.oxycblt.auxio.music.extractor.CacheRepository
|
||||
import org.oxycblt.auxio.music.extractor.CacheRepositoryImpl
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
|
|
|
@ -15,11 +15,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.music.extractor
|
||||
package org.oxycblt.auxio.music.cache
|
||||
|
||||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.music.cache.CachedSong
|
||||
import org.oxycblt.auxio.music.cache.CachedSongsDao
|
||||
import org.oxycblt.auxio.music.model.RawSong
|
||||
import org.oxycblt.auxio.util.*
|
||||
|
||||
|
|
|
@ -157,6 +157,8 @@ data class MimeType(val fromExtension: String, val fromFormat: String?) {
|
|||
MediaFormat.MIMETYPE_AUDIO_VORBIS -> R.string.cdc_vorbis
|
||||
MediaFormat.MIMETYPE_AUDIO_OPUS -> R.string.cdc_opus
|
||||
MediaFormat.MIMETYPE_AUDIO_FLAC -> R.string.cdc_flac
|
||||
// TODO: Add ALAC to this as soon as I can stop using MediaFormat for
|
||||
// extracting metadata and just use ExoPlayer.
|
||||
// We don't give a name to more unpopular formats.
|
||||
else -> -1
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.io.File
|
|||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.yield
|
||||
import org.oxycblt.auxio.music.MusicSettings
|
||||
import org.oxycblt.auxio.music.extractor.Cache
|
||||
import org.oxycblt.auxio.music.cache.Cache
|
||||
import org.oxycblt.auxio.music.metadata.Date
|
||||
import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
|
||||
import org.oxycblt.auxio.music.metadata.transformPositionField
|
||||
|
|
|
@ -35,7 +35,7 @@ import kotlinx.coroutines.withContext
|
|||
import kotlinx.coroutines.yield
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.auxio.music.*
|
||||
import org.oxycblt.auxio.music.extractor.*
|
||||
import org.oxycblt.auxio.music.cache.CacheRepository
|
||||
import org.oxycblt.auxio.music.metadata.TagExtractor
|
||||
import org.oxycblt.auxio.music.model.Library
|
||||
import org.oxycblt.auxio.music.model.RawSong
|
||||
|
|
|
@ -56,8 +56,10 @@ import org.oxycblt.auxio.util.logD
|
|||
*/
|
||||
@AndroidEntryPoint
|
||||
class IndexerService : Service(), Indexer.Controller, MusicSettings.Listener {
|
||||
@Inject lateinit var indexer: Indexer
|
||||
@Inject lateinit var imageLoader: ImageLoader
|
||||
@Inject lateinit var musicRepository: MusicRepository
|
||||
@Inject lateinit var indexer: Indexer
|
||||
@Inject lateinit var musicSettings: MusicSettings
|
||||
@Inject lateinit var playbackManager: PlaybackStateManager
|
||||
private val serviceJob = Job()
|
||||
private val indexScope = CoroutineScope(serviceJob + Dispatchers.IO)
|
||||
|
@ -67,8 +69,6 @@ class IndexerService : Service(), Indexer.Controller, MusicSettings.Listener {
|
|||
private lateinit var observingNotification: ObservingNotification
|
||||
private lateinit var wakeLock: PowerManager.WakeLock
|
||||
private lateinit var indexerContentObserver: SystemContentObserver
|
||||
@Inject lateinit var musicSettings: MusicSettings
|
||||
@Inject lateinit var imageLoader: ImageLoader
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
|
|
@ -34,7 +34,7 @@ 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.flac.LibflacAudioRenderer
|
||||
import com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
|
||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
||||
|
@ -128,7 +128,7 @@ class PlaybackService :
|
|||
audioListener,
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES,
|
||||
replayGainProcessor),
|
||||
LibflacAudioRenderer(handler, audioListener, replayGainProcessor))
|
||||
FfmpegAudioRenderer(handler, audioListener, replayGainProcessor))
|
||||
}
|
||||
|
||||
player =
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.content.Context
|
|||
import android.util.AttributeSet
|
||||
import androidx.annotation.AttrRes
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.util.fixDoubleRipple
|
||||
|
||||
/**
|
||||
|
@ -30,8 +31,11 @@ import org.oxycblt.auxio.util.fixDoubleRipple
|
|||
*/
|
||||
open class RippleFixMaterialButton
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
|
||||
MaterialButton(context, attrs, defStyleAttr) {
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@AttrRes defStyleAttr: Int = R.attr.materialButtonStyle
|
||||
) : MaterialButton(context, attrs, defStyleAttr) {
|
||||
init {
|
||||
fixDoubleRipple()
|
||||
}
|
||||
|
|
|
@ -196,7 +196,6 @@ class WidgetProvider : AppWidgetProvider() {
|
|||
/**
|
||||
* Set up the control bar in a [RemoteViews] layout that contains one. This is a kind of
|
||||
* "floating" drawable that sits in front of the cover and contains the controls.
|
||||
* @param context [Context] required to set up the view.
|
||||
*/
|
||||
private fun RemoteViews.setupBar(): RemoteViews {
|
||||
// Below API 31, enable a rounded bar only if round mode is enabled.
|
||||
|
@ -214,7 +213,6 @@ class WidgetProvider : AppWidgetProvider() {
|
|||
/**
|
||||
* Set up the background in a [RemoteViews] layout that contains one. This is largely
|
||||
* self-explanatory, being a solid-color background that sits behind the cover and controls.
|
||||
* @param context [Context] required to set up the view.
|
||||
*/
|
||||
private fun RemoteViews.setupBackground(): RemoteViews {
|
||||
// Below API 31, enable a rounded background only if round mode is enabled.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.materialswitch.MaterialSwitch xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/switchWidget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
|
@ -5,6 +5,7 @@
|
|||
<style name="Widget.Auxio.AppBarLayout" parent="Widget.Material3.AppBarLayout">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<!-- Fix flickering lift animation when scrolling quickly -->
|
||||
<item name="android:stateListAnimator">@null</item>
|
||||
</style>
|
||||
|
||||
|
|
32
prebuild.py
32
prebuild.py
|
@ -17,10 +17,8 @@ import sys
|
|||
import subprocess
|
||||
import re
|
||||
|
||||
# WARNING: THE EXOPLAYER VERSION MUST BE KEPT IN LOCK-STEP WITH THE FLAC EXTENSION AND
|
||||
# WARNING: THE EXOPLAYER VERSION MUST BE KEPT IN LOCK-STEP WITH THE FFMPEG EXTENSION AND
|
||||
# THE GRADLE DEPENDENCY. IF NOT, VERY UNFRIENDLY BUILD FAILURES AND CRASHES MAY ENSUE.
|
||||
# EXO_VERSION = "2.18.2"
|
||||
FLAC_VERSION = "1.3.2"
|
||||
|
||||
OK="\033[1;32m" # Bold green
|
||||
FATAL="\033[1;31m" # Bold red
|
||||
|
@ -102,18 +100,26 @@ sh("git clone https://github.com/OxygenCobalt/ExoPlayer.git " + exoplayer_path)
|
|||
os.chdir(exoplayer_path)
|
||||
sh("git checkout auxio")
|
||||
|
||||
print(INFO + "info:" + NC + " assembling flac extension...")
|
||||
flac_ext_aar_path = os.path.join(exoplayer_path, "extensions", "flac",
|
||||
"buildout", "outputs", "aar", "extension-flac-release.aar")
|
||||
flac_ext_jni_path = os.path.join("extensions", "flac", "src", "main", "jni")
|
||||
print(INFO + "info:" + NC + " assembling ffmpeg extension...")
|
||||
if system == "Linux":
|
||||
host = "linux-x86_64"
|
||||
elif system == "Darwin":
|
||||
host = "darwin-x86_64"
|
||||
|
||||
os.chdir(flac_ext_jni_path)
|
||||
sh('curl "https://ftp.osuosl.org/pub/xiph/releases/flac/flac-' + FLAC_VERSION +
|
||||
'.tar.xz" | tar xJ && mv "flac-' + FLAC_VERSION + '" flac')
|
||||
sh(ndk_build_path + " APP_ABI=all -j4")
|
||||
ffmpeg_ext_path = os.path.join(exoplayer_path, "extensions", "ffmpeg", "src", "main")
|
||||
ffmpeg_ext_aar_path = os.path.join(exoplayer_path, "extensions", "ffmpeg", "buildout", "outputs", "aar", "extension-ffmpeg-release.aar")
|
||||
ffmpeg_ext_jni_path = os.path.join(exoplayer_path, "extensions", "ffmpeg", "src", "main", "jni")
|
||||
ffmpeg_src_path = os.path.join(ffmpeg_ext_jni_path, "ffmpeg")
|
||||
|
||||
os.chdir(ffmpeg_ext_jni_path)
|
||||
sh("git clone git://source.ffmpeg.org/ffmpeg ffmpeg")
|
||||
os.chdir(ffmpeg_src_path)
|
||||
sh("git checkout release/4.2")
|
||||
os.chdir(ffmpeg_ext_jni_path)
|
||||
sh('./build_ffmpeg.sh "' + ffmpeg_ext_path + '" "' + ndk_path + '" "' + host + '" "' + "flac" + '" "' + "alac" + '"')
|
||||
|
||||
os.chdir(exoplayer_path)
|
||||
sh("./gradlew extension-flac:bundleReleaseAar")
|
||||
sh("./gradlew extension-ffmpeg:bundleReleaseAar")
|
||||
|
||||
print(INFO + "info:" + NC + " assembling extractor component...")
|
||||
|
||||
|
@ -124,7 +130,7 @@ sh("./gradlew library-extractor:bundleReleaseAar")
|
|||
|
||||
os.chdir(start_path)
|
||||
sh("mkdir " + libs_path)
|
||||
sh("cp " + flac_ext_aar_path + " " + libs_path)
|
||||
sh("cp " + ffmpeg_ext_aar_path + " " + libs_path)
|
||||
sh("cp " + extractor_aar_path + " " + libs_path)
|
||||
|
||||
print(OK + "success:" + NC + " completed pre-build")
|
||||
|
|
Loading…
Reference in a new issue