more fixes

This commit is contained in:
deniscerri 2023-04-15 14:15:55 +02:00
parent 9a50b85d85
commit 525a37475c
No known key found for this signature in database
GPG key ID: 95C43D517D830350
3 changed files with 105 additions and 16 deletions

View file

@ -14,6 +14,9 @@ try {
}catch(IOException ignored){}
android {
namespace 'com.deniscerri.ytdlnis'
compileSdk 33
signingConfigs {
debug {
storeFile file(properties["signingConfig.storeFile"])
@ -22,11 +25,10 @@ android {
keyPassword properties["signingConfig.keyPassword"]
}
}
compileSdkVersion 33
defaultConfig {
applicationId "com.deniscerri.ytdl"
minSdkVersion 23
targetSdkVersion 33
minSdk 23
targetSdk 33
versionCode project.versionCode
versionName project.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -106,7 +108,6 @@ android {
composeOptions {
kotlinCompilerExtensionVersion composeVer
}
namespace 'com.deniscerri.ytdlnis'
}

View file

@ -8,14 +8,12 @@ import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.core.view.forEach
import androidx.lifecycle.lifecycleScope
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.ChapterItem
@ -23,13 +21,28 @@ import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.InfoUtil
import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.DefaultRenderersFactory
import com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem.fromUri
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.database.DatabaseProvider
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.MergingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.ui.PlayerView
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
import com.google.android.exoplayer2.upstream.cache.SimpleCache
import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.exoplayer2.util.Util
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.card.MaterialCardView
@ -47,6 +60,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.lang.reflect.Type
import java.util.*
import kotlin.properties.Delegates
@ -60,6 +74,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
private lateinit var player: Player
private lateinit var cutSection : ConstraintLayout
private lateinit var durationText: TextView
private lateinit var progress : ProgressBar
private lateinit var rangeSlider : RangeSlider
private lateinit var fromTextInput : TextInputLayout
@ -78,6 +93,8 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
private lateinit var chapters: List<ChapterItem>
private lateinit var selectedCuts: MutableList<String>
private lateinit var cache: SimpleCache
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -100,7 +117,52 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
behavior.peekHeight = displayMetrics.heightPixels / 2
}
player = ExoPlayer.Builder(requireContext()).build()
val renderersFactory = DefaultRenderersFactory(requireContext().applicationContext)
.setEnableDecoderFallback(true)
.setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER)
.setMediaCodecSelector { mimeType, requiresSecureDecoder, requiresTunnelingDecoder ->
var decoderInfos: MutableList<MediaCodecInfo> =
MediaCodecSelector.DEFAULT
.getDecoderInfos(
mimeType,
requiresSecureDecoder,
requiresTunnelingDecoder
)
if (MimeTypes.VIDEO_H264 == mimeType) {
// copy the list because MediaCodecSelector.DEFAULT returns an unmodifiable list
decoderInfos = ArrayList(decoderInfos)
decoderInfos.reverse()
}
decoderInfos
}
val trackSelector = DefaultTrackSelector()
val loadControl = DefaultLoadControl()
// Specify cache folder, my cache folder named media which is inside getCacheDir.
val cacheFolder = File(requireContext().cacheDir, "media")
// Specify cache size and removing policies
val cacheEvictor = LeastRecentlyUsedCacheEvictor(1 * 1024 * 1024) // My cache size will be 1MB and it will automatically remove least recently used files if the size is reached out.
// Build cache
val databaseProvider: DatabaseProvider = StandaloneDatabaseProvider(requireContext())
cache = SimpleCache(cacheFolder, cacheEvictor, databaseProvider)
// Build data source factory with cache enabled, if data is available in cache it will return immediately, otherwise it will open a new connection to get the data.
val defaultDataSourceFactory = DefaultDataSourceFactory(
requireContext(),
Util.getUserAgent(requireContext(), requireContext().getString(R.string.app_name))
)
val cacheDataSourceFactory = CacheDataSource.Factory()
.setCache(cache)
.setUpstreamDataSourceFactory(defaultDataSourceFactory)
player = ExoPlayer.Builder(requireContext(), renderersFactory)
.setTrackSelector(trackSelector)
.setLoadControl(loadControl)
.build()
val frame = view.findViewById<MaterialCardView>(R.id.frame_layout)
val videoView = view.findViewById<PlayerView>(R.id.video_view)
videoView.player = player
@ -109,6 +171,8 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
//cut section
cutSection = view.findViewById(R.id.cut_section)
durationText = view.findViewById(R.id.durationText)
durationText.text = ""
progress = view.findViewById(R.id.progress)
rangeSlider = view.findViewById(R.id.rangeSlider)
fromTextInput = view.findViewById(R.id.from_textinput)
@ -154,16 +218,17 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
if (data.isEmpty()) throw Exception("No Streaming URL found!")
if (data.size == 2){
val audioSource: MediaSource =
DefaultMediaSourceFactory(requireContext())
val audioSource : MediaSource =
ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(fromUri(Uri.parse(data[0])))
val videoSource: MediaSource =
DefaultMediaSourceFactory(requireContext())
ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(fromUri(Uri.parse(data[1])))
(player as ExoPlayer).setMediaSource(MergingMediaSource(videoSource, audioSource))
}else{
player.addMediaItem(fromUri(Uri.parse(data[0])))
}
player.addMediaItem(fromUri(Uri.parse(data[0])))
progress.visibility = View.GONE
populateSuggestedChapters()
@ -180,18 +245,20 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
//poll video progress
lifecycleScope.launch {
videoProgress(player).collect {
val startTimestamp = (rangeSlider.valueFrom.toInt() * timeSeconds) / 100
val endTimestamp = (rangeSlider.valueTo.toInt() * timeSeconds) / 100
val currentTime = infoUtil.formatIntegerDuration(it, Locale.US)
durationText.text = "$currentTime / ${item.duration}"
val startTimestamp = convertStringToTimestamp(fromTextInput.editText!!.text.toString())
val endTimestamp = convertStringToTimestamp(toTextInput.editText!!.text.toString())
if (it >= endTimestamp){
player.prepare()
player.seekTo((startTimestamp * 1000).toLong())
}
}
}
videoView.setOnClickListener {
if (player.isPlaying) player.stop()
if (player.isPlaying) player.pause()
else {
player.prepare()
player.play()
}
}
@ -479,7 +546,6 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
private fun convertStringToTimestamp(duration: String): Int {
return try {
val timeArray = duration.split(":")
Log.e("aa", timeArray.toString())
var timeSeconds = timeArray[timeArray.lastIndex].toInt()
var times = 60
for (i in timeArray.lastIndex - 1 downTo 0) {
@ -506,6 +572,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private val list
private fun cleanUp(){
player.stop()
cache.release()
parentFragmentManager.beginTransaction().remove(parentFragmentManager.findFragmentByTag("cutVideoSheet")!!).commit()
}
}

View file

@ -39,6 +39,27 @@
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/durationText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#80000000"
android:clickable="false"
android:ellipsize="end"
android:gravity="center"
android:maxLength="17"
android:maxLines="1"
android:minWidth="30dp"
android:paddingHorizontal="5dp"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold"
app:cornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="@+id/frame_layout"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cut_section"
android:visibility="gone"