improving the way video durations are fetched, should be a lot quicker

This commit is contained in:
tibbi 2020-05-04 11:04:34 +02:00
parent a4c1da2ac6
commit 69addc428a
6 changed files with 53 additions and 65 deletions

View file

@ -78,7 +78,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:5.27.2' implementation 'com.simplemobiletools:commons:5.27.3'
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'it.sephiroth.android.exif:library:1.0.1' implementation 'it.sephiroth.android.exif:library:1.0.1'

View file

@ -389,7 +389,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
val isFavorite = favoritesDB.isFavorite(mPath) val isFavorite = favoritesDB.isFavorite(mPath)
val duration = if (type == TYPE_VIDEOS) mPath.getVideoDuration() else 0 val duration = if (type == TYPE_VIDEOS) getVideoDuration(mPath) ?: 0 else 0
val ts = System.currentTimeMillis() val ts = System.currentTimeMillis()
val medium = Medium(null, mPath.getFilenameFromPath(), mPath, mPath.getParentPath(), ts, ts, File(mPath).length(), type, duration, isFavorite, 0) val medium = Medium(null, mPath.getFilenameFromPath(), mPath, mPath.getParentPath(), ts, ts, File(mPath).length(), type, duration, isFavorite, 0)
mediaDB.insert(medium) mediaDB.insert(medium)

View file

