change video player configs for faster load time
This commit is contained in:
parent
903293e159
commit
a7187b1a68
5 changed files with 36 additions and 29 deletions
|
|
@ -84,10 +84,6 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions{
|
|
||||||
disable 'MissingTranslation'
|
|
||||||
disable 'RestrictedApi'
|
|
||||||
}
|
|
||||||
|
|
||||||
android.applicationVariants.configureEach { variant ->
|
android.applicationVariants.configureEach { variant ->
|
||||||
variant.outputs.each { output ->
|
variant.outputs.each { output ->
|
||||||
|
|
@ -134,6 +130,14 @@ android {
|
||||||
// Disables dependency metadata when building Android App Bundles.
|
// Disables dependency metadata when building Android App Bundles.
|
||||||
includeInBundle = false
|
includeInBundle = false
|
||||||
}
|
}
|
||||||
|
packagingOptions {
|
||||||
|
jniLibs {
|
||||||
|
useLegacyPackaging true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lint {
|
||||||
|
disable 'MissingTranslation', 'RestrictedApi'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|locale"
|
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|locale"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:extractNativeLibs="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="YTDLnis"
|
android:label="YTDLnis"
|
||||||
android:localeConfig="@xml/locales_config"
|
android:localeConfig="@xml/locales_config"
|
||||||
|
|
|
||||||
|
|
@ -3,42 +3,47 @@ package com.deniscerri.ytdl.util
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.media3.common.AudioAttributes
|
import androidx.media3.common.AudioAttributes
|
||||||
import androidx.media3.common.C
|
import androidx.media3.common.C
|
||||||
|
import androidx.media3.common.PlaybackParameters
|
||||||
|
import androidx.media3.datasource.DefaultDataSource
|
||||||
import androidx.media3.exoplayer.DefaultLoadControl
|
import androidx.media3.exoplayer.DefaultLoadControl
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
object VideoPlayerUtil {
|
object VideoPlayerUtil {
|
||||||
|
private const val MINIMUM_BUFFER_DURATION = 1000 * 10 //exo default is 50s
|
||||||
|
|
||||||
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
|
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
|
||||||
fun buildPlayer(context: Context) : ExoPlayer {
|
fun buildPlayer(context: Context) : ExoPlayer {
|
||||||
val player: ExoPlayer
|
val dataSourceFactory = DefaultDataSource.Factory(context)
|
||||||
|
val audioAttributes = AudioAttributes.Builder()
|
||||||
|
.setUsage(C.USAGE_MEDIA)
|
||||||
|
.setContentType(C.AUDIO_CONTENT_TYPE_MOVIE)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
|
||||||
val trackSelector = DefaultTrackSelector(context)
|
|
||||||
val loadControl = DefaultLoadControl.Builder()
|
val loadControl = DefaultLoadControl.Builder()
|
||||||
// cache the last three minutes
|
// cache the last three minutes
|
||||||
.setBackBuffer(1000 * 60 * 3, true)
|
.setBackBuffer(1000 * 60 * 3, true)
|
||||||
.setBufferDurationsMs(
|
.setBufferDurationsMs(
|
||||||
1000 * 10, // exo default is 50s
|
MINIMUM_BUFFER_DURATION,
|
||||||
50000,
|
max(50 * 1000, MINIMUM_BUFFER_DURATION),
|
||||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
||||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
|
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
player = ExoPlayer.Builder(context)
|
return ExoPlayer.Builder(context)
|
||||||
.setUsePlatformDiagnostics(false)
|
.setUsePlatformDiagnostics(false)
|
||||||
.setTrackSelector(trackSelector)
|
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
|
||||||
.setLoadControl(loadControl)
|
.setTrackSelector(DefaultTrackSelector(context))
|
||||||
.setHandleAudioBecomingNoisy(true)
|
.setHandleAudioBecomingNoisy(true)
|
||||||
.setAudioAttributes(
|
.setLoadControl(loadControl)
|
||||||
AudioAttributes.Builder()
|
.setAudioAttributes(audioAttributes, false)
|
||||||
.setUsage(C.USAGE_MEDIA)
|
|
||||||
.setContentType(C.AUDIO_CONTENT_TYPE_MOVIE)
|
|
||||||
.build()
|
|
||||||
,
|
|
||||||
true)
|
|
||||||
.build()
|
.build()
|
||||||
|
.apply {
|
||||||
return player
|
skipSilenceEnabled = false
|
||||||
|
playbackParameters = PlaybackParameters(1f, 1.0f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -358,8 +358,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
|
||||||
request.applyDefaultOptionsForFetchingData(urls.firstOrNull { it.isURL() })
|
request.applyDefaultOptionsForFetchingData(urls.firstOrNull { it.isURL() })
|
||||||
if (urls.all { it.isYoutubeURL() }) {
|
if (urls.all { it.isYoutubeURL() }) {
|
||||||
request.setYoutubeExtractorArgs(urls[0])
|
request.setYoutubeExtractorArgs(urls[0])
|
||||||
request.addOption("--extractor-args", "youtube:player_skip=initial_data,webpage")
|
|
||||||
request.addOption("--extractor-args", "youtubetab:skip=webpage")
|
|
||||||
}
|
}
|
||||||
if (!request.hasOption("--no-check-certificates")) request.addOption("--no-check-certificates")
|
if (!request.hasOption("--no-check-certificates")) request.addOption("--no-check-certificates")
|
||||||
|
|
||||||
|
|
@ -431,8 +429,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
|
||||||
request.applyDefaultOptionsForFetchingData(url)
|
request.applyDefaultOptionsForFetchingData(url)
|
||||||
if (url.isYoutubeURL()) {
|
if (url.isYoutubeURL()) {
|
||||||
request.setYoutubeExtractorArgs(url)
|
request.setYoutubeExtractorArgs(url)
|
||||||
request.addOption("--extractor-args", "youtube:player_skip=initial_data,webpage")
|
|
||||||
request.addOption("--extractor-args", "youtubetab:skip=webpage")
|
|
||||||
}
|
}
|
||||||
if (!request.hasOption("--no-check-certificates")) request.addOption("--no-check-certificates")
|
if (!request.hasOption("--no-check-certificates")) request.addOption("--no-check-certificates")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,9 +134,12 @@ class NewPipeUtil(context: Context) {
|
||||||
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
|
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
|
||||||
try {
|
try {
|
||||||
val streamInfo = StreamInfo.getInfo(url)
|
val streamInfo = StreamInfo.getInfo(url)
|
||||||
val item = createVideoFromStream(streamInfo, url)
|
val item = createVideoFromStream(streamInfo, url)!!
|
||||||
if (item!!.urls.isBlank()) return Result.failure(Throwable())
|
|
||||||
val urls = item.urls.split(",")
|
val videoURL = item.formats.filter { it.vcodec.isNotBlank() && it.vcodec != "none" }.firstOrNull { !it.url.isNullOrBlank() }?.url ?: ""
|
||||||
|
val audioURL = item.formats.filter { it.vcodec.isBlank() || it.vcodec == "none" }.firstOrNull { !it.url.isNullOrBlank() }?.url ?: ""
|
||||||
|
|
||||||
|
val urls = listOf(videoURL, audioURL)
|
||||||
val chapters = item.chapters
|
val chapters = item.chapters
|
||||||
return Result.success(Pair(urls, chapters))
|
return Result.success(Pair(urls, chapters))
|
||||||
}catch (e: Exception) {
|
}catch (e: Exception) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue