mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Update wholphin-extensions with newer MpvPlayer
This commit is contained in:
parent
b23d30f94b
commit
fda24f31b1
10 changed files with 38 additions and 1635 deletions
|
|
@ -20,12 +20,21 @@ plugins {
|
|||
alias(libs.plugins.openapi.generator)
|
||||
}
|
||||
|
||||
val isCI = if (System.getenv("CI") != null) System.getenv("CI").toBoolean() else false
|
||||
val shouldSign = isCI && System.getenv("KEY_ALIAS") != null
|
||||
val ffmpegModuleExists = project.file("libs/lib-decoder-ffmpeg-release.aar").exists()
|
||||
val av1ModuleExists = project.file("libs/lib-decoder-av1-release.aar").exists()
|
||||
val mpvModuleExists = project.file("libs/wholphin-mpv-release.aar").exists()
|
||||
val extensionsRepoActive = project.hasProperty("WholphinExtensionsUsername")
|
||||
val isCI = providers.systemProperty("CI").orElse("false").map { it.toBoolean() }
|
||||
val shouldSign =
|
||||
isCI.zip(
|
||||
providers.systemProperty("KEY_ALIAS").orElse("").map { it.isNotBlank() },
|
||||
) { isCI, hasKey ->
|
||||
isCI && hasKey
|
||||
}
|
||||
val ffmpegModuleExists =
|
||||
providers.provider { project.file("libs/lib-decoder-ffmpeg-release.aar").exists() }
|
||||
val av1ModuleExists =
|
||||
providers.provider { project.file("libs/lib-decoder-av1-release.aar").exists() }
|
||||
val mpvModuleExists =
|
||||
providers.provider { project.file("libs/wholphin-mpv-release.aar").exists() }
|
||||
val extensionsRepoActive =
|
||||
providers.provider { project.hasProperty("WholphinExtensionsUsername") }
|
||||
|
||||
val gitTags =
|
||||
providers
|
||||
|
|
@ -63,7 +72,7 @@ configure<ApplicationExtension> {
|
|||
}
|
||||
|
||||
signingConfigs {
|
||||
if (shouldSign) {
|
||||
if (shouldSign.get()) {
|
||||
create("ci") {
|
||||
file("ci.keystore").writeBytes(
|
||||
Base64.getDecoder().decode(System.getenv("SIGNING_KEY")),
|
||||
|
|
@ -88,7 +97,7 @@ configure<ApplicationExtension> {
|
|||
"proguard-rules.pro",
|
||||
)
|
||||
isDebuggable = false
|
||||
if (shouldSign) {
|
||||
if (shouldSign.get()) {
|
||||
signingConfig = signingConfigs.getByName("ci")
|
||||
} else {
|
||||
val localPropertiesFile = project.rootProject.file("local.properties")
|
||||
|
|
@ -346,28 +355,28 @@ dependencies {
|
|||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
coreLibraryDesugaring(libs.desugar.jdk.libs)
|
||||
|
||||
if (ffmpegModuleExists) {
|
||||
if (ffmpegModuleExists.get()) {
|
||||
logger.info("Using local ffmpeg decoder")
|
||||
implementation(files("libs/lib-decoder-ffmpeg-release.aar"))
|
||||
} else if (extensionsRepoActive) {
|
||||
} else if (extensionsRepoActive.get()) {
|
||||
logger.info("Using prebuilt ffmpeg decoder")
|
||||
implementation(libs.wholphin.extensions.ffmpeg)
|
||||
} else {
|
||||
logger.warn("Media3 ffmpeg decoder was NOT found")
|
||||
}
|
||||
if (av1ModuleExists) {
|
||||
if (av1ModuleExists.get()) {
|
||||
logger.info("Using local av1 decoder")
|
||||
implementation(files("libs/lib-decoder-av1-release.aar"))
|
||||
} else if (extensionsRepoActive) {
|
||||
} else if (extensionsRepoActive.get()) {
|
||||
logger.info("Using prebuilt av1 decoder")
|
||||
implementation(libs.wholphin.extensions.av1)
|
||||
} else {
|
||||
logger.warn("Media3 av1 decoder was NOT found")
|
||||
}
|
||||
if (mpvModuleExists) {
|
||||
if (mpvModuleExists.get()) {
|
||||
logger.info("Using local libMPV build")
|
||||
implementation(files("libs/wholphin-mpv-release.aar"))
|
||||
} else if (extensionsRepoActive) {
|
||||
} else if (extensionsRepoActive.get()) {
|
||||
logger.info("Using prebuilt libMPV")
|
||||
implementation(libs.wholphin.extensions.mpv)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
|||
import androidx.media3.exoplayer.video.MediaCodecVideoRenderer
|
||||
import androidx.media3.exoplayer.video.VideoRendererEventListener
|
||||
import androidx.media3.extractor.DefaultExtractorsFactory
|
||||
import com.github.damontecres.wholphin.mpv.MpvPlayer
|
||||
import com.github.damontecres.wholphin.preferences.AssPlaybackMode
|
||||
import com.github.damontecres.wholphin.preferences.MediaExtensionStatus
|
||||
import com.github.damontecres.wholphin.preferences.PlaybackPreferences
|
||||
import com.github.damontecres.wholphin.preferences.PlayerBackend
|
||||
import com.github.damontecres.wholphin.services.hilt.AuthOkHttpClient
|
||||
import com.github.damontecres.wholphin.util.mpv.MpvPlayer
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.peerless2012.ass.media.AssHandler
|
||||
import io.github.peerless2012.ass.media.factory.AssRenderersFactory
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ import androidx.tv.material3.MaterialTheme
|
|||
import androidx.tv.material3.surfaceColorAtElevation
|
||||
import com.github.damontecres.wholphin.data.model.ItemPlayback
|
||||
import com.github.damontecres.wholphin.data.model.Playlist
|
||||
import com.github.damontecres.wholphin.mpv.MpvPlayer
|
||||
import com.github.damontecres.wholphin.preferences.AssPlaybackMode
|
||||
import com.github.damontecres.wholphin.preferences.PlayerBackend
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
|
|
@ -91,7 +92,6 @@ import com.github.damontecres.wholphin.ui.tryRequestFocus
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.Media3SubtitleOverride
|
||||
import com.github.damontecres.wholphin.util.mpv.MpvPlayer
|
||||
import io.github.peerless2012.ass.media.widget.AssSubtitleView
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import androidx.compose.ui.unit.sp
|
|||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.ui.CaptionStyleCompat
|
||||
import com.github.damontecres.wholphin.R
|
||||
import com.github.damontecres.wholphin.mpv.MPVLib
|
||||
import com.github.damontecres.wholphin.preferences.AppChoicePreference
|
||||
import com.github.damontecres.wholphin.preferences.AppClickablePreference
|
||||
import com.github.damontecres.wholphin.preferences.AppDestinationPreference
|
||||
|
|
@ -24,7 +25,6 @@ import com.github.damontecres.wholphin.preferences.SubtitlePreferences
|
|||
import com.github.damontecres.wholphin.ui.indexOfFirstOrNull
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferenceGroup
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib
|
||||
import com.github.damontecres.wholphin.util.mpv.setPropertyColor
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
|
|||
|
|
@ -1,311 +0,0 @@
|
|||
package com.github.damontecres.wholphin.util.mpv
|
||||
|
||||
/*
|
||||
This file is copied from https://github.com/mpv-android/mpv-android/blob/master/app/src/main/java/is/xyz/mpv/MPVLib.kt
|
||||
|
||||
Copyright (c) 2016 Ilya Zhuravlev
|
||||
Copyright (c) 2016 sfan5 <sfan5@live.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.view.Surface
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
// Wrapper for native library
|
||||
|
||||
@Suppress("unused")
|
||||
object MPVLib {
|
||||
init {
|
||||
val libs = arrayOf("mpv", "player")
|
||||
for (lib in libs) {
|
||||
System.loadLibrary(lib)
|
||||
}
|
||||
}
|
||||
|
||||
external fun create(appctx: Context)
|
||||
|
||||
external fun init()
|
||||
|
||||
external fun destroy()
|
||||
|
||||
external fun attachSurface(surface: Surface)
|
||||
|
||||
external fun detachSurface()
|
||||
|
||||
external fun command(cmd: Array<out String>)
|
||||
|
||||
external fun setOptionString(
|
||||
name: String,
|
||||
value: String,
|
||||
): Int
|
||||
|
||||
external fun grabThumbnail(dimension: Int): Bitmap?
|
||||
|
||||
external fun getPropertyInt(property: String): Int?
|
||||
|
||||
external fun setPropertyInt(
|
||||
property: String,
|
||||
value: Int,
|
||||
)
|
||||
|
||||
external fun getPropertyDouble(property: String): Double?
|
||||
|
||||
external fun setPropertyDouble(
|
||||
property: String,
|
||||
value: Double,
|
||||
)
|
||||
|
||||
external fun getPropertyBoolean(property: String): Boolean?
|
||||
|
||||
external fun setPropertyBoolean(
|
||||
property: String,
|
||||
value: Boolean,
|
||||
)
|
||||
|
||||
external fun getPropertyString(property: String): String?
|
||||
|
||||
external fun setPropertyString(
|
||||
property: String,
|
||||
value: String,
|
||||
)
|
||||
|
||||
external fun observeProperty(
|
||||
property: String,
|
||||
format: Int,
|
||||
)
|
||||
|
||||
private val observers = CopyOnWriteArrayList<EventObserver>()
|
||||
|
||||
@JvmStatic
|
||||
fun addObserver(o: EventObserver) {
|
||||
observers.add(o)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun removeObserver(o: EventObserver) {
|
||||
observers.remove(o)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Long,
|
||||
) {
|
||||
for (o in observers) {
|
||||
o.eventProperty(property, value)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Boolean,
|
||||
) {
|
||||
for (o in observers) {
|
||||
o.eventProperty(property, value)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Double,
|
||||
) {
|
||||
for (o in observers) {
|
||||
o.eventProperty(property, value)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: String,
|
||||
) {
|
||||
for (o in observers) {
|
||||
o.eventProperty(property, value)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventProperty(property: String) {
|
||||
for (o in observers) {
|
||||
o.eventProperty(property)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun event(eventId: Int) {
|
||||
for (o in observers) {
|
||||
o.event(eventId)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun eventEndFile(
|
||||
reason: Int,
|
||||
error: Int,
|
||||
) {
|
||||
for (o in observers) {
|
||||
o.eventEndFile(reason, error)
|
||||
}
|
||||
}
|
||||
|
||||
private val log_observers = CopyOnWriteArrayList<LogObserver>()
|
||||
|
||||
@JvmStatic
|
||||
fun addLogObserver(o: LogObserver) {
|
||||
log_observers.add(o)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun removeLogObserver(o: LogObserver) {
|
||||
log_observers.remove(o)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logMessage(
|
||||
prefix: String,
|
||||
level: Int,
|
||||
text: String,
|
||||
) {
|
||||
for (o in log_observers) {
|
||||
o.logMessage(prefix, level, text)
|
||||
}
|
||||
}
|
||||
|
||||
interface EventObserver {
|
||||
fun eventProperty(property: String)
|
||||
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Long,
|
||||
)
|
||||
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Boolean,
|
||||
)
|
||||
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: String,
|
||||
)
|
||||
|
||||
fun eventProperty(
|
||||
property: String,
|
||||
value: Double,
|
||||
)
|
||||
|
||||
fun event(eventId: Int)
|
||||
|
||||
fun eventEndFile(
|
||||
reason: Int,
|
||||
error: Int,
|
||||
)
|
||||
}
|
||||
|
||||
interface LogObserver {
|
||||
fun logMessage(
|
||||
prefix: String,
|
||||
level: Int,
|
||||
text: String,
|
||||
)
|
||||
}
|
||||
|
||||
object MpvFormat {
|
||||
const val MPV_FORMAT_NONE: Int = 0
|
||||
const val MPV_FORMAT_STRING: Int = 1
|
||||
const val MPV_FORMAT_OSD_STRING: Int = 2
|
||||
const val MPV_FORMAT_FLAG: Int = 3
|
||||
const val MPV_FORMAT_INT64: Int = 4
|
||||
const val MPV_FORMAT_DOUBLE: Int = 5
|
||||
const val MPV_FORMAT_NODE: Int = 6
|
||||
const val MPV_FORMAT_NODE_ARRAY: Int = 7
|
||||
const val MPV_FORMAT_NODE_MAP: Int = 8
|
||||
const val MPV_FORMAT_BYTE_ARRAY: Int = 9
|
||||
}
|
||||
|
||||
object MpvEvent {
|
||||
const val MPV_EVENT_NONE: Int = 0
|
||||
const val MPV_EVENT_SHUTDOWN: Int = 1
|
||||
const val MPV_EVENT_LOG_MESSAGE: Int = 2
|
||||
const val MPV_EVENT_GET_PROPERTY_REPLY: Int = 3
|
||||
const val MPV_EVENT_SET_PROPERTY_REPLY: Int = 4
|
||||
const val MPV_EVENT_COMMAND_REPLY: Int = 5
|
||||
const val MPV_EVENT_START_FILE: Int = 6
|
||||
const val MPV_EVENT_END_FILE: Int = 7
|
||||
const val MPV_EVENT_FILE_LOADED: Int = 8
|
||||
|
||||
@Deprecated("")
|
||||
const val MPV_EVENT_IDLE: Int = 11
|
||||
|
||||
@Deprecated("")
|
||||
const val MPV_EVENT_TICK: Int = 14
|
||||
const val MPV_EVENT_CLIENT_MESSAGE: Int = 16
|
||||
const val MPV_EVENT_VIDEO_RECONFIG: Int = 17
|
||||
const val MPV_EVENT_AUDIO_RECONFIG: Int = 18
|
||||
const val MPV_EVENT_SEEK: Int = 20
|
||||
const val MPV_EVENT_PLAYBACK_RESTART: Int = 21
|
||||
const val MPV_EVENT_PROPERTY_CHANGE: Int = 22
|
||||
const val MPV_EVENT_QUEUE_OVERFLOW: Int = 24
|
||||
const val MPV_EVENT_HOOK: Int = 25
|
||||
}
|
||||
|
||||
object MpvLogLevel {
|
||||
const val MPV_LOG_LEVEL_NONE: Int = 0
|
||||
const val MPV_LOG_LEVEL_FATAL: Int = 10
|
||||
const val MPV_LOG_LEVEL_ERROR: Int = 20
|
||||
const val MPV_LOG_LEVEL_WARN: Int = 30
|
||||
const val MPV_LOG_LEVEL_INFO: Int = 40
|
||||
const val MPV_LOG_LEVEL_V: Int = 50
|
||||
const val MPV_LOG_LEVEL_DEBUG: Int = 60
|
||||
const val MPV_LOG_LEVEL_TRACE: Int = 70
|
||||
}
|
||||
|
||||
object MpvEndFileReason {
|
||||
const val MPV_END_FILE_REASON_EOF: Int = 0
|
||||
const val MPV_END_FILE_REASON_STOP: Int = 2
|
||||
const val MPV_END_FILE_REASON_QUIT: Int = 3
|
||||
const val MPV_END_FILE_REASON_ERROR: Int = 4
|
||||
const val MPV_END_FILE_REASON_REDIRECT: Int = 5
|
||||
}
|
||||
|
||||
object MpvError {
|
||||
const val MPV_ERROR_SUCCESS = 0
|
||||
const val MPV_ERROR_EVENT_QUEUE_FULL = -1
|
||||
const val MPV_ERROR_NOMEM = -2
|
||||
const val MPV_ERROR_UNINITIALIZED = -3
|
||||
const val MPV_ERROR_INVALID_PARAMETER = -4
|
||||
const val MPV_ERROR_OPTION_NOT_FOUND = -5
|
||||
const val MPV_ERROR_OPTION_FORMAT = -6
|
||||
const val MPV_ERROR_OPTION_ERROR = -7
|
||||
const val MPV_ERROR_PROPERTY_NOT_FOUND = -8
|
||||
const val MPV_ERROR_PROPERTY_FORMAT = -9
|
||||
const val MPV_ERROR_PROPERTY_UNAVAILABLE = -10
|
||||
const val MPV_ERROR_PROPERTY_ERROR = -11
|
||||
const val MPV_ERROR_COMMAND = -12
|
||||
const val MPV_ERROR_LOADING_FAILED = -13
|
||||
const val MPV_ERROR_AO_INIT_FAILED = -14
|
||||
const val MPV_ERROR_VO_INIT_FAILED = -15
|
||||
const val MPV_ERROR_NOTHING_TO_PLAY = -16
|
||||
const val MPV_ERROR_UNKNOWN_FORMAT = -17
|
||||
const val MPV_ERROR_UNSUPPORTED = -18
|
||||
const val MPV_ERROR_NOT_IMPLEMENTED = -19
|
||||
const val MPV_ERROR_GENERIC = -20
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package com.github.damontecres.wholphin.util.mpv
|
||||
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvFormat.MPV_FORMAT_DOUBLE
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvFormat.MPV_FORMAT_FLAG
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvFormat.MPV_FORMAT_INT64
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvFormat.MPV_FORMAT_NONE
|
||||
import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvFormat.MPV_FORMAT_STRING
|
||||
|
||||
object MPVProperty {
|
||||
const val POSITION = "time-pos"
|
||||
const val POSITION_FULL = "time-pos/full"
|
||||
const val DURATION = "duration/full"
|
||||
const val PAUSED = "pause"
|
||||
const val PAUSED_FOR_CACHE = "paused-for-cache"
|
||||
const val SPEED = "speed"
|
||||
const val TRACK_LIST = "track-list"
|
||||
const val ASPECT = "video-params/aspect"
|
||||
const val ROTATE = "video-params/rotate"
|
||||
const val TRACK_VIDEO = "current-tracks/video/image"
|
||||
const val METADATA = "metadata"
|
||||
const val HWDEC = "hwdec-current"
|
||||
const val MUTE = "mute"
|
||||
const val TRACK_AUDIO = "current-tracks/audio/selected"
|
||||
const val SEEKABLE = "seekable"
|
||||
const val SUBTITLE_TEXT = "sub-text"
|
||||
|
||||
val observedProperties =
|
||||
mapOf(
|
||||
POSITION to MPV_FORMAT_INT64,
|
||||
// POSITION_FULL to MPV_FORMAT_DOUBLE,
|
||||
DURATION to MPV_FORMAT_DOUBLE,
|
||||
PAUSED to MPV_FORMAT_FLAG,
|
||||
PAUSED_FOR_CACHE to MPV_FORMAT_FLAG,
|
||||
SPEED to MPV_FORMAT_STRING,
|
||||
TRACK_LIST to MPV_FORMAT_NONE,
|
||||
ASPECT to MPV_FORMAT_DOUBLE,
|
||||
ROTATE to MPV_FORMAT_DOUBLE,
|
||||
TRACK_VIDEO to MPV_FORMAT_NONE,
|
||||
METADATA to MPV_FORMAT_NONE,
|
||||
HWDEC to MPV_FORMAT_NONE,
|
||||
MUTE to MPV_FORMAT_FLAG,
|
||||
TRACK_AUDIO to MPV_FORMAT_NONE,
|
||||
SEEKABLE to MPV_FORMAT_FLAG,
|
||||
SUBTITLE_TEXT to MPV_FORMAT_STRING,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.github.damontecres.wholphin.util.mpv
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
class MpvLogger : MPVLib.LogObserver {
|
||||
override fun logMessage(
|
||||
prefix: String,
|
||||
level: Int,
|
||||
text: String,
|
||||
) {
|
||||
// https://github.com/mpv-player/mpv/blob/122abdfec3124bfc92a2918a70ca8150eee68338/include/mpv/client.h#L1423
|
||||
when {
|
||||
level <= 10 -> Timber.wtf("%s, %s", prefix, text)
|
||||
level <= 20 -> Timber.e("%s, %s", prefix, text)
|
||||
level <= 30 -> Timber.w("%s, %s", prefix, text)
|
||||
level <= 40 -> Timber.i("%s, %s", prefix, text)
|
||||
level <= 50 -> Timber.d("%s, %s", prefix, text)
|
||||
else -> Timber.v("%s, %s", prefix, text)
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
package com.github.damontecres.wholphin.util.mpv
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.github.damontecres.wholphin.mpv.MPVLib
|
||||
|
||||
fun MPVLib.setPropertyColor(
|
||||
property: String,
|
||||
color: Color,
|
||||
) = setPropertyString(property, color.mpvFormat)
|
||||
|
||||
private val Color.mpvFormat: String get() = "$red/$green/$blue/$alpha"
|
||||
|
|
@ -45,7 +45,7 @@ kotlinxCoroutinesTest = "1.10.2"
|
|||
coreTesting = "2.2.0"
|
||||
openapi-generator = "7.22.0"
|
||||
runner = "1.7.0"
|
||||
wholphin-extensions = "0.1.2"
|
||||
wholphin-extensions = "0.2.0"
|
||||
|
||||
[libraries]
|
||||
wholphin-extensions-mpv = { module = "com.github.damontecres.wholphin.mpv:wholphin-mpv", version.ref = "wholphin-extensions" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue