gpt4 book ai didi

android - Exoplayer 搜索栏预览

转载 作者:行者123 更新时间:2023-12-03 23:07:02 26 4
gpt4 key购买 nike

我正在尝试在我的 exoplayer 上向我的搜索栏添加预览,就像在 youtube 或 plex 中一样(见下图)

enter image description here

我找到了 library但它还不是最新的。

我已经有了每帧的图像,但我不知道如何将它们集成到我的 Exoplayer 中,我正在寻找应该从哪里开始的教程或解释,因为我有点迷路了。

我找到了 Timebar.onScrubListener 在浏览 exoplayer 文档时。我猜我将使用这 3 个监听器来获取擦洗的位置并显示相应的图像。

最佳答案

更新:library截至 2020 年 5 月是最新的,因此您可以直接使用它。
我将在下面为那些不想使用该库的人留下代码。

在搜索并调整它以适应我的需要后,我通过查看 previewSeekBar 的方式找到了一种方法。正在做,我最终使用了同样的东西,所以这里是:
我的 Sprite 由 10 列和 6 行组成,每个方 block 代表 1 秒
滑翔变换

private const val MAX_LINES = 6
private const val MAX_COLUMNS = 10
private const val THUMBNAILS_EACH = 1000 // milliseconds
private const val ONE_MINUTE = 60000 // one minute in millisecond

class GlideThumbnailTransformation(position: Long) : BitmapTransformation() {

private val x: Int
private val y: Int

init {
// Remainder of position on one minute because we just need to know which square of the current miniature
val square = position.rem(ONE_MINUTE).toInt() / THUMBNAILS_EACH
y = square / MAX_COLUMNS
x = square % MAX_COLUMNS
}

override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
val width = toTransform.width / MAX_COLUMNS
val height = toTransform.height / MAX_LINES
return Bitmap.createBitmap(toTransform, x * width, y * height, width, height)
}

override fun updateDiskCacheKey(messageDigest: MessageDigest) {
val data: ByteArray = ByteBuffer.allocate(8).putInt(x).putInt(y).array()
messageDigest.update(data)
}

override fun hashCode(): Int {
return (x.toString() + y.toString()).hashCode()
}

override fun equals(other: Any?): Boolean {
if (other !is GlideThumbnailTransformation) {
return false
}
return other.x == x && other.y == y
}
}
Activity

val thumbnailUrl = "https://bitdash-a.akamaihd.net/content/MI201109210084_1/thumbnails/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.jpg"
exo_progress.addListener(object : TimeBar.OnScrubListener {
override fun onScrubMove(timeBar: TimeBar, position: Long) {
previewFrameLayout.visibility = View.VISIBLE
val targetX = updatePreviewX(position.toInt(), exoPlayer.duration.toInt())
previewFrameLayout.x = targetX.toFloat()
GlideApp.with(scrubbingPreview)
.load(thumbnailUrl)
.override(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL)
.transform(GlideThumbnailTransformation(position))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(scrubbingPreview)
}

override fun onScrubStop(timeBar: TimeBar, position: Long, canceled: Boolean) {
previewFrameLayout.visibility = View.INVISIBLE
}

override fun onScrubStart(timeBar: TimeBar, position: Long) {}
})

private fun updatePreviewX(progress: Int, max: Int): Int {
if (max == 0) { return 0 }

val parent = previewFrameLayout.parent as ViewGroup
val layoutParams = previewFrameLayout.layoutParams as MarginLayoutParams
val offset = progress.toFloat() / max
val minimumX: Int = previewFrameLayout.left
val maximumX = (parent.width - parent.paddingRight - layoutParams.rightMargin)

// We remove the padding of the scrubbing, if you have a custom size juste use dimen to calculate this
val previewPaddingRadius: Int = dpToPx(resources.displayMetrics, DefaultTimeBar.DEFAULT_SCRUBBER_DRAGGED_SIZE_DP).div(2)
val previewLeftX = (exo_progress as View).left.toFloat()
val previewRightX = (exo_progress as View).right.toFloat()
val previewSeekBarStartX: Float = previewLeftX + previewPaddingRadius
val previewSeekBarEndX: Float = previewRightX - previewPaddingRadius
val currentX = (previewSeekBarStartX + (previewSeekBarEndX - previewSeekBarStartX) * offset)
val startX: Float = currentX - previewFrameLayout.width / 2f
val endX: Float = startX + previewFrameLayout.width

// Clamp the moves
return if (startX >= minimumX && endX <= maximumX) {
startX.toInt()
} else if (startX < minimumX) {
minimumX
} else {
maximumX - previewFrameLayout.width
}
}

private fun dpToPx(displayMetrics: DisplayMetrics, dps: Int): Int {
return (dps * displayMetrics.density).toInt()
}
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_gravity="bottom"
android:layoutDirection="ltr"
android:background="#CC000000"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="4dp"
android:orientation="horizontal"
android:id="@+id/controlsLayout"
app:layout_constraintBottom_toBottomOf="parent">

<ImageButton android:id="@id/exo_prev"
style="@style/ExoMediaButton.Previous"/>

<ImageButton android:id="@id/exo_rew"
style="@style/ExoMediaButton.Rewind"/>

<ImageButton android:id="@id/exo_repeat_toggle"
style="@style/ExoMediaButton"/>

<ImageButton android:id="@id/exo_play"
style="@style/ExoMediaButton.Play"/>

<ImageButton android:id="@id/exo_pause"
style="@style/ExoMediaButton.Pause"/>

<ImageButton android:id="@id/exo_ffwd"
style="@style/ExoMediaButton.FastForward"/>

<ImageButton android:id="@id/exo_next"
style="@style/ExoMediaButton.Next"/>

</LinearLayout>

<TextView android:id="@id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"
app:layout_constraintBottom_toTopOf="@id/controlsLayout"
app:layout_constraintStart_toStartOf="parent"/>

<FrameLayout
android:id="@+id/previewFrameLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:background="@drawable/video_frame"
android:padding="2dp"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/exo_progress"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.25"
tools:visibility="visible">

<ImageView
android:id="@+id/scrubbingPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />

</FrameLayout>

<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="26dp"
app:layout_constraintBottom_toBottomOf="@id/exo_position"
app:layout_constraintEnd_toStartOf="@id/exo_duration"
app:layout_constraintStart_toEndOf="@+id/exo_position"
app:layout_constraintTop_toTopOf="@+id/exo_position"/>

<TextView android:id="@id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"
app:layout_constraintBaseline_toBaselineOf="@id/exo_position"
app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
可绘制/视频帧
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@android:color/white" />

<solid android:color="@android:color/black" />
</shape>
可能会有一些改进,所以请随时发表评论

关于android - Exoplayer 搜索栏预览,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61887784/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com