#115 changed video thumbnail strategy
This commit is contained in:
parent
2d8d49a282
commit
d43a6f1865
2 changed files with 26 additions and 14 deletions
|
@ -3,7 +3,6 @@ package deckers.thibault.aves.decoder
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.Priority
|
import com.bumptech.glide.Priority
|
||||||
import com.bumptech.glide.Registry
|
import com.bumptech.glide.Registry
|
||||||
|
@ -58,16 +57,13 @@ internal class VideoThumbnailFetcher(private val model: VideoThumbnail) : DataFe
|
||||||
try {
|
try {
|
||||||
var bytes = retriever.embeddedPicture
|
var bytes = retriever.embeddedPicture
|
||||||
if (bytes == null) {
|
if (bytes == null) {
|
||||||
// try to match the thumbnails returned by the content resolver / Media Store
|
// there is no consistent strategy across devices to match
|
||||||
// the following strategies are from empirical evidence from a few test devices:
|
// the thumbnails returned by the content resolver / Media Store
|
||||||
// - API 29: sync frame closest to the middle
|
// so we derive one in an arbitrary way
|
||||||
// - API 26/27: default representative frame at any time position
|
|
||||||
var timeMillis: Long? = null
|
var timeMillis: Long? = null
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
val durationMillis = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull()
|
val durationMillis = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull()
|
||||||
if (durationMillis != null) {
|
if (durationMillis != null) {
|
||||||
timeMillis = durationMillis / 2
|
timeMillis = if (durationMillis < 15000) 0 else 15000
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val frame = if (timeMillis != null) {
|
val frame = if (timeMillis != null) {
|
||||||
retriever.getFrameAtTime(timeMillis * 1000)
|
retriever.getFrameAtTime(timeMillis * 1000)
|
||||||
|
|
|
@ -94,18 +94,34 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
||||||
|
|
||||||
_lastException = null;
|
_lastException = null;
|
||||||
_providers.clear();
|
_providers.clear();
|
||||||
|
|
||||||
|
final highQuality = entry.getThumbnail(extent: extent);
|
||||||
|
ThumbnailProvider? lowQuality;
|
||||||
|
if (widget.progressive && !entry.isSvg) {
|
||||||
|
if (entry.isVideo) {
|
||||||
|
// previously fetched thumbnail
|
||||||
|
final cached = entry.bestCachedThumbnail;
|
||||||
|
final lowQualityExtent = cached.key.extent;
|
||||||
|
if (lowQualityExtent > 0 && lowQualityExtent != extent) {
|
||||||
|
lowQuality = cached;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// default platform thumbnail
|
||||||
|
lowQuality = entry.getThumbnail();
|
||||||
|
}
|
||||||
|
}
|
||||||
_providers.addAll([
|
_providers.addAll([
|
||||||
if (widget.progressive && !entry.isSvg)
|
if (lowQuality != null)
|
||||||
_ConditionalImageProvider(
|
_ConditionalImageProvider(
|
||||||
ScrollAwareImageProvider(
|
ScrollAwareImageProvider(
|
||||||
context: _scrollAwareContext,
|
context: _scrollAwareContext,
|
||||||
imageProvider: entry.getThumbnail(),
|
imageProvider: lowQuality,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_ConditionalImageProvider(
|
_ConditionalImageProvider(
|
||||||
ScrollAwareImageProvider(
|
ScrollAwareImageProvider(
|
||||||
context: _scrollAwareContext,
|
context: _scrollAwareContext,
|
||||||
imageProvider: entry.getThumbnail(extent: extent),
|
imageProvider: highQuality,
|
||||||
),
|
),
|
||||||
_needSizedProvider,
|
_needSizedProvider,
|
||||||
),
|
),
|
||||||
|
@ -233,7 +249,7 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
|
||||||
|
|
||||||
if (animate && widget.heroTag != null) {
|
if (animate && widget.heroTag != null) {
|
||||||
final background = settings.imageBackground;
|
final background = settings.imageBackground;
|
||||||
final backgroundColor = background.isColor? background.color : null;
|
final backgroundColor = background.isColor ? background.color : null;
|
||||||
image = Hero(
|
image = Hero(
|
||||||
tag: widget.heroTag!,
|
tag: widget.heroTag!,
|
||||||
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {
|
||||||
|
|
Loading…
Reference in a new issue