pull/1817/head
kunfei 3 years ago
parent f8b105303c
commit 0bdf3eae54
  1. 54
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@ -39,7 +39,6 @@ class HttpReadAloudService : BaseReadAloudService(),
cacheDir.absolutePath + File.separator + "httpTTS" + File.separator cacheDir.absolutePath + File.separator + "httpTTS" + File.separator
} }
private var speechRate: Int = AppConfig.speechRatePlay private var speechRate: Int = AppConfig.speechRatePlay
private val cacheFiles = hashSetOf<String>()
private var downloadTask: Coroutine<*>? = null private var downloadTask: Coroutine<*>? = null
private var playIndexJob: Job? = null private var playIndexJob: Job? = null
private var downloadTaskIsActive = false private var downloadTaskIsActive = false
@ -65,17 +64,14 @@ class HttpReadAloudService : BaseReadAloudService(),
} else { } else {
super.play() super.play()
kotlin.runCatching { kotlin.runCatching {
val tts = ReadAloud.httpTTS ?: throw NoStackTraceException("httpTts is null")
val fileName = md5SpeakFileName(
tts.url, AppConfig.ttsSpeechRate.toString(), contentList[nowSpeak]
)
if (nowSpeak == 0 && downloadTask?.isActive != true) { if (nowSpeak == 0 && downloadTask?.isActive != true) {
downloadAudio() downloadAudio()
} else { } else {
val fileName = md5SpeakFileName(contentList[nowSpeak])
val file = getSpeakFileAsMd5(fileName) val file = getSpeakFileAsMd5(fileName)
if (file.exists()) { if (file.exists()) {
playAudio(file) playAudio(file)
} else { } else if (downloadTask?.isActive != true) {
downloadAudio() downloadAudio()
} }
} }
@ -107,27 +103,22 @@ class HttpReadAloudService : BaseReadAloudService(),
delay(100) delay(100)
} }
downloadTask = execute { downloadTask = execute {
clearSpeakCache()
removeCacheFile() removeCacheFile()
val httpTts = ReadAloud.httpTTS ?: return@execute val httpTts = ReadAloud.httpTTS ?: throw NoStackTraceException("tts is null")
contentList.forEachIndexed { index, content -> contentList.forEachIndexed { index, content ->
ensureActive() ensureActive()
val fileName = val fileName = md5SpeakFileName(content)
md5SpeakFileName(httpTts.url, speechRate.toString(), content)
val speakText = content.replace(AppPattern.notReadAloudRegex, "") val speakText = content.replace(AppPattern.notReadAloudRegex, "")
if (hasSpeakFile(fileName)) { //已经下载好的语音缓存 if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
if (index == nowSpeak) { if (index == nowSpeak) {
val file = getSpeakFileAsMd5(fileName) val file = getSpeakFileAsMd5(fileName)
playAudio(file) playAudio(file)
} }
} else if (hasSpeakCache(fileName)) { //缓存文件还在,可能还没下载完
return@forEachIndexed
} else if (speakText.isEmpty()) { } else if (speakText.isEmpty()) {
createSilentSound(fileName) createSilentSound(fileName)
return@forEachIndexed return@forEachIndexed
} else { } else {
runCatching { runCatching {
createSpeakCache(fileName)
val analyzeUrl = AnalyzeUrl( val analyzeUrl = AnalyzeUrl(
httpTts.url, httpTts.url,
speakText = speakText, speakText = speakText,
@ -155,7 +146,6 @@ class HttpReadAloudService : BaseReadAloudService(),
response.body!!.bytes().let { bytes -> response.body!!.bytes().let { bytes ->
val file = createSpeakFileAsMd5IfNotExist(fileName) val file = createSpeakFileAsMd5IfNotExist(fileName)
file.writeBytes(bytes) file.writeBytes(bytes)
removeSpeakCache(fileName)
if (index == nowSpeak) { if (index == nowSpeak) {
playAudio(file) playAudio(file)
} }
@ -163,9 +153,8 @@ class HttpReadAloudService : BaseReadAloudService(),
downloadErrorNo = 0 downloadErrorNo = 0
}.onFailure { }.onFailure {
when (it) { when (it) {
is CancellationException -> removeSpeakCache(fileName) is CancellationException -> Unit
is ConcurrentException -> { is ConcurrentException -> {
removeSpeakCache(fileName)
delay(it.waitTime.toLong()) delay(it.waitTime.toLong())
downloadAudio() downloadAudio()
} }
@ -177,7 +166,6 @@ class HttpReadAloudService : BaseReadAloudService(),
pauseReadAloud(true) pauseReadAloud(true)
} }
is SocketTimeoutException, is ConnectException -> { is SocketTimeoutException, is ConnectException -> {
removeSpeakCache(fileName)
downloadErrorNo++ downloadErrorNo++
if (downloadErrorNo > 5) { if (downloadErrorNo > 5) {
val msg = "tts超时或连接错误超过5次\n${it.localizedMessage}" val msg = "tts超时或连接错误超过5次\n${it.localizedMessage}"
@ -189,7 +177,6 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
} }
else -> { else -> {
removeSpeakCache(fileName)
downloadErrorNo++ downloadErrorNo++
val msg = "tts下载错误\n${it.localizedMessage}" val msg = "tts下载错误\n${it.localizedMessage}"
AppLog.put(msg, it) AppLog.put(msg, it)
@ -228,9 +215,9 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
} }
private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String { private fun md5SpeakFileName(content: String): String {
return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" + return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" +
MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content") MD5Utils.md5Encode16("${ReadAloud.httpTTS?.url}-|-$speechRate-|-$content")
} }
private fun createSilentSound(fileName: String) { private fun createSilentSound(fileName: String) {
@ -238,26 +225,17 @@ class HttpReadAloudService : BaseReadAloudService(),
file.writeBytes(resources.openRawResource(R.raw.silent_sound).readBytes()) file.writeBytes(resources.openRawResource(R.raw.silent_sound).readBytes())
} }
@Synchronized private fun hasSpeakFile(name: String): Boolean {
private fun clearSpeakCache() = cacheFiles.clear() return FileUtils.exist("${ttsFolderPath}$name.mp3")
}
@Synchronized
private fun hasSpeakCache(name: String) = cacheFiles.contains(name)
@Synchronized
private fun createSpeakCache(name: String) = cacheFiles.add(name)
@Synchronized
private fun removeSpeakCache(name: String) = cacheFiles.remove(name)
private fun hasSpeakFile(name: String) =
FileUtils.exist("${ttsFolderPath}$name.mp3")
private fun getSpeakFileAsMd5(name: String): File = private fun getSpeakFileAsMd5(name: String): File {
File("${ttsFolderPath}$name.mp3") return File("${ttsFolderPath}$name.mp3")
}
private fun createSpeakFileAsMd5IfNotExist(name: String): File = private fun createSpeakFileAsMd5IfNotExist(name: String): File {
FileUtils.createFileIfNotExist("${ttsFolderPath}$name.mp3") return FileUtils.createFileIfNotExist("${ttsFolderPath}$name.mp3")
}
/** /**
* 移除缓存文件 * 移除缓存文件

Loading…
Cancel
Save