Skip to content

Commit

Permalink
功能优化: 增加添加扫描目录后视频扫描
Browse files Browse the repository at this point in the history
  • Loading branch information
xyoye committed Feb 4, 2024
1 parent fa3b9de commit 0b4b7cc
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import com.xyoye.common_component.resolver.MediaResolver
import com.xyoye.common_component.storage.AbstractStorage
import com.xyoye.common_component.storage.file.StorageFile
import com.xyoye.common_component.storage.file.impl.VideoStorageFile
import com.xyoye.common_component.utils.MediaUtils
import com.xyoye.common_component.utils.getFileName
import com.xyoye.common_component.utils.getFileNameNoExtension
import com.xyoye.common_component.utils.isDanmuFile
import com.xyoye.common_component.utils.isSubtitleFile
import com.xyoye.common_component.utils.meida.VideoScan
import com.xyoye.common_component.utils.subtitle.SubtitleFinder
import com.xyoye.data_component.bean.FolderBean
import com.xyoye.data_component.bean.LocalDanmuBean
Expand Down Expand Up @@ -126,7 +126,7 @@ class VideoStorage(library: MediaLibraryEntity) : AbstractStorage(library) {
private suspend fun deepRefresh() {
//系统视频数据 = 自定义扫描目录视频 + MediaStore中系统视频
val systemVideos = DatabaseManager.instance.getExtendFolderDao().getAll()
.flatMap { MediaUtils.scanVideoFile(it.folderPath) }
.flatMap { VideoScan.traverse(it.folderPath) }
.plus(MediaResolver.queryVideo())
.distinctBy { it.filePath }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteException
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import com.xyoye.common_component.base.app.BaseApplication
import com.xyoye.common_component.extension.isInvalid
import com.xyoye.common_component.extension.toText
import com.xyoye.common_component.utils.meida.VideoExtension
import com.xyoye.data_component.entity.VideoEntity
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
Expand Down Expand Up @@ -102,41 +99,6 @@ object MediaUtils {
}
}

/**
* 扫描文件夹内视频文件
*/
fun scanVideoFile(folderPath: String): MutableList<VideoEntity> {
val folderFile = File(folderPath)
if (!folderFile.exists())
return mutableListOf()

val childFileArray = folderFile.listFiles() ?: return mutableListOf()

val videoEntities = mutableListOf<VideoEntity>()
childFileArray.forEach {
if (it.isFile && isVideoFile(it.absolutePath)) {
videoEntities.add(
VideoEntity(
0,
0,
0,
it.absolutePath,
folderPath,
null,
null,
getVideoDuration(it),
it.length(),
isFilter = false,
isExtend = true
)
)
} else if (it.isDirectory) {
videoEntities.addAll(scanVideoFile(it.absolutePath))
}
}
return videoEntities
}

/**
* 获取Uri对应文件的真实路径
*/
Expand Down Expand Up @@ -203,22 +165,4 @@ object MediaUtils {
}
return false
}

private fun getVideoDuration(videoFile: File): Long {
if (videoFile.isInvalid()) {
return 0
}
val retriever = MediaMetadataRetriever()
return try {
retriever.setDataSource(BaseApplication.getAppContext(), Uri.fromFile(videoFile))
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
?.toLongOrNull()
?: 0
} catch (e: Exception) {
e.printStackTrace()
0
} finally {
retriever.release()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.xyoye.common_component.utils.meida

import android.media.MediaMetadataRetriever
import android.net.Uri
import com.xyoye.common_component.base.app.BaseApplication
import com.xyoye.common_component.extension.isInvalid
import com.xyoye.common_component.utils.isVideoFile
import com.xyoye.data_component.entity.VideoEntity
import java.io.File

/**
* Created by xyoye on 2024/2/4
*/

object VideoScan {

/**
* 遍历路径内的视频文件
*/
fun traverse(filePath: String): List<VideoEntity> {
return try {
traverse(File(filePath))
} catch (e: Exception) {
e.printStackTrace()
emptyList()
}
}

/**
* 遍历文件内的视频文件,包括文件自身
*/
private fun traverse(file: File): List<VideoEntity> {
if (file.isFile) {
return if (file.isInvalid()) {
return emptyList()
} else if (isVideoFile(file.absolutePath)) {
listOf(generateVideoEntity(file))
} else {
emptyList()
}
}

if (file.exists().not() || file.canRead().not()) {
return emptyList()
}
return file.listFiles()
?.flatMap { traverse(it) }
?: emptyList()
}

/**
* 生成视频数据库实体
*/
private fun generateVideoEntity(file: File): VideoEntity {
return VideoEntity(
0,
0,
0,
file.absolutePath,
file.parentFile?.absolutePath.orEmpty(),
null,
null,
getVideoDuration(file),
file.length(),
isFilter = false,
isExtend = true
)
}

/**
* 获取视频时长
*/
private fun getVideoDuration(videoFile: File): Long {
if (videoFile.isInvalid()) {
return 0
}
val retriever = MediaMetadataRetriever()
return try {
retriever.setDataSource(BaseApplication.getAppContext(), Uri.fromFile(videoFile))
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
?.toLongOrNull()
?: 0
} catch (e: Exception) {
e.printStackTrace()
0
} finally {
retriever.release()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import com.xyoye.common_component.source.VideoSourceManager
import com.xyoye.common_component.source.factory.StorageVideoSourceFactory
import com.xyoye.common_component.storage.StorageFactory
import com.xyoye.common_component.storage.impl.LinkStorage
import com.xyoye.common_component.utils.MediaUtils
import com.xyoye.common_component.utils.SupervisorScope
import com.xyoye.common_component.utils.getDirPath
import com.xyoye.common_component.utils.meida.VideoScan
import com.xyoye.common_component.weight.ToastCenter
import com.xyoye.data_component.entity.ExtendFolderEntity
import com.xyoye.data_component.entity.MediaLibraryEntity
Expand All @@ -38,7 +38,7 @@ class PlayerIntentViewModel : BaseViewModel() {
return@launch

val folderPath = getDirPath(filePath)
val extendVideos = MediaUtils.scanVideoFile(folderPath)
val extendVideos = VideoScan.traverse(folderPath)
if (extendVideos.isNotEmpty()) {
DatabaseManager.instance.getExtendFolderDao().insert(
ExtendFolderEntity(folderPath, extendVideos.size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.xyoye.common_component.base.BaseViewModel
import com.xyoye.common_component.database.DatabaseManager
import com.xyoye.common_component.utils.MediaUtils
import com.xyoye.common_component.storage.StorageFactory
import com.xyoye.common_component.utils.meida.VideoScan
import com.xyoye.common_component.weight.ToastCenter
import com.xyoye.data_component.entity.ExtendFolderEntity
import com.xyoye.data_component.entity.MediaLibraryEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

Expand All @@ -30,26 +32,47 @@ class ScanExtendFragmentViewModel : BaseViewModel() {
fun removeExtendFolder(entity: ExtendFolderEntity) {
viewModelScope.launch {
DatabaseManager.instance.getExtendFolderDao().delete(entity.folderPath)

// 移除本地视频库中关联的视频
DatabaseManager.instance.getVideoDao().deleteExtend()
// 刷新扩展目录UI
getExtendFolder()
}
}

fun addExtendFolder(folderPath: String) {
viewModelScope.launch(Dispatchers.IO) {
showLoading()
val extendVideos = MediaUtils.scanVideoFile(folderPath)
val extendVideos = VideoScan.traverse(folderPath)
hideLoading()

if (extendVideos.size == 0) {
if (extendVideos.isEmpty()) {
ToastCenter.showError("失败,当前文件夹内未识别到任何视频")
return@launch
}

// 新增扩展目录到数据库
val entity = ExtendFolderEntity(folderPath, extendVideos.size)
DatabaseManager.instance.getExtendFolderDao().insert(entity)

// 刷新本地视频库
refreshVideoStorage()
// 刷新扩展目录UI
getExtendFolder()

// 关闭弹窗
extendAppendedLiveData.postValue(Any())
}
}

/**
* 刷新本地视频库
*/
private fun refreshVideoStorage() {
viewModelScope.launch {
val storage = StorageFactory.createStorage(MediaLibraryEntity.LOCAL) ?: return@launch
val rootFile = storage.getRootFile() ?: return@launch
storage.openDirectory(rootFile, true)
}
}
}

0 comments on commit 0b4b7cc

Please sign in to comment.