@ -216,16 +216,16 @@ fun Context.getDirectParentSubfolders(dirs: ArrayList<Directory>, currentPathPre
} }
val directory = Directory(newDirId++, val directory = Directory(newDirId++,
parent, parent,
subDirs.first().tmb, subDirs.first().tmb,
getFolderNameFromPath(parent), getFolderNameFromPath(parent),
subDirs.sumBy { it.mediaCnt }, subDirs.sumBy { it.mediaCnt },
lastModified, lastModified,
dateTaken, dateTaken,
subDirs.sumByLong { it.size }, subDirs.sumByLong { it.size },
getPathLocation(parent), getPathLocation(parent),
mediaTypes, mediaTypes,
"") "")
directory.containsMediaFilesDirectly = false directory.containsMediaFilesDirectly = false
dirs.add(directory) dirs.add(directory)
@ -442,15 +442,15 @@ fun Context.getPathLocation(path: String): Int {
fun Context.loadPng(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) { fun Context.loadPng(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) {
val options = RequestOptions() val options = RequestOptions()
.signature(path.getFileSignature()) .signature(path.getFileSignature())
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true) .skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.priority(Priority.LOW) .priority(Priority.LOW)
.format(DecodeFormat.PREFER_ARGB_8888) .format(DecodeFormat.PREFER_ARGB_8888)
val builder = Glide.with(applicationContext) val builder = Glide.with(applicationContext)
.asBitmap() .asBitmap()
.load(path) .load(path)
if (cropThumbnails) options.centerCrop() else options.fitCenter() if (cropThumbnails) options.centerCrop() else options.fitCenter()
builder.apply(options).into(target) builder.apply(options).into(target)
@ -458,34 +458,34 @@ fun Context.loadPng(path: String, target: MySquareImageView, cropThumbnails: Boo
fun Context.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) { fun Context.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) {
val options = RequestOptions() val options = RequestOptions()
.signature(path.getFileSignature()) .signature(path.getFileSignature())
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true) .skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.priority(Priority.LOW) .priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
val builder = Glide.with(applicationContext) val builder = Glide.with(applicationContext)
.load(path) .load(path)
if (cropThumbnails) options.centerCrop() else options.fitCenter() if (cropThumbnails) options.centerCrop() else options.fitCenter()
builder.apply(options) builder.apply(options)
.transition(DrawableTransitionOptions.withCrossFade()) .transition(DrawableTransitionOptions.withCrossFade())
.into(target) .into(target)
} }
fun Context.loadStaticGIF(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) { fun Context.loadStaticGIF(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = null) {
val options = RequestOptions() val options = RequestOptions()
.signature(path.getFileSignature()) .signature(path.getFileSignature())
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true) .skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.priority(Priority.LOW) .priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
val builder = Glide.with(applicationContext) val builder = Glide.with(applicationContext)
.asBitmap() // make sure the GIF wont animate .asBitmap() // make sure the GIF wont animate
.load(path) .load(path)
if (cropThumbnails) options.centerCrop() else options.fitCenter() if (cropThumbnails) options.centerCrop() else options.fitCenter()
builder.apply(options) builder.apply(options)
.into(target) .into(target)
} }
fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boolean) { fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
@ -493,12 +493,12 @@ fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boo
val options = RequestOptions().signature(path.getFileSignature()) val options = RequestOptions().signature(path.getFileSignature())
Glide.with(applicationContext) Glide.with(applicationContext)
.`as`(PictureDrawable::class.java) .`as`(PictureDrawable::class.java)
.listener(SvgSoftwareLayerSetter()) .listener(SvgSoftwareLayerSetter())
.load(path) .load(path)
.apply(options) .apply(options)
.transition(DrawableTransitionOptions.withCrossFade()) .transition(DrawableTransitionOptions.withCrossFade())
.into(target) .into(target)
} }
fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, forceShowHidden: Boolean = false, callback: (ArrayList<Directory>) -> Unit) { fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, forceShowHidden: Boolean = false, callback: (ArrayList<Directory>) -> Unit) {
@ -789,9 +789,9 @@ fun Context.addPathToDB(path: String) {
try { try {
val isFavorite = favoritesDB.isFavorite(path) val isFavorite = favoritesDB.isFavorite(path)
val videoDuration = if (type == TYPE_VIDEOS) path.getVideoDuration() else 0 val videoDuration = if (type == TYPE_VIDEOS) getVideoDuration(path) ?: 0 else 0
val medium = Medium(null, path.getFilenameFromPath(), path, path.getParentPath(), System.currentTimeMillis(), System.currentTimeMillis(), val medium = Medium(null, path.getFilenameFromPath(), path, path.getParentPath(), System.currentTimeMillis(), System.currentTimeMillis(),
File(path).length(), type, videoDuration, isFavorite, 0L) File(path).length(), type, videoDuration, isFavorite, 0L)
mediaDB.insert(medium) mediaDB.insert(medium)
} catch (ignored: Exception) { } catch (ignored: Exception) {
@ -888,7 +888,7 @@ fun Context.updateDirectoryPath(path: String) {
fun Context.getFileDateTaken(path: String): Long { fun Context.getFileDateTaken(path: String): Long {
val projection = arrayOf( val projection = arrayOf(
Images.Media.DATE_TAKEN Images.Media.DATE_TAKEN
) )
val uri = Files.getContentUri("external") val uri = Files.getContentUri("external")

View file

@ -1,7 +1,6 @@
package com.simplemobiletools.gallery.pro.extensions package com.simplemobiletools.gallery.pro.extensions
import android.content.Context import android.content.Context
import android.media.MediaMetadataRetriever
import android.os.Environment import android.os.Environment
import com.simplemobiletools.commons.extensions.containsNoMedia import com.simplemobiletools.commons.extensions.containsNoMedia
import com.simplemobiletools.commons.extensions.doesParentHaveNoMedia import com.simplemobiletools.commons.extensions.doesParentHaveNoMedia
@ -67,15 +66,4 @@ fun String.getDistinctPath(): String {
} }
} }
fun String.getVideoDuration(): Int {
var seconds = 0
try {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(this)
seconds = Math.round(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt() / 1000f)
} catch (e: Exception) {
}
return seconds
}
fun String.isDownloadsFolder() = equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(), true) fun String.isDownloadsFolder() = equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(), true)

View file

@ -29,7 +29,6 @@ import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity
import com.simplemobiletools.gallery.pro.activities.VideoActivity import com.simplemobiletools.gallery.pro.activities.VideoActivity
import com.simplemobiletools.gallery.pro.extensions.config import com.simplemobiletools.gallery.pro.extensions.config
import com.simplemobiletools.gallery.pro.extensions.getVideoDuration
import com.simplemobiletools.gallery.pro.extensions.hasNavBar import com.simplemobiletools.gallery.pro.extensions.hasNavBar
import com.simplemobiletools.gallery.pro.extensions.parseFileChannel import com.simplemobiletools.gallery.pro.extensions.parseFileChannel
import com.simplemobiletools.gallery.pro.helpers.* import com.simplemobiletools.gallery.pro.helpers.*
@ -688,7 +687,8 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun setupVideoDuration() { private fun setupVideoDuration() {
ensureBackgroundThread { ensureBackgroundThread {
mDuration = mMedium.path.getVideoDuration() mDuration = context?.getVideoDuration(mMedium.path) ?: 0
activity?.runOnUiThread { activity?.runOnUiThread {
setupTimeHolder() setupTimeHolder()
setPosition(0) setPosition(0)

View file

@ -49,9 +49,9 @@ class MediaFetcher(val context: Context) {
val OTGPath = context.config.OTGPath val OTGPath = context.config.OTGPath
val folders = getLatestFileFolders() val folders = getLatestFileFolders()
folders.addAll(arrayListOf( folders.addAll(arrayListOf(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString(), Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString(),
"${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)}/Camera", "${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)}/Camera",
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString() Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString()
).filter { context.getDoesFilePathExist(it, OTGPath) }) ).filter { context.getDoesFilePathExist(it, OTGPath) })
val filterMedia = context.config.filterMedia val filterMedia = context.config.filterMedia
@ -193,7 +193,7 @@ class MediaFetcher(val context: Context) {
val showHidden = config.shouldShowHidden val showHidden = config.shouldShowHidden
val excludedFolders = config.excludedFolders val excludedFolders = config.excludedFolders
return foldersToScan.distinctBy { it.getDistinctPath() } return foldersToScan.distinctBy { it.getDistinctPath() }
.filter { it.shouldFolderBeVisible(excludedFolders, includedFolders, showHidden, context) }.toMutableSet() as LinkedHashSet<String> .filter { it.shouldFolderBeVisible(excludedFolders, includedFolders, showHidden, context) }.toMutableSet() as LinkedHashSet<String>
} }
private fun addFolder(curFolders: HashSet<String>, folder: String) { private fun addFolder(curFolders: HashSet<String>, folder: String) {
@ -294,7 +294,7 @@ class MediaFetcher(val context: Context) {
} else { } else {
val lastModified = if (getProperLastModified) file.lastModified() else 0L val lastModified = if (getProperLastModified) file.lastModified() else 0L
var dateTaken = lastModified var dateTaken = lastModified
val videoDuration = if (getVideoDurations && isVideo) path.getVideoDuration() else 0 val videoDuration = if (getVideoDurations && isVideo) context.getVideoDuration(path) ?: 0 else 0
if (getProperDateTaken) { if (getProperDateTaken) {
var newDateTaken = dateTakens.remove(path) var newDateTaken = dateTakens.remove(path)
@ -383,7 +383,7 @@ class MediaFetcher(val context: Context) {
} }
val path = Uri.decode(file.uri.toString().replaceFirst("${context.config.OTGTreeUri}/document/${context.config.OTGPartition}%3A", "${context.config.OTGPath}/")) val path = Uri.decode(file.uri.toString().replaceFirst("${context.config.OTGTreeUri}/document/${context.config.OTGPartition}%3A", "${context.config.OTGPath}/"))
val videoDuration = if (getVideoDurations) path.getVideoDuration() else 0 val videoDuration = if (getVideoDurations) context.getVideoDuration(path) ?: 0 else 0
val isFavorite = favoritePaths.contains(path) val isFavorite = favoritePaths.contains(path)
val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type, videoDuration, isFavorite, 0L) val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type, videoDuration, isFavorite, 0L)
media.add(medium) media.add(medium)
@ -396,8 +396,8 @@ class MediaFetcher(val context: Context) {
val dateTakens = HashMap<String, Long>() val dateTakens = HashMap<String, Long>()
if (folder != FAVORITES) { if (folder != FAVORITES) {
val projection = arrayOf( val projection = arrayOf(
Images.Media.DISPLAY_NAME, Images.Media.DISPLAY_NAME,
Images.Media.DATE_TAKEN Images.Media.DATE_TAKEN
) )
val uri = Files.getContentUri("external") val uri = Files.getContentUri("external")
@ -494,7 +494,7 @@ class MediaFetcher(val context: Context) {
val sortDescending = currentGrouping and GROUP_DESCENDING != 0 val sortDescending = currentGrouping and GROUP_DESCENDING != 0
val sorted = if (currentGrouping and GROUP_BY_LAST_MODIFIED_DAILY != 0 || currentGrouping and GROUP_BY_LAST_MODIFIED_MONTHLY != 0 || val sorted = if (currentGrouping and GROUP_BY_LAST_MODIFIED_DAILY != 0 || currentGrouping and GROUP_BY_LAST_MODIFIED_MONTHLY != 0 ||
currentGrouping and GROUP_BY_DATE_TAKEN_DAILY != 0 || currentGrouping and GROUP_BY_DATE_TAKEN_MONTHLY != 0) { currentGrouping and GROUP_BY_DATE_TAKEN_DAILY != 0 || currentGrouping and GROUP_BY_DATE_TAKEN_MONTHLY != 0) {
mediumGroups.toSortedMap(if (sortDescending) compareByDescending { mediumGroups.toSortedMap(if (sortDescending) compareByDescending {
it.toLongOrNull() ?: 0L it.toLongOrNull() ?: 0L
} else { } else {