kunfei il y a 4 ans
Parent
commit
c3c3a2c693
1 fichiers modifiés avec 96 ajouts et 85 suppressions
  1. 96 85
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

+ 96 - 85
app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@@ -43,6 +43,7 @@ class HttpReadAloudService : BaseReadAloudService(),
     private val cacheFiles = hashSetOf<String>()
     private var downloadTask: Coroutine<*>? = null
     private var playIndexJob: Job? = null
+    private var downloadTaskIsActive = false
     private var downloadErrorNo: Int = 0
     private var playErrorNo = 0
 
@@ -103,104 +104,114 @@ class HttpReadAloudService : BaseReadAloudService(),
     }
 
     private fun downloadAudio() {
-        downloadTask?.cancel()
-        downloadTask = execute {
-            clearSpeakCache()
-            removeCacheFile()
-            val httpTts = ReadAloud.httpTTS ?: return@execute
-            contentList.forEachIndexed { index, content ->
-                ensureActive()
-                val fileName =
-                    md5SpeakFileName(httpTts.url, speechRate.toString(), content)
-                val speakText = content.replace(AppPattern.notReadAloudRegex, "")
-                if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
-                    if (index == nowSpeak) {
-                        val file = getSpeakFileAsMd5(fileName)
-                        playAudio(file)
-                    }
-                } else if (hasSpeakCache(fileName)) { //缓存文件还在,可能还没下载完
-                    return@forEachIndexed
-                } else if (speakText.isEmpty()) {
-                    createSilentSound(fileName)
-                    return@forEachIndexed
-                } else {
-                    runCatching {
-                        createSpeakCache(fileName)
-                        val analyzeUrl = AnalyzeUrl(
-                            httpTts.url,
-                            speakText = speakText,
-                            speakSpeed = speechRate,
-                            source = httpTts,
-                            headerMapF = httpTts.getHeaderMap(true)
-                        )
-                        var response = analyzeUrl.getResponseAwait()
-                        ensureActive()
-                        httpTts.loginCheckJs?.takeIf { checkJs ->
-                            checkJs.isNotBlank()
-                        }?.let { checkJs ->
-                            response = analyzeUrl.evalJS(checkJs, response) as Response
+        launch {
+            downloadTask?.cancel()
+            while (downloadTaskIsActive) {
+                //在线tts大部分只能单线程,等待上次访问结束
+                delay(100)
+            }
+            downloadTask = execute {
+                clearSpeakCache()
+                removeCacheFile()
+                val httpTts = ReadAloud.httpTTS ?: return@execute
+                contentList.forEachIndexed { index, content ->
+                    ensureActive()
+                    val fileName =
+                        md5SpeakFileName(httpTts.url, speechRate.toString(), content)
+                    val speakText = content.replace(AppPattern.notReadAloudRegex, "")
+                    if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
+                        if (index == nowSpeak) {
+                            val file = getSpeakFileAsMd5(fileName)
+                            playAudio(file)
                         }
-                        httpTts.contentType?.takeIf { ct ->
-                            ct.isNotBlank()
-                        }?.let { ct ->
-                            response.headers["Content-Type"]?.let { contentType ->
-                                if (!contentType.matches(ct.toRegex())) {
-                                    throw NoStackTraceException(response.body!!.string())
-                                }
+                    } else if (hasSpeakCache(fileName)) { //缓存文件还在,可能还没下载完
+                        return@forEachIndexed
+                    } else if (speakText.isEmpty()) {
+                        createSilentSound(fileName)
+                        return@forEachIndexed
+                    } else {
+                        runCatching {
+                            createSpeakCache(fileName)
+                            val analyzeUrl = AnalyzeUrl(
+                                httpTts.url,
+                                speakText = speakText,
+                                speakSpeed = speechRate,
+                                source = httpTts,
+                                headerMapF = httpTts.getHeaderMap(true)
+                            )
+                            var response = analyzeUrl.getResponseAwait()
+                            ensureActive()
+                            httpTts.loginCheckJs?.takeIf { checkJs ->
+                                checkJs.isNotBlank()
+                            }?.let { checkJs ->
+                                response = analyzeUrl.evalJS(checkJs, response) as Response
                             }
-                        }
-                        ensureActive()
-                        response.body!!.bytes().let { bytes ->
-                            val file = createSpeakFileAsMd5IfNotExist(fileName)
-                            file.writeBytes(bytes)
-                            removeSpeakCache(fileName)
-                            if (index == nowSpeak) {
-                                playAudio(file)
+                            httpTts.contentType?.takeIf { ct ->
+                                ct.isNotBlank()
+                            }?.let { ct ->
+                                response.headers["Content-Type"]?.let { contentType ->
+                                    if (!contentType.matches(ct.toRegex())) {
+                                        throw NoStackTraceException(response.body!!.string())
+                                    }
+                                }
                             }
-                        }
-                        downloadErrorNo = 0
-                    }.onFailure {
-                        when (it) {
-                            is CancellationException -> removeSpeakCache(fileName)
-                            is ConcurrentException -> {
+                            ensureActive()
+                            response.body!!.bytes().let { bytes ->
+                                val file = createSpeakFileAsMd5IfNotExist(fileName)
+                                file.writeBytes(bytes)
                                 removeSpeakCache(fileName)
-                                delay(it.waitTime.toLong())
-                                downloadAudio()
-                            }
-                            is ScriptException, is WrappedException -> {
-                                AppLog.put("js错误\n${it.localizedMessage}", it)
-                                toastOnUi("js错误\n${it.localizedMessage}")
-                                it.printOnDebug()
-                                cancel()
-                                pauseReadAloud(true)
+                                if (index == nowSpeak) {
+                                    playAudio(file)
+                                }
                             }
-                            is SocketTimeoutException, is ConnectException -> {
-                                removeSpeakCache(fileName)
-                                downloadErrorNo++
-                                if (downloadErrorNo > 5) {
-                                    val msg = "tts超时或连接错误超过5次\n${it.localizedMessage}"
-                                    AppLog.put(msg, it)
-                                    toastOnUi(msg)
-                                    pauseReadAloud(true)
-                                } else {
+                            downloadErrorNo = 0
+                        }.onFailure {
+                            when (it) {
+                                is CancellationException -> removeSpeakCache(fileName)
+                                is ConcurrentException -> {
+                                    removeSpeakCache(fileName)
+                                    delay(it.waitTime.toLong())
                                     downloadAudio()
                                 }
-                            }
-                            else -> {
-                                removeSpeakCache(fileName)
-                                downloadErrorNo++
-                                val msg = "tts下载错误\n${it.localizedMessage}"
-                                AppLog.put(msg, it)
-                                it.printOnDebug()
-                                if (downloadErrorNo > 5) {
+                                is ScriptException, is WrappedException -> {
+                                    AppLog.put("js错误\n${it.localizedMessage}", it)
+                                    toastOnUi("js错误\n${it.localizedMessage}")
+                                    it.printOnDebug()
+                                    cancel()
                                     pauseReadAloud(true)
-                                } else {
-                                    createSilentSound(fileName)
+                                }
+                                is SocketTimeoutException, is ConnectException -> {
+                                    removeSpeakCache(fileName)
+                                    downloadErrorNo++
+                                    if (downloadErrorNo > 5) {
+                                        val msg = "tts超时或连接错误超过5次\n${it.localizedMessage}"
+                                        AppLog.put(msg, it)
+                                        toastOnUi(msg)
+                                        pauseReadAloud(true)
+                                    } else {
+                                        downloadAudio()
+                                    }
+                                }
+                                else -> {
+                                    removeSpeakCache(fileName)
+                                    downloadErrorNo++
+                                    val msg = "tts下载错误\n${it.localizedMessage}"
+                                    AppLog.put(msg, it)
+                                    it.printOnDebug()
+                                    if (downloadErrorNo > 5) {
+                                        pauseReadAloud(true)
+                                    } else {
+                                        createSilentSound(fileName)
+                                    }
                                 }
                             }
                         }
                     }
                 }
+            }.onStart {
+                downloadTaskIsActive = true
+            }.onFinally {
+                downloadTaskIsActive = false
             }
         }
     }