Wraps the existing Activity-owned ExoPlayer in a Media3 MediaSession. Side effects: - Lock-screen media controls (play/pause) - System media notification with play/pause buttons - Audio focus + ducking (other audio dims when straw plays) - Bluetooth + headset hardware-button routing - Plays nicely alongside other media apps' notifications The ExoPlayer is also configured with AudioAttributes (USAGE_MEDIA + CONTENT_TYPE_MOVIE) and handleAudioFocus=true so other apps can request focus correctly (e.g., a phone call ducks/pauses straw). Also scaffolded but NOT yet wired: - PlaybackService extending MediaSessionService — the foundation for true background-after-Activity-kill audio. Manifest entry + deps added (media3-session 1.4.1, concurrent-futures-ktx 1.2.0). The Activity-to-Service migration via MediaController is M-3 work. - POST_NOTIFICATIONS, FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK, WAKE_LOCK permissions in manifest. For the user right now: lock the phone while a video plays — media controls appear on the lock screen. Open another app — notification with play/pause sits in the shade. Press a headset's play/pause — straw responds. Pull the home screen — PiP keeps the video floating + audio continues. Full screen-off-background-audio after killing the activity arrives in M-3.
113 lines
3.6 KiB
Kotlin
113 lines
3.6 KiB
Kotlin
/*
|
|
* SPDX-FileCopyrightText: 2026 Sulkta-Coop
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* :strawApp — thin Android application shell. Day-2: pulls NewPipeExtractor,
|
|
* Media3, Ktor-style HTTP-via-OkHttp + kotlinx-serialization JSON for the
|
|
* search → detail → player → SponsorBlock + RYD flow. We keep our deps in
|
|
* this module, NOT in the shared libs.versions.toml, so upstream NewPipe
|
|
* stays cleanly mergeable.
|
|
*/
|
|
|
|
import com.android.build.api.dsl.ApplicationExtension
|
|
|
|
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.jetbrains.kotlin.compose)
|
|
alias(libs.plugins.jetbrains.kotlinx.serialization)
|
|
}
|
|
|
|
kotlin {
|
|
jvmToolchain(21)
|
|
}
|
|
|
|
configure<ApplicationExtension> {
|
|
compileSdk {
|
|
version = release(NEWPIPE_VERSION_SDK_COMPILE_MAJOR) {
|
|
minorApiLevel = NEWPIPE_VERSION_SDK_COMPILE_MINOR
|
|
}
|
|
}
|
|
namespace = STRAW_APPLICATION_ID
|
|
|
|
defaultConfig {
|
|
applicationId = STRAW_APPLICATION_ID
|
|
minSdk { version = release(24) }
|
|
targetSdk { version = release(NEWPIPE_VERSION_SDK_TARGET) }
|
|
versionCode = STRAW_VERSION_CODE
|
|
versionName = STRAW_VERSION_NAME
|
|
resValue("string", "app_name", "Straw")
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
isDebuggable = true
|
|
applicationIdSuffix = ".debug"
|
|
resValue("string", "app_name", "Straw debug")
|
|
}
|
|
release {
|
|
isMinifyEnabled = false
|
|
}
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility = JavaVersion.VERSION_21
|
|
targetCompatibility = JavaVersion.VERSION_21
|
|
}
|
|
|
|
buildFeatures {
|
|
compose = true
|
|
buildConfig = true
|
|
resValues = true
|
|
}
|
|
|
|
packaging {
|
|
resources {
|
|
excludes += setOf(
|
|
"META-INF/README.md",
|
|
"META-INF/CHANGES",
|
|
"META-INF/COPYRIGHT",
|
|
"META-INF/INDEX.LIST",
|
|
"META-INF/io.netty.versions.properties",
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
// Compose + AndroidX core
|
|
implementation(libs.androidx.activity)
|
|
implementation(libs.androidx.core)
|
|
implementation(libs.jetbrains.compose.runtime)
|
|
implementation(libs.jetbrains.compose.foundation)
|
|
implementation(libs.jetbrains.compose.material3)
|
|
implementation(libs.jetbrains.compose.ui)
|
|
implementation("androidx.compose.material:material-icons-core:1.7.5")
|
|
|
|
// Lifecycle + ViewModel for Compose
|
|
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")
|
|
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.10.0")
|
|
|
|
// Coroutines
|
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0")
|
|
|
|
// Image loading
|
|
implementation(libs.coil.compose)
|
|
implementation(libs.coil.network.okhttp)
|
|
|
|
// NewPipeExtractor (JVM/Android-only) + its OkHttp dep
|
|
implementation(libs.newpipe.extractor)
|
|
implementation(libs.squareup.okhttp)
|
|
|
|
// JSON for SponsorBlock + Return YouTube Dislike clients
|
|
implementation(libs.kotlinx.serialization.json)
|
|
|
|
// Media3 ExoPlayer
|
|
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
|
implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
|
implementation("androidx.media3:media3-exoplayer-hls:1.4.1")
|
|
implementation("androidx.media3:media3-ui:1.4.1")
|
|
// Media3 session — MediaSessionService for background audio + lock-screen controls.
|
|
implementation("androidx.media3:media3-session:1.4.1")
|
|
// Guava ListenableFuture support for awaiting MediaController connect.
|
|
implementation("androidx.concurrent:concurrent-futures-ktx:1.2.0")
|
|
}
|