EffectViewModel.kt 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package com.adealink.weparty.effect
  2. import androidx.lifecycle.LiveData
  3. import com.adealink.frame.base.IError
  4. import com.adealink.frame.download.listener.TaskListener
  5. import com.adealink.frame.download.task.Task
  6. import com.adealink.frame.download.task.TaskPriority
  7. import com.adealink.frame.effect.data.EffectAnimType
  8. import com.adealink.frame.log.Log
  9. import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
  10. import com.adealink.frame.mvvm.viewmodel.BaseViewModel
  11. import com.adealink.frame.storage.file.WeFile
  12. import com.adealink.frame.storage.file.getCacheFilePathByUrl
  13. import com.adealink.frame.storageService
  14. import com.adealink.frame.util.md5
  15. import com.adealink.weparty.App
  16. import kotlinx.coroutines.async
  17. import kotlinx.coroutines.awaitAll
  18. import kotlinx.coroutines.coroutineScope
  19. import kotlinx.coroutines.launch
  20. import kotlinx.coroutines.suspendCancellableCoroutine
  21. import kotlin.coroutines.resume
  22. class EffectViewModel : BaseViewModel() {
  23. fun downloadResources(urls: List<String>, priority: TaskPriority): LiveData<List<WeFile?>> {
  24. val liveData = OnceMutableLiveData<List<WeFile?>>()
  25. viewModelScope.launch {
  26. val resultList = coroutineScope {
  27. urls.map { url ->
  28. async {
  29. downloadEffect(url, priority)
  30. }
  31. }.awaitAll()
  32. }
  33. liveData.send(resultList)
  34. }
  35. return liveData
  36. }
  37. fun downloadResource(url: String, priority: TaskPriority): LiveData<WeFile?> {
  38. val liveData = OnceMutableLiveData<WeFile?>()
  39. viewModelScope.launch {
  40. liveData.send(
  41. downloadEffect(url, priority)
  42. )
  43. }
  44. return liveData
  45. }
  46. /**
  47. * 接入腾讯云特效播放器后按需使用,需传入新旧链接,根据特效特效播放器可用情况下载对应资源
  48. */
  49. fun downloadResource(
  50. oldUrl: String,
  51. newUrl: String?,
  52. newAnimType: Int,
  53. forceOldRes: Boolean = false,
  54. priority: TaskPriority = TaskPriority.NORMAL
  55. ): LiveData<EffectSaveResource> {
  56. val liveData = OnceMutableLiveData<EffectSaveResource>()
  57. val effectUrl: String
  58. val effectAnimType: Int
  59. when (forceOldRes || newUrl.isNullOrEmpty()) {
  60. true -> {
  61. effectUrl = oldUrl
  62. effectAnimType = EffectAnimType.getOldEffectAnimTypeByUrl(oldUrl)
  63. }
  64. else -> {
  65. effectUrl = newUrl
  66. effectAnimType = newAnimType
  67. }
  68. }
  69. viewModelScope.launch {
  70. val animType = EffectAnimType.map(effectAnimType)
  71. if (animType == null) {
  72. //不支持的动效类型
  73. liveData.send(EffectSaveResource(null, effectAnimType))
  74. return@launch
  75. }
  76. liveData.send(
  77. EffectSaveResource(downloadEffect(effectUrl, priority), effectAnimType)
  78. )
  79. }
  80. return liveData
  81. }
  82. private suspend fun downloadEffect(url: String, priority: TaskPriority): WeFile? {
  83. val savePath = getCacheFilePathByUrl(url)
  84. return suspendCancellableCoroutine { continuation ->
  85. addDownloadTask(url, savePath, priority,
  86. { localPath ->
  87. if (continuation.isActive) {
  88. continuation.resume(
  89. localPath
  90. )
  91. }
  92. },
  93. {
  94. if (continuation.isActive) {
  95. continuation.resume(null)
  96. }
  97. })
  98. }
  99. }
  100. private fun addDownloadTask(
  101. url: String,
  102. savePath: String,
  103. priority: TaskPriority,
  104. success: ((path: WeFile) -> Unit)? = null,
  105. failed: ((error: IError) -> Unit)? = null,
  106. ) {
  107. Log.d(TAG, "addDownloadTask, url: $url")
  108. Log.d(TAG, " savePath: $savePath")
  109. val file = storageService.file.createWeFile(savePath)
  110. if (file.exists()) {
  111. Log.d(TAG, "addDownloadTask, fileExist, return")
  112. success?.invoke(file)
  113. return
  114. }
  115. val taskId = url.md5()
  116. val task = Task(taskId, url, savePath, TaskPriority.getPriority(priority))
  117. Log.d(
  118. TAG,
  119. "addDownloadTask, start download, url:$url, task:$task"
  120. )
  121. task.listeners.add(object : TaskListener {
  122. override fun onFinished(task: Task) {
  123. super.onFinished(task)
  124. success?.invoke(file)
  125. Log.d(
  126. TAG,
  127. "addDownloadTask, download success, task:$task"
  128. )
  129. }
  130. override fun onError(task: Task, error: IError) {
  131. super.onError(task, error)
  132. failed?.invoke(error)
  133. Log.e(
  134. TAG,
  135. "addDownloadTask, task:$task, error:$error"
  136. )
  137. }
  138. })
  139. addDownloadTask(task)
  140. }
  141. private fun addDownloadTask(task: Task) {
  142. App.instance.downloadService.addTask(task)
  143. }
  144. companion object {
  145. private const val TAG = "EffectViewModel"
  146. }
  147. }