Skip to content

Commit

Permalink
Merge pull request #215 from xyoye/dev_4.1.0
Browse files Browse the repository at this point in the history
Dev 4.1.0
  • Loading branch information
xyoye authored Feb 4, 2024
2 parents 8597829 + 0b4b7cc commit 49ce06a
Show file tree
Hide file tree
Showing 15 changed files with 415 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.xyoye.common_component.config

import androidx.appcompat.app.AppCompatDelegate
import com.xyoye.common_component.network.config.Api
import com.xyoye.common_component.utils.meida.VideoExtension
import com.xyoye.data_component.enums.HistorySort
import com.xyoye.data_component.enums.StorageSort
import com.xyoye.mmkv_annotation.MMKVFiled
Expand Down Expand Up @@ -84,4 +85,8 @@ object AppConfigTable {
@MMKVFiled
//备用域名地址
var backupDomain: String = Api.DAN_DAN_SPARE

@MMKVFiled
//支持的视频后缀
var supportVideoExtension: String = VideoExtension.supportText
}
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,14 +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.data_component.entity.VideoEntity
import com.xyoye.common_component.utils.meida.VideoExtension
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
Expand All @@ -25,14 +23,6 @@ import java.util.Locale
* Created by xyoye on 2020/11/26.
*/

private val commonVideoExtension = arrayOf(
"3gp", "avi", "flv", "mp4",
"m4v", "mkv", "mov", "mpeg",
"mpg", "mpe", "rm", "rmvb",
"wmv", "asf", "asx", "dat",
"vob", "m3u8", "m2ts", "m4s"
)

val supportSubtitleExtension = arrayOf(
"ass", "scc", "stl", "srt",
"ttml"
Expand All @@ -45,7 +35,7 @@ val supportAudioExtension = arrayOf(

fun isVideoFile(filePath: String): Boolean {
val extension = getFileExtension(filePath)
return commonVideoExtension.contains(extension.lowercase(Locale.ROOT))
return VideoExtension.isSupport(extension)
}

fun isSubtitleFile(filePath: String): Boolean {
Expand Down Expand Up @@ -109,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 @@ -210,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,80 @@
package com.xyoye.common_component.utils.meida

import com.xyoye.common_component.config.AppConfig

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

object VideoExtension {

// 视频文件扩展名分隔符
private const val SEPARATOR = ","

// 默认支持的视频文件扩展名
private val defaultSupport = arrayOf(
"3gp", "asf", "asx", "avi",
"dat", "flv", "m2ts", "m3u8",
"m4s", "m4v", "mkv", "mov",
"mp4", "mpe", "mpeg", "mpg",
"rm", "rmvb", "vob", "wmv"
)

// 当前支持的视频文件扩展名
private val _support = defaultSupport.toMutableList()
val support: List<String> get() = _support

// 当前支持的视频文件扩展名文本
val supportText: String get() = _support.joinToString(SEPARATOR)

init {
refresh()
}

/**
* 重置为默认支持的视频文件扩展名
*/
fun resetDefault() {
AppConfig.putSupportVideoExtension(defaultSupport.joinToString(SEPARATOR))
refresh()
}

/**
* 更新支持的视频文件扩展名
*/
fun update(extensionText: String): Boolean {
return update(extensionText.split(SEPARATOR))
}

/**
* 更新支持的视频文件扩展名
*/
fun update(extensions: List<String>): Boolean {
val storeExtensions = extensions.filter { it.isNotBlank() }.map { it.lowercase() }
if (storeExtensions.isEmpty()) {
return false
}
AppConfig.putSupportVideoExtension(storeExtensions.joinToString(SEPARATOR))
refresh()
return true
}

/**
* 是否是支持的视频文件扩展名
*/
fun isSupport(extension: String): Boolean {
return _support.contains(extension.lowercase())
}

/**
* 从磁盘中获取支持的视频文件扩展名
*/
private fun refresh() {
val stored = AppConfig.getSupportVideoExtension()?.split(SEPARATOR)
if (stored.isNullOrEmpty()) {
return
}
_support.clear()
_support.addAll(stored)
}
}
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 @@ -40,6 +40,7 @@ class FileManagerDialog(
activity: Activity,
private val action: FileManagerAction,
private var defaultFolderPath: String? = null,
private val dismissWhenClickPositive: Boolean = true,
private val listener: (resultPath: String) -> Unit
) : BaseBottomDialog<DialogFileManagerBinding>(activity) {

Expand Down Expand Up @@ -79,9 +80,11 @@ class FileManagerDialog(
setNegativeListener { dismiss() }

setPositiveListener {
dismiss()
AppConfig.putLastOpenFolder(currentDirPath)
listener.invoke(currentDirPath)
if (dismissWhenClickPositive) {
dismiss()
}
}

binding.rootPathTv.setOnClickListener {
Expand Down
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
Loading

0 comments on commit 49ce06a

Please sign in to comment.