This commit is contained in:
kunfei
2022-04-21 08:43:54 +08:00
parent e99459e2e7
commit 8bdb3042da
@@ -43,6 +43,7 @@ class HttpReadAloudService : BaseReadAloudService(),
private val cacheFiles = hashSetOf<String>() 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 downloadErrorNo: Int = 0 private var downloadErrorNo: Int = 0
private var playErrorNo = 0 private var playErrorNo = 0
@@ -103,104 +104,114 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
private fun downloadAudio() { private fun downloadAudio() {
downloadTask?.cancel() launch {
downloadTask = execute { downloadTask?.cancel()
clearSpeakCache() while (downloadTaskIsActive) {
removeCacheFile() //在线tts大部分只能单线程,等待上次访问结束
val httpTts = ReadAloud.httpTTS ?: return@execute delay(100)
contentList.forEachIndexed { index, content -> }
ensureActive() downloadTask = execute {
val fileName = clearSpeakCache()
md5SpeakFileName(httpTts.url, speechRate.toString(), content) removeCacheFile()
val speakText = content.replace(AppPattern.notReadAloudRegex, "") val httpTts = ReadAloud.httpTTS ?: return@execute
if (hasSpeakFile(fileName)) { //已经下载好的语音缓存 contentList.forEachIndexed { index, content ->
if (index == nowSpeak) { ensureActive()
val file = getSpeakFileAsMd5(fileName) val fileName =
playAudio(file) md5SpeakFileName(httpTts.url, speechRate.toString(), content)
} val speakText = content.replace(AppPattern.notReadAloudRegex, "")
} else if (hasSpeakCache(fileName)) { //缓存文件还在,可能还没下载完 if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
return@forEachIndexed if (index == nowSpeak) {
} else if (speakText.isEmpty()) { val file = getSpeakFileAsMd5(fileName)
createSilentSound(fileName) playAudio(file)
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
} }
httpTts.contentType?.takeIf { ct -> } else if (hasSpeakCache(fileName)) { //缓存文件还在,可能还没下载完
ct.isNotBlank() return@forEachIndexed
}?.let { ct -> } else if (speakText.isEmpty()) {
response.headers["Content-Type"]?.let { contentType -> createSilentSound(fileName)
if (!contentType.matches(ct.toRegex())) { return@forEachIndexed
throw NoStackTraceException(response.body!!.string()) } 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
}
httpTts.contentType?.takeIf { ct ->
ct.isNotBlank()
}?.let { ct ->
response.headers["Content-Type"]?.let { contentType ->
if (!contentType.matches(ct.toRegex())) {
throw NoStackTraceException(response.body!!.string())
}
} }
} }
} ensureActive()
ensureActive() 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) {
playAudio(file)
}
}
downloadErrorNo = 0
}.onFailure {
when (it) {
is CancellationException -> removeSpeakCache(fileName)
is ConcurrentException -> {
removeSpeakCache(fileName) removeSpeakCache(fileName)
delay(it.waitTime.toLong()) if (index == nowSpeak) {
downloadAudio() playAudio(file)
}
} }
is ScriptException, is WrappedException -> { downloadErrorNo = 0
AppLog.put("js错误\n${it.localizedMessage}", it) }.onFailure {
toastOnUi("js错误\n${it.localizedMessage}") when (it) {
it.printOnDebug() is CancellationException -> removeSpeakCache(fileName)
cancel() is ConcurrentException -> {
pauseReadAloud(true) removeSpeakCache(fileName)
} delay(it.waitTime.toLong())
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() downloadAudio()
} }
} is ScriptException, is WrappedException -> {
else -> { AppLog.put("js错误\n${it.localizedMessage}", it)
removeSpeakCache(fileName) toastOnUi("js错误\n${it.localizedMessage}")
downloadErrorNo++ it.printOnDebug()
val msg = "tts下载错误\n${it.localizedMessage}" cancel()
AppLog.put(msg, it)
it.printOnDebug()
if (downloadErrorNo > 5) {
pauseReadAloud(true) 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
} }
} }
} }