diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt index 8e628723f..18f9b70d4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt @@ -801,7 +801,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener { return } - val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths) + val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths, false) val newDir = if (curMedia.isEmpty()) { if (directory.path != tempFolderPath) { dirPathsToRemove.add(directory.path) @@ -874,7 +874,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener { return } - val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths) + val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly, getProperDateTaken, favoritePaths, false) if (newMedia.isEmpty()) { continue } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt index 7199811e9..6ab3b2478 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt @@ -111,7 +111,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList } mIsVideo = type == TYPE_VIDEOS - mMedium = Medium(null, filename, mUri.toString(), mUri!!.path.getParentPath(), 0, 0, file.length(), type, false, 0L) + mMedium = Medium(null, filename, mUri.toString(), mUri!!.path.getParentPath(), 0, 0, file.length(), type, 0, false, 0L) supportActionBar?.title = mMedium!!.name bundle.putSerializable(MEDIUM, mMedium) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt index e48ac8b4c..8731f0a30 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt @@ -460,7 +460,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList() foldersToScan.forEach { - val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, favoritePaths) + val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, favoritePaths, getVideoDurations) media.addAll(newMedia) } mediaFetcher.sortMedia(media, context.config.getFileSorting(SHOW_ALL)) media } else { - mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo, getProperDateTaken, favoritePaths) + mediaFetcher.getFilesFrom(mPath, isPickImage, isPickVideo, getProperDateTaken, favoritePaths, getVideoDurations) } return mediaFetcher.groupMedia(media, pathToUse) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/databases/GalleryDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/databases/GalleryDatabase.kt index 63873e0cc..d6412cda5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/databases/GalleryDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/databases/GalleryDatabase.kt @@ -4,12 +4,14 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao import com.simplemobiletools.gallery.pro.interfaces.MediumDao import com.simplemobiletools.gallery.pro.models.Directory import com.simplemobiletools.gallery.pro.models.Medium -@Database(entities = [Directory::class, Medium::class], version = 4) +@Database(entities = [Directory::class, Medium::class], version = 5) abstract class GalleryDatabase : RoomDatabase() { abstract fun DirectoryDao(): DirectoryDao @@ -24,7 +26,7 @@ abstract class GalleryDatabase : RoomDatabase() { synchronized(GalleryDatabase::class) { if (db == null) { db = Room.databaseBuilder(context.applicationContext, GalleryDatabase::class.java, "gallery.db") - .fallbackToDestructiveMigration() + .addMigrations(MIGRATION_4_5) .build() } } @@ -35,5 +37,11 @@ abstract class GalleryDatabase : RoomDatabase() { fun destroyInstance() { db = null } + + private val MIGRATION_4_5 = object : Migration(4, 5) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE media ADD COLUMN video_duration INTEGER default 0 NOT NULL") + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/String.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/String.kt index 4e5808a33..ee08503bf 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/String.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/String.kt @@ -1,5 +1,6 @@ package com.simplemobiletools.gallery.pro.extensions +import android.media.MediaMetadataRetriever import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.helpers.OTG_PATH import java.io.File @@ -43,3 +44,14 @@ fun String.getDistinctPath(): String { toLowerCase() } } + +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 +} diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt index e03c00f4f..4e10c5038 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt @@ -523,7 +523,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S } private fun setupVideoDuration() { - mDuration = medium.getVideoDuration() + mDuration = medium.path.getVideoDuration() setupTimeHolder() setPosition(0) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt index 77c116a6a..c9f644991 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt @@ -18,7 +18,8 @@ import java.util.* class MediaFetcher(val context: Context) { var shouldStop = false - fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean, favoritePaths: ArrayList): ArrayList { + fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean, getProperDateTaken: Boolean, favoritePaths: ArrayList, + getVideoDurations: Boolean): ArrayList { val filterMedia = context.config.filterMedia if (filterMedia == 0) { return ArrayList() @@ -26,10 +27,10 @@ class MediaFetcher(val context: Context) { val curMedia = ArrayList() if (curPath.startsWith(OTG_PATH)) { - val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia, favoritePaths) + val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia, favoritePaths, getVideoDurations) curMedia.addAll(newMedia) } else { - val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken, favoritePaths) + val newMedia = getMediaInFolder(curPath, isPickImage, isPickVideo, filterMedia, getProperDateTaken, favoritePaths, getVideoDurations) curMedia.addAll(newMedia) } @@ -167,7 +168,7 @@ class MediaFetcher(val context: Context) { } private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, getProperDateTaken: Boolean, - favoritePaths: ArrayList): ArrayList { + favoritePaths: ArrayList, getVideoDurations: Boolean): ArrayList { val media = ArrayList() val deletedMedia = if (folder == RECYCLE_BIN) { @@ -231,6 +232,7 @@ class MediaFetcher(val context: Context) { } else { val lastModified = file.lastModified() var dateTaken = lastModified + val videoDuration = if (getVideoDurations) path.getVideoDuration() else 0 if (getProperDateTaken) { dateTaken = dateTakens.remove(filename) ?: lastModified @@ -245,14 +247,15 @@ class MediaFetcher(val context: Context) { } val isFavorite = favoritePaths.contains(path) - val medium = Medium(null, filename, path, file.parent, lastModified, dateTaken, size, type, isFavorite, 0L) + val medium = Medium(null, filename, path, file.parent, lastModified, dateTaken, size, type, videoDuration, isFavorite, 0L) media.add(medium) } } return media } - private fun getMediaOnOTG(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, favoritePaths: ArrayList): ArrayList { + private fun getMediaOnOTG(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int, favoritePaths: ArrayList, + getVideoDurations: Boolean): ArrayList { val media = ArrayList() val files = context.getDocumentFile(folder)?.listFiles() ?: return media val doExtraCheck = context.config.doExtraCheck @@ -307,8 +310,9 @@ class MediaFetcher(val context: Context) { } val path = Uri.decode(file.uri.toString().replaceFirst("${context.config.OTGTreeUri}/document/${context.config.OTGPartition}%3A", OTG_PATH)) + val videoDuration = if (getVideoDurations) path.getVideoDuration() else 0 val isFavorite = favoritePaths.contains(path) - val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type, isFavorite, 0L) + val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type, videoDuration, isFavorite, 0L) media.add(medium) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/MediumDao.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/MediumDao.kt index bf2d68d9f..d0436d877 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/MediumDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/MediumDao.kt @@ -9,16 +9,16 @@ import com.simplemobiletools.gallery.pro.models.Medium @Dao interface MediumDao { - @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, is_favorite, deleted_ts FROM media WHERE deleted_ts = 0 AND parent_path = :path COLLATE NOCASE") + @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, video_duration, is_favorite, deleted_ts FROM media WHERE deleted_ts = 0 AND parent_path = :path COLLATE NOCASE") fun getMediaFromPath(path: String): List - @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, is_favorite, deleted_ts FROM media WHERE deleted_ts = 0 AND is_favorite = 1") + @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, video_duration, is_favorite, deleted_ts FROM media WHERE deleted_ts = 0 AND is_favorite = 1") fun getFavorites(): List @Query("SELECT full_path FROM media WHERE deleted_ts = 0 AND is_favorite = 1") fun getFavoritePaths(): List - @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, is_favorite, deleted_ts FROM media WHERE deleted_ts != 0") + @Query("SELECT filename, full_path, parent_path, last_modified, date_taken, size, type, video_duration, is_favorite, deleted_ts FROM media WHERE deleted_ts != 0") fun getDeletedMedia(): List @Insert(onConflict = REPLACE) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Medium.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Medium.kt index 730dc0dcf..e6d95da66 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Medium.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Medium.kt @@ -1,6 +1,5 @@ package com.simplemobiletools.gallery.pro.models -import android.media.MediaMetadataRetriever import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Index @@ -26,6 +25,7 @@ data class Medium( @ColumnInfo(name = "date_taken") var taken: Long, @ColumnInfo(name = "size") val size: Long, @ColumnInfo(name = "type") val type: Int, + @ColumnInfo(name = "video_duration") val videoDuration: Int, @ColumnInfo(name = "is_favorite") var isFavorite: Boolean, @ColumnInfo(name = "deleted_ts") var deletedTS: Long) : Serializable, ThumbnailItem() { @@ -77,17 +77,4 @@ data class Medium( return calendar.timeInMillis.toString() } - - fun getVideoDuration(): Int { - var seconds = 0 - try { - if (isVideo()) { - val retriever = MediaMetadataRetriever() - retriever.setDataSource(path) - seconds = Math.round(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt() / 1000f) - } - } catch (e: Exception) { - } - return seconds - } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/receivers/RefreshMediaReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/receivers/RefreshMediaReceiver.kt index 01e4591e2..3e3f35ec9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/receivers/RefreshMediaReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/receivers/RefreshMediaReceiver.kt @@ -16,7 +16,7 @@ class RefreshMediaReceiver : BroadcastReceiver() { Thread { val medium = Medium(null, path.getFilenameFromPath(), path, path.getParentPath(), System.currentTimeMillis(), System.currentTimeMillis(), - File(path).length(), getFileType(path), false, 0L) + File(path).length(), getFileType(path), 0, false, 0L) context.galleryDB.MediumDao().insert(medium) }.start() }