Add experimental libMPV player
This commit is contained in:
parent
88b5d38ffc
commit
c9d0d6ab17
7 changed files with 1543 additions and 14 deletions
|
@ -103,6 +103,8 @@ dependencies {
|
|||
implementation("com.google.android.exoplayer:exoplayer-ui:$exoplayerVersion")
|
||||
implementation(files("libs/extension-ffmpeg-release.aar"))
|
||||
|
||||
implementation(files("libs/libmpv/app-release.aar"))
|
||||
|
||||
// Timber
|
||||
val timberVersion = "5.0.1"
|
||||
implementation("com.jakewharton.timber:timber:$timberVersion")
|
||||
|
|
BIN
app/libs/libmpv/app-release.aar
Executable file
BIN
app/libs/libmpv/app-release.aar
Executable file
Binary file not shown.
14
app/src/main/assets/mpv.conf
Executable file
14
app/src/main/assets/mpv.conf
Executable file
|
@ -0,0 +1,14 @@
|
|||
#vo=mediacodec_embed
|
||||
# hwdec: try to use hardware decoding
|
||||
hwdec=mediacodec-copy
|
||||
hwdec-codecs="h264,hevc,mpeg4,mpeg2video,vp8,vp9,av1"
|
||||
gpu-dumb-mode=auto
|
||||
# tls: allow self signed certificate
|
||||
tls-verify=no
|
||||
tls-ca-file=""
|
||||
# demuxer: limit cache to 32 MiB, the default is too high for mobile devices
|
||||
demuxer-max-bytes=32MiB
|
||||
demuxer-max-back-bytes=32MiB
|
||||
# sub: scale subtitles with video
|
||||
sub-scale-with-window=no
|
||||
sub-use-margins=no
|
1473
app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt
Normal file
1473
app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt
Normal file
File diff suppressed because it is too large
Load diff
14
app/src/main/java/dev/jdtech/jellyfin/mpv/TrackType.java
Normal file
14
app/src/main/java/dev/jdtech/jellyfin/mpv/TrackType.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package dev.jdtech.jellyfin.mpv;
|
||||
|
||||
import androidx.annotation.StringDef;
|
||||
|
||||
@StringDef({
|
||||
TrackType.VIDEO,
|
||||
TrackType.AUDIO,
|
||||
TrackType.SUBTITLE,
|
||||
})
|
||||
public @interface TrackType {
|
||||
String VIDEO = "video";
|
||||
String AUDIO = "audio";
|
||||
String SUBTITLE = "sub";
|
||||
}
|
|
@ -12,6 +12,7 @@ import com.google.android.exoplayer2.*
|
|||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
||||
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
@ -26,7 +27,7 @@ constructor(
|
|||
application: Application,
|
||||
private val jellyfinRepository: JellyfinRepository
|
||||
) : ViewModel(), Player.Listener {
|
||||
var player: SimpleExoPlayer
|
||||
var player: BasePlayer
|
||||
|
||||
private val _navigateBack = MutableLiveData<Boolean>()
|
||||
val navigateBack: LiveData<Boolean> = _navigateBack
|
||||
|
@ -38,18 +39,24 @@ constructor(
|
|||
private val sp = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
|
||||
init {
|
||||
val renderersFactory =
|
||||
DefaultRenderersFactory(application).setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
|
||||
val trackSelector = DefaultTrackSelector(application)
|
||||
trackSelector.setParameters(
|
||||
trackSelector.buildUponParameters()
|
||||
.setTunnelingEnabled(true)
|
||||
.setPreferredAudioLanguage(sp.getString("audio_language", null))
|
||||
.setPreferredTextLanguage(sp.getString("subtitle_language", null))
|
||||
)
|
||||
val useMpv = sp.getBoolean("mpv_player", false)
|
||||
|
||||
if (useMpv) {
|
||||
player = MPVPlayer(application, false)
|
||||
} else {
|
||||
val renderersFactory =
|
||||
DefaultRenderersFactory(application).setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
|
||||
val trackSelector = DefaultTrackSelector(application)
|
||||
trackSelector.setParameters(
|
||||
trackSelector.buildUponParameters()
|
||||
.setTunnelingEnabled(true)
|
||||
.setPreferredAudioLanguage(sp.getString("audio_language", null))
|
||||
.setPreferredTextLanguage(sp.getString("subtitle_language", null))
|
||||
)
|
||||
player = SimpleExoPlayer.Builder(application, renderersFactory)
|
||||
.setTrackSelector(trackSelector)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
fun initializePlayer(
|
||||
|
@ -75,9 +82,17 @@ constructor(
|
|||
Timber.e(e)
|
||||
}
|
||||
|
||||
player.setMediaItems(mediaItems, currentWindow, items[0].playbackPosition)
|
||||
player.playWhenReady = playWhenReady
|
||||
player.prepare()
|
||||
val useMpv = sp.getBoolean("mpv_player", false)
|
||||
|
||||
if (useMpv) {
|
||||
player.setMediaItem(mediaItems[0])
|
||||
player.prepare()
|
||||
player.play()
|
||||
} else {
|
||||
player.setMediaItems(mediaItems, currentWindow, items[0].playbackPosition)
|
||||
player.playWhenReady = playWhenReady
|
||||
player.prepare()
|
||||
}
|
||||
}
|
||||
|
||||
pollPosition(player)
|
||||
|
@ -104,7 +119,7 @@ constructor(
|
|||
player.release()
|
||||
}
|
||||
|
||||
private fun pollPosition(player: SimpleExoPlayer) {
|
||||
private fun pollPosition(player: BasePlayer) {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val runnable = object : Runnable {
|
||||
override fun run() {
|
||||
|
|
|
@ -39,6 +39,17 @@
|
|||
app:useSimpleSummaryProvider="true" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="Player">
|
||||
<SwitchPreference
|
||||
app:key="mpv_player"
|
||||
app:title="MPV Player"
|
||||
app:summary="Use the experimental MPV Player to play videos. MPV has support for more video, audio and subtitle codecs."/>
|
||||
<SwitchPreference
|
||||
app:dependency="mpv_player"
|
||||
app:title="Force software decoding"
|
||||
app:summary="Disable hardware decoding and use software decoding. Can be useful if hardware decoding gives weird artifacts."/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/about">
|
||||
|
||||
<Preference
|
||||
|
|
Loading…
Reference in a new issue