#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.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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue