#115 changed video thumbnail strategy

This commit is contained in:
Thibault Deckers 2021-11-08 17:23:35 +09:00
parent 2d8d49a282
commit d43a6f1865
2 changed files with 26 additions and 14 deletions

View file

@ -3,7 +3,6 @@ package deckers.thibault.aves.decoder
import android.content.Context
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.Registry
@ -58,16 +57,13 @@ internal class VideoThumbnailFetcher(private val model: VideoThumbnail) : DataFe
try {
var bytes = retriever.embeddedPicture
if (bytes == null) {
// try to match the thumbnails returned by the content resolver / Media Store
// the following strategies are from empirical evidence from a few test devices:
// - API 29: sync frame closest to the middle
// - API 26/27: default representative frame at any time position
// there is no consistent strategy across devices to match
// the thumbnails returned by the content resolver / Media Store
// so we derive one in an arbitrary way
var timeMillis: Long? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val durationMillis = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull()
if (durationMillis != null) {
timeMillis = durationMillis / 2
}
val durationMillis = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull()
if (durationMillis != null) {
timeMillis = if (durationMillis < 15000) 0 else 15000
}
val frame = if (timeMillis != null) {
retriever.getFrameAtTime(timeMillis * 1000)

View file

@ -94,18 +94,34 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
_lastException = null;
_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([
if (widget.progressive && !entry.isSvg)
if (lowQuality != null)
_ConditionalImageProvider(
ScrollAwareImageProvider(
context: _scrollAwareContext,
imageProvider: entry.getThumbnail(),
imageProvider: lowQuality,
),
),
_ConditionalImageProvider(
ScrollAwareImageProvider(
context: _scrollAwareContext,
imageProvider: entry.getThumbnail(extent: extent),
imageProvider: highQuality,
),
_needSizedProvider,
),
@ -233,7 +249,7 @@ class _ThumbnailImageState extends State<ThumbnailImage> {
if (animate && widget.heroTag != null) {
final background = settings.imageBackground;
final backgroundColor = background.isColor? background.color : null;
final backgroundColor = background.isColor ? background.color : null;
image = Hero(
tag: widget.heroTag!,
flightShuttleBuilder: (flight, animation, direction, fromHero, toHero) {