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.utils.FileUtils
import io.legado.app.utils.LogUtils
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.postEvent
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.jetbrains.anko.collections.forEachWithIndex
import java.io.File
import java.io.FileDescriptor
import java.io.FileInputStream
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.util.*
class HttpReadAloudService : BaseReadAloudService(),
MediaPlayer.OnPreparedListener,
@ -55,12 +62,17 @@ class HttpReadAloudService : BaseReadAloudService(),
override fun play() {
if (contentList.isEmpty()) return
if (nowSpeak == 0) {
downloadAudio()
} else {
val file = getSpeakFile(nowSpeak)
if (file.exists()) {
playAudio(FileInputStream(file).fd)
ReadAloud.httpTTS?.let {
val fileName = md5SpeakFileName(it.url, AppConfig.ttsSpeechRate.toString(), contentList[nowSpeak])
if (nowSpeak == 0) {
downloadAudio()
} else {
val file = getSpeakFileAsMd5(fileName)
if (file.exists()) {
playAudio(FileInputStream(file).fd)
} else {
downloadAudio()
}
}
}
}
@ -68,28 +80,54 @@ class HttpReadAloudService : BaseReadAloudService(),
private fun downloadAudio() {
task?.cancel()
task = execute {
FileUtils.deleteFile(ttsFolder)
for (index in 0 until contentList.size) {
if (isActive) {
ReadAloud.httpTTS?.let {
AnalyzeUrl(
it.url,
speakText = contentList[index],
speakSpeed = AppConfig.ttsSpeechRate
).getByteArray().let { bytes ->
if (isActive) {
val file = getSpeakFile(index)
file.writeBytes(bytes)
if (index == nowSpeak) {
@Suppress("BlockingMethodInNonBlockingContext")
val fis = FileInputStream(file)
playAudio(fis.fd)
removeCacheFile()
ReadAloud.httpTTS?.let {
contentList.forEachWithIndex { index, item ->
if (isActive) {
val fileName =
md5SpeakFileName(it.url, AppConfig.ttsSpeechRate.toString(), item)
if (hasSpeakFile(fileName)) { //已经下载好的语音缓存
if (index == nowSpeak) {
val file = getSpeakFileAsMd5(fileName)
@Suppress("BlockingMethodInNonBlockingContext")
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 {
return FileUtils.createFileIfNotExist("${ttsFolder}${File.separator}${index}.mp3")
private fun speakFilePath() = ttsFolder + File.separator
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) {
super.pauseReadAloud(pause)
mediaPlayer.pause()

Loading…
Cancel
Save