Merge pull request #783 from litcc/dev1

fix: 朗读时翻页防止重复发送请求
pull/801/head 3.21.010520
kunfei 4 years ago committed by GitHub
commit 3d09170ad4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 127
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@ -12,11 +12,18 @@ import io.legado.app.service.help.ReadAloud
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileUtils
import io.legado.app.utils.LogUtils import io.legado.app.utils.LogUtils
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.jetbrains.anko.collections.forEachWithIndex
import java.io.File import java.io.File
import java.io.FileDescriptor import java.io.FileDescriptor
import java.io.FileInputStream import java.io.FileInputStream
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.util.*
class HttpReadAloudService : BaseReadAloudService(), class HttpReadAloudService : BaseReadAloudService(),
MediaPlayer.OnPreparedListener, MediaPlayer.OnPreparedListener,
@ -55,12 +62,17 @@ class HttpReadAloudService : BaseReadAloudService(),
override fun play() { override fun play() {
if (contentList.isEmpty()) return if (contentList.isEmpty()) return
if (nowSpeak == 0) { ReadAloud.httpTTS?.let {
downloadAudio() val fileName = md5SpeakFileName(it.url, AppConfig.ttsSpeechRate.toString(), contentList[nowSpeak])
} else { if (nowSpeak == 0) {
val file = getSpeakFile(nowSpeak) downloadAudio()
if (file.exists()) { } else {
playAudio(FileInputStream(file).fd) val file = getSpeakFileAsMd5(fileName)
if (file.exists()) {
playAudio(FileInputStream(file).fd)
} else {
downloadAudio()
}
} }
} }
} }
@ -68,28 +80,54 @@ class HttpReadAloudService : BaseReadAloudService(),
private fun downloadAudio() { private fun downloadAudio() {
task?.cancel() task?.cancel()
task = execute { task = execute {
FileUtils.deleteFile(ttsFolder) removeCacheFile()
for (index in 0 until contentList.size) { ReadAloud.httpTTS?.let {
if (isActive) { contentList.forEachWithIndex { index, item ->
ReadAloud.httpTTS?.let { if (isActive) {
AnalyzeUrl( val fileName =
it.url, md5SpeakFileName(it.url, AppConfig.ttsSpeechRate.toString(), item)
speakText = contentList[index],
speakSpeed = AppConfig.ttsSpeechRate if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
).getByteArray().let { bytes -> if (index == nowSpeak) {
if (isActive) { val file = getSpeakFileAsMd5(fileName)
val file = getSpeakFile(index)
file.writeBytes(bytes) @Suppress("BlockingMethodInNonBlockingContext")
if (index == nowSpeak) { val fis = FileInputStream(file)
@Suppress("BlockingMethodInNonBlockingContext") playAudio(fis.fd)
val fis = FileInputStream(file) }
playAudio(fis.fd) } else if (hasSpeakCacheFile(fileName)) { //缓存文件还在,可能还没下载完
return@let
} else { //没有下载并且没有缓存文件
try {
createSpeakCacheFile(fileName)
AnalyzeUrl(
it.url,
speakText = item,
speakSpeed = AppConfig.ttsSpeechRate
).getByteArray().let { bytes ->
if (isActive) {
val file = getSpeakFileAsMd5(fileName)
//val file = getSpeakFile(index)
file.writeBytes(bytes)
if (index == nowSpeak) {
@Suppress("BlockingMethodInNonBlockingContext")
val fis = FileInputStream(file)
playAudio(fis.fd)
}
}
} }
} catch (e: SocketTimeoutException) {
removeSpeakCacheFile(fileName)
// delay(2000)
// downloadAudio()
} catch (e: ConnectException) {
removeSpeakCacheFile(fileName)
} catch (e: Exception) {
removeSpeakCacheFile(fileName)
} }
} }
} }
} else {
break
} }
} }
} }
@ -110,10 +148,47 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
} }
private fun getSpeakFile(index: Int = nowSpeak): File { private fun speakFilePath() = ttsFolder + File.separator
return FileUtils.createFileIfNotExist("${ttsFolder}${File.separator}${index}.mp3") private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String {
return MD5Utils.md5Encode16(textChapter!!.title) + "_" + MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content")
}
private fun hasSpeakFile(name: String) =
FileUtils.exist("${speakFilePath()}$name.mp3")
private fun hasSpeakCacheFile(name: String) =
FileUtils.exist("${speakFilePath()}$name.mp3.cache")
private fun createSpeakCacheFile(name: String): File =
FileUtils.createFileWithReplace("${speakFilePath()}$name.mp3.cache")
private fun removeSpeakCacheFile(name: String) {
FileUtils.delete("${speakFilePath()}$name.mp3.cache")
}
private fun getSpeakFileAsMd5(name: String): File =
FileUtils.createFileIfNotExist("${speakFilePath()}$name.mp3")
private fun removeCacheFile() {
FileUtils.listDirsAndFiles(speakFilePath())?.forEach {
if (it == null) {
return@forEach
}
if (Regex(""".+\.mp3$""").matches(it.name)) { //mp3缓存文件
val reg =
"""^${MD5Utils.md5Encode16(textChapter!!.title)}_[a-z0-9]{16}\.mp3$""".toRegex()
if (!reg.matches(it.name)) {
FileUtils.deleteFile(it.absolutePath)
}
} else {
if (Date().time - it.lastModified() > 30000) {
FileUtils.deleteFile(it.absolutePath)
}
}
}
} }
override fun pauseReadAloud(pause: Boolean) { override fun pauseReadAloud(pause: Boolean) {
super.pauseReadAloud(pause) super.pauseReadAloud(pause)
mediaPlayer.pause() mediaPlayer.pause()

Loading…
Cancel
Save