Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

Expand All @@ -34,54 +33,49 @@ class LocalMediaInfoSynchronizer @Inject constructor(
@Dispatcher(NextDispatchers.Default) private val dispatcher: CoroutineDispatcher,
) : MediaInfoSynchronizer {

private val media = MutableSharedFlow<Uri>()

override suspend fun addMedia(uri: Uri) = media.emit(uri)
override fun syncMediaInfoForMediumUri(uri: Uri) {
updateMediaInfo(uri)
}

private suspend fun sync(): Unit = withContext(dispatcher) {
media.collect { mediumUri ->
val medium = mediumDao.getWithInfo(mediumUri.toString()) ?: return@collect
if (medium.mediumEntity.thumbnailPath?.let { File(it) }?.exists() == true) {
return@collect
}
private fun updateMediaInfo(mediumUri: Uri) = applicationScope.launch(dispatcher) {
val medium = mediumDao.getWithInfo(mediumUri.toString()) ?: return@launch

val mediaInfo = runCatching {
MediaInfoBuilder().from(context = context, uri = mediumUri).build() ?: throw NullPointerException()
}.onFailure { e ->
e.printStackTrace()
Log.d(TAG, "sync: MediaInfoBuilder exception", e)
}.getOrNull() ?: return@collect
val thumbnailExists = medium.mediumEntity.thumbnailPath?.let { File(it) }?.exists() == true
val isMediaSizeChanged = File(medium.mediumEntity.path).length() != medium.mediumEntity.size
if (thumbnailExists && !isMediaSizeChanged) return@launch

val thumbnail = runCatching { mediaInfo.getFrame() }.getOrNull()
mediaInfo.release()
val mediaInfo = runCatching {
MediaInfoBuilder().from(context = context, uri = mediumUri).build() ?: throw NullPointerException()
}.onFailure { e ->
e.printStackTrace()
Log.d(TAG, "sync: MediaInfoBuilder exception", e)
}.getOrNull() ?: return@launch

val videoStreamInfo = mediaInfo.videoStream?.toVideoStreamInfoEntity(medium.mediumEntity.uriString)
val audioStreamsInfo = mediaInfo.audioStreams.map {
it.toAudioStreamInfoEntity(medium.mediumEntity.uriString)
}
val subtitleStreamsInfo = mediaInfo.subtitleStreams.map {
it.toSubtitleStreamInfoEntity(medium.mediumEntity.uriString)
}
val thumbnailPath = thumbnail?.saveTo(
storageDir = context.thumbnailCacheDir,
quality = 40,
fileName = medium.mediumEntity.mediaStoreId.toString(),
)
val thumbnail = runCatching { mediaInfo.getFrame() }.getOrNull()
mediaInfo.release()

mediumDao.upsert(
medium.mediumEntity.copy(
format = mediaInfo.format,
thumbnailPath = thumbnailPath,
),
)
videoStreamInfo?.let { mediumDao.upsertVideoStreamInfo(it) }
audioStreamsInfo.onEach { mediumDao.upsertAudioStreamInfo(it) }
subtitleStreamsInfo.onEach { mediumDao.upsertSubtitleStreamInfo(it) }
val videoStreamInfo = mediaInfo.videoStream?.toVideoStreamInfoEntity(medium.mediumEntity.uriString)
val audioStreamsInfo = mediaInfo.audioStreams.map {
it.toAudioStreamInfoEntity(medium.mediumEntity.uriString)
}
}
val subtitleStreamsInfo = mediaInfo.subtitleStreams.map {
it.toSubtitleStreamInfoEntity(medium.mediumEntity.uriString)
}
val thumbnailPath = thumbnail?.saveTo(
storageDir = context.thumbnailCacheDir,
quality = 40,
fileName = medium.mediumEntity.mediaStoreId.toString(),
)

init {
applicationScope.launch { sync() }
mediumDao.upsert(
medium.mediumEntity.copy(
format = mediaInfo.format,
thumbnailPath = thumbnailPath,
),
)
videoStreamInfo?.let { mediumDao.upsertVideoStreamInfo(it) }
audioStreamsInfo.onEach { mediumDao.upsertAudioStreamInfo(it) }
subtitleStreamsInfo.onEach { mediumDao.upsertSubtitleStreamInfo(it) }
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import android.net.Uri

interface MediaInfoSynchronizer {

suspend fun addMedia(uri: Uri)
fun syncMediaInfoForMediumUri(uri: Uri)
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ class MediaPickerViewModel @Inject constructor(
}

fun addToMediaInfoSynchronizer(uri: Uri) {
viewModelScope.launch {
mediaInfoSynchronizer.addMedia(uri)
}
mediaInfoSynchronizer.syncMediaInfoForMediumUri(uri)
}

fun renameVideo(uri: Uri, to: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ class MediaPickerFolderViewModel @Inject constructor(
}

fun addToMediaInfoSynchronizer(uri: Uri) {
viewModelScope.launch {
mediaInfoSynchronizer.addMedia(uri)
}
mediaInfoSynchronizer.syncMediaInfoForMediumUri(uri)
}

fun renameVideo(uri: Uri, to: String) {
Expand Down
Loading