Skip to content

Commit

Permalink
updated dependencies
Browse files Browse the repository at this point in the history
added video sources with query params (fixes #12)
added custom LoadControl
  • Loading branch information
DatL4g committed Oct 25, 2022
1 parent 4bb9375 commit cd82de3
Show file tree
Hide file tree
Showing 12 changed files with 331 additions and 103 deletions.
40 changes: 20 additions & 20 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,22 @@ dependencies {

coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.6")

implementation("androidx.appcompat:appcompat:1.4.2")
implementation("com.google.android.material:material:1.7.0-alpha02")
implementation("androidx.appcompat:appcompat:1.5.1")
implementation("com.google.android.material:material:1.8.0-alpha02")
runtimeOnly("androidx.vectordrawable:vectordrawable-animated:1.1.0")
implementation("androidx.core:core-splashscreen:1.0.0-rc01")
implementation("androidx.core:core-splashscreen:1.0.0")

implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("com.github.devendroid:ReadMoreOption:1.0.3")
implementation("com.mikepenz:aboutlibraries:10.3.1")
implementation("com.mikepenz:aboutlibraries:10.5.1")

implementation("com.google.android.exoplayer:exoplayer:2.18.0")
implementation("com.google.android.exoplayer:exoplayer:2.18.1")
implementation("com.github.DATL4G.PreviewSeekBar:previewseekbar-exoplayer:3.0.1")
implementation("com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.16")
implementation("com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.16")
implementation("com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.19")
implementation("com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.19")

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
Expand All @@ -114,21 +114,21 @@ dependencies {
strictly("1.5.6")
}

implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.activity:activity-ktx:1.5.0")
implementation("androidx.fragment:fragment-ktx:1.5.0")
implementation("androidx.room:room-ktx:2.4.2")
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.activity:activity-ktx:1.6.1")
implementation("androidx.fragment:fragment-ktx:1.5.4")
implementation("androidx.room:room-ktx:2.4.3")

implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0")
implementation("androidx.lifecycle:lifecycle-common-java8:2.5.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1")
implementation("androidx.lifecycle:lifecycle-common-java8:2.5.1")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")

implementation("androidx.navigation:navigation-runtime-ktx:2.5.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.5.0")
implementation("androidx.navigation:navigation-ui-ktx:2.5.0")
implementation("androidx.navigation:navigation-runtime-ktx:2.5.3")
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")

implementation("com.google.dagger:hilt-android:2.42")
kapt("com.google.dagger:hilt-android-compiler:2.42")
Expand All @@ -155,7 +155,7 @@ dependencies {
implementation("com.github.Ferfalk:SimpleSearchView:0.2.0")
implementation("net.openid:appauth:0.11.1")
implementation("io.github.florent37:shapeofview:1.4.7")
implementation("com.github.skydoves:androidveil:1.1.2")
implementation("com.github.skydoves:androidveil:1.1.3")
implementation("com.diogobernardino:williamchart:3.11.0")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS
import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory.*
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import dagger.hilt.android.AndroidEntryPoint
import de.datlag.burningseries.R
Expand All @@ -32,6 +32,7 @@ import de.datlag.burningseries.extend.AdvancedFragment
import de.datlag.burningseries.helper.lazyMutable
import de.datlag.burningseries.ui.connector.BackPressedDispatcher
import de.datlag.burningseries.ui.connector.KeyEventDispatcher
import de.datlag.burningseries.ui.view.CustomControl
import de.datlag.burningseries.viewmodel.BurningSeriesViewModel
import de.datlag.burningseries.viewmodel.SettingsViewModel
import de.datlag.burningseries.viewmodel.VideoViewModel
Expand Down Expand Up @@ -110,13 +111,16 @@ class VideoFragment : AdvancedFragment(R.layout.fragment_video), PreviewLoader,
private fun initPlayer(): Unit = with(binding) {
retriever = FFmpegMediaMetadataRetriever()

val extractorFactory = DefaultExtractorsFactory().setTsExtractorFlags(FLAG_DETECT_ACCESS_UNITS)
val extractorFactory = DefaultExtractorsFactory().setTsExtractorFlags(
FLAG_ALLOW_NON_IDR_KEYFRAMES and FLAG_DETECT_ACCESS_UNITS and FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS
)
if (!::exoPlayer.isInitialized) {
exoPlayer = ExoPlayer.Builder(safeContext).apply {
setSeekBackIncrementMs(10000)
setSeekForwardIncrementMs(10000)
setPauseAtEndOfMediaItems(true)
setMediaSourceFactory(DefaultMediaSourceFactory(safeContext, extractorFactory))
setLoadControl(CustomControl())
}.build().apply {
addListener(this@VideoFragment)
playWhenReady = true
Expand Down
217 changes: 217 additions & 0 deletions app/src/main/java/de/datlag/burningseries/ui/view/CustomControl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package de.datlag.burningseries.ui.view

import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.C.TrackType
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.LoadControl
import com.google.android.exoplayer2.Renderer
import com.google.android.exoplayer2.source.TrackGroupArray
import com.google.android.exoplayer2.trackselection.ExoTrackSelection
import com.google.android.exoplayer2.upstream.Allocator
import com.google.android.exoplayer2.upstream.DefaultAllocator
import com.google.android.exoplayer2.util.PriorityTaskManager

class CustomControl(
private val allocator: DefaultAllocator,
minBufferMs: Int,
maxBufferMs: Int,
bufferForPlaybackMs: Int,
bufferForPlaybackAfterRebufferMs: Int
) : LoadControl {

private var minBufferUs: Long = 0
private var maxBufferUs: Long = 0
private var bufferForPlaybackUs: Long = 0
private var bufferForPlaybackAfterRebufferUs: Long = 0
private var priorityTaskManager: PriorityTaskManager? = null

private var targetBufferBytes = 0
private var isLoading = false

constructor() : this(
DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE),
DEFAULT_MIN_BUFFER_MS,
DEFAULT_MAX_BUFFER_MS,
DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
)

init {
this.minBufferUs = VIDEO_BUFFER_SCALE_UP_FACTOR * minBufferMs * 1000L
this.maxBufferUs = VIDEO_BUFFER_SCALE_UP_FACTOR * maxBufferMs * 1000L
this.bufferForPlaybackUs = bufferForPlaybackMs * 1000L
this.bufferForPlaybackAfterRebufferUs = bufferForPlaybackAfterRebufferMs * 1000L
}

override fun onPrepared() {
reset(false)
}

override fun onTracksSelected(
renderers: Array<Renderer>,
trackGroups: TrackGroupArray,
trackSelections: Array<out ExoTrackSelection>
) {
targetBufferBytes = DEFAULT_VIDEO_BUFFER_SIZE
for (i in renderers.indices) {
targetBufferBytes += getDefaultBufferSize(renderers[i].trackType)
if (renderers[i].trackType == C.TRACK_TYPE_VIDEO) {
targetBufferBytes *= VIDEO_BUFFER_SCALE_UP_FACTOR
}
}
allocator.setTargetBufferSize(targetBufferBytes)
}

override fun onStopped() {
reset(false)
}

override fun onReleased() {
reset(true)
}

override fun getAllocator(): Allocator {
return allocator
}

override fun getBackBufferDurationUs(): Long {
return minBufferUs
}

override fun retainBackBufferFromKeyframe(): Boolean {
return false
}

override fun shouldContinueLoading(
playbackPositionUs: Long, bufferedDurationUs: Long, playbackSpeed: Float
): Boolean {
val wasLoading = isLoading

computeIsBuffering(bufferedDurationUs)

if (isLoading != wasLoading) {
if (isLoading) {
priorityTaskManager?.add(C.PRIORITY_PLAYBACK)
} else {
priorityTaskManager?.remove(C.PRIORITY_PLAYBACK)
}
}

return isLoading
}

override fun shouldStartPlayback(
bufferedDurationUs: Long,
playbackSpeed: Float,
rebuffering: Boolean,
targetLiveOffsetUs: Long
): Boolean {
val minBufferDurationUs = if (rebuffering) {
bufferForPlaybackAfterRebufferUs
} else {
this.bufferForPlaybackUs
}
return minBufferDurationUs <= 0 || bufferedDurationUs >= minBufferDurationUs
}

private fun reset(resetAllocator: Boolean) {
targetBufferBytes = 0
if (isLoading) {
priorityTaskManager?.remove(C.PRIORITY_PLAYBACK)
}
isLoading = false
if (resetAllocator) {
allocator.reset()
}
}

private fun getDefaultBufferSize(trackType: @TrackType Int): Int {
return when (trackType) {
C.TRACK_TYPE_DEFAULT -> DEFAULT_MUXED_BUFFER_SIZE
C.TRACK_TYPE_AUDIO -> DEFAULT_AUDIO_BUFFER_SIZE
C.TRACK_TYPE_VIDEO -> DEFAULT_VIDEO_BUFFER_SIZE
C.TRACK_TYPE_TEXT -> DEFAULT_TEXT_BUFFER_SIZE
C.TRACK_TYPE_METADATA -> DEFAULT_METADATA_BUFFER_SIZE
C.TRACK_TYPE_CAMERA_MOTION -> DEFAULT_CAMERA_MOTION_BUFFER_SIZE
C.TRACK_TYPE_IMAGE -> DEFAULT_IMAGE_BUFFER_SIZE
C.TRACK_TYPE_NONE -> 0
C.TRACK_TYPE_UNKNOWN -> throw IllegalArgumentException()
else -> throw IllegalArgumentException()
}
}

private fun getBufferTimeState(bufferedDurationUs: Long): Int {
return if (bufferedDurationUs > maxBufferUs) {
ABOVE_HIGH_WATERMARK
} else {
if (bufferedDurationUs < minBufferUs) {
BELOW_LOW_WATERMARK
} else {
BETWEEN_WATERMARKS
}
}
}

private fun computeIsBuffering(bufferedDurationUs: Long) {
val bufferTimeState = getBufferTimeState(bufferedDurationUs)
val targetBufferSizeReached = allocator.totalBytesAllocated >= targetBufferBytes

isLoading = when (bufferTimeState) {
BELOW_LOW_WATERMARK -> true
BETWEEN_WATERMARKS -> !targetBufferSizeReached
else -> false
}
}

companion object {
/**
* The default minimum duration of media that the player will attempt to ensure is buffered at all
* times, in milliseconds.
*/
const val DEFAULT_MIN_BUFFER_MS = 50000

/**
* The default maximum duration of media that the player will attempt to buffer, in milliseconds.
*/
const val DEFAULT_MAX_BUFFER_MS = 50000

/**
* The default duration of media that must be buffered for playback to start or resume following a
* user action such as a seek, in milliseconds.
*/
const val DEFAULT_BUFFER_FOR_PLAYBACK_MS = 2500

/**
* The default duration of media that must be buffered for playback to resume after a rebuffer, in
* milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user action.
*/
const val DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 5000

/** A default size in bytes for a video buffer. */
const val DEFAULT_VIDEO_BUFFER_SIZE = 8000 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for an audio buffer. */
const val DEFAULT_AUDIO_BUFFER_SIZE = 200 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for a text buffer. */
const val DEFAULT_TEXT_BUFFER_SIZE = 2 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for a metadata buffer. */
const val DEFAULT_METADATA_BUFFER_SIZE = 2 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for a camera motion buffer. */
const val DEFAULT_CAMERA_MOTION_BUFFER_SIZE = 2 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for an image buffer. */
const val DEFAULT_IMAGE_BUFFER_SIZE = 2 * C.DEFAULT_BUFFER_SEGMENT_SIZE

/** A default size in bytes for a muxed buffer (e.g. containing video, audio and text). */
const val DEFAULT_MUXED_BUFFER_SIZE = DEFAULT_VIDEO_BUFFER_SIZE + DEFAULT_AUDIO_BUFFER_SIZE + DEFAULT_TEXT_BUFFER_SIZE

const val ABOVE_HIGH_WATERMARK = 0
const val BETWEEN_WATERMARKS = 1
const val BELOW_LOW_WATERMARK = 2

const val VIDEO_BUFFER_SCALE_UP_FACTOR = 8
}
}
8 changes: 4 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ buildscript {
maven { url = uri("https://plugins.gradle.org/m2/") }
}
dependencies {
classpath("com.android.tools.build:gradle:7.2.1")
classpath("com.android.tools.build:gradle:7.2.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.5.0")
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.5.3")
classpath("com.google.dagger:hilt-android-gradle-plugin:2.42")
classpath("org.jetbrains.kotlin:kotlin-serialization:1.6.21")
classpath("com.google.protobuf:protobuf-gradle-plugin:0.8.19")
classpath("io.michaelrocks:paranoid-gradle-plugin:0.3.7")
classpath("com.klaxit.hiddensecrets:HiddenSecretsPlugin:0.2.0")
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:10.3.1")
classpath("com.klaxit.hiddensecrets:HiddenSecretsPlugin:0.2.1")
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:10.5.1")

// wait for https://github.com/Faire/gradle-kotlin-buildozer/pull/13
}
Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/Configuration.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Configuration {
const val buildTools = "30.0.3"
const val compileSdk = 32
const val compileSdk = 33
const val minSdk = 21
const val targetSdk = 32
const val targetSdk = 33
}
12 changes: 6 additions & 6 deletions database/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ android {
dependencies {
implementation(project(mapOf("path" to ":model")))

implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.appcompat:appcompat:1.4.2")
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.5.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")

api("androidx.room:room-runtime:2.4.2")
api("androidx.room:room-ktx:2.4.2")
kapt("androidx.room:room-compiler:2.4.2")
api("androidx.room:room-runtime:2.4.3")
api("androidx.room:room-ktx:2.4.3")
kapt("androidx.room:room-compiler:2.4.3")

implementation("javax.inject:javax.inject:1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
4 changes: 2 additions & 2 deletions datastore/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ android {
}

dependencies {
implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.appcompat:appcompat:1.4.2")
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.5.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
Expand Down
Loading

0 comments on commit cd82de3

Please sign in to comment.