pull/1395/head
gedoor 3 years ago
parent b186c4cdc6
commit 0115b0a94a
  1. 1519
      app/schemas/io.legado.app.data.AppDatabase/42.json
  2. 4
      app/src/main/assets/defaultData/httpTTS.json
  3. 2
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  4. 9
      app/src/main/java/io/legado/app/data/DatabaseMigrations.kt
  5. 1
      app/src/main/java/io/legado/app/data/entities/HttpTTS.kt
  6. 10
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

File diff suppressed because it is too large Load Diff

@ -2,7 +2,8 @@
{ {
"id": -100, "id": -100,
"name": "1.百度", "name": "1.百度",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}" "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}",
"contentType": "audio/wav"
}, },
{ {
"id": -99, "id": -99,
@ -13,6 +14,7 @@
"id": -29, "id": -29,
"name": "3.阿里云语音", "name": "3.阿里云语音",
"url": "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts,{\"method\": \"POST\",\"body\": {\"appkey\":\"{{source.getLoginInfoMap().get('AppKey')}}\",\"text\":\"{{speakText}}\",\"format\":\"mp3\",\"volume\":100,\"speech_rate\":{{String((speakSpeed) * 20 - 400)}} }}", "url": "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts,{\"method\": \"POST\",\"body\": {\"appkey\":\"{{source.getLoginInfoMap().get('AppKey')}}\",\"text\":\"{{speakText}}\",\"format\":\"mp3\",\"volume\":100,\"speech_rate\":{{String((speakSpeed) * 20 - 400)}} }}",
"contentType": "audio/mpeg",
"loginUrl": "var loginInfo = source.getLoginInfoMap();\nvar accessKeyId = loginInfo.get('AccessKeyId');\nvar accessKeySecret = loginInfo.get('AccessKeySecret');\nvar timestamp = java.timeFormatUTC(new Date().getTime(), \"YYYY-MM-dd'T'HH:mm:ss'Z'\", 0);\nvar aly = new JavaImporter(Packages.javax.crypto.Mac, Packages.javax.crypto.spec.SecretKeySpec, Packages.javax.xml.bind.DatatypeConverter, Packages.java.net.URLEncoder, Packages.java.lang.String, Packages.android.util.Base64);\nwith (aly) {\n function percentEncode(value) {\n return URLEncoder.encode(value, \"UTF-8\").replace(\"+\", \"%20\")\n .replace(\"*\", \"%2A\").replace(\"%7E\", \"~\")\n }\n\n function sign(stringToSign, accessKeySecret) {\n var mac = Mac.getInstance('HmacSHA1');\n mac.init(new SecretKeySpec(String(accessKeySecret + '&').getBytes(\"UTF-8\"), \"HmacSHA1\"));\n var signData = mac.doFinal(String(stringToSign).getBytes(\"UTF-8\"));\n var signBase64 = Base64.encodeToString(signData, Base64.NO_WRAP);\n var signUrlEncode = percentEncode(signBase64);\n return signUrlEncode;\n }\n}\nvar query = 'AccessKeyId=' + accessKeyId + '&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=' + java.randomUUID() + '&SignatureVersion=1.0&Timestamp=' + percentEncode(timestamp) + '&Version=2019-02-28';\nvar signStr = sign('GET&' + percentEncode('/') + '&' + percentEncode(query), accessKeySecret);\nvar queryStringWithSign = \"Signature=\" + signStr + \"&\" + query;\nvar body = java.ajax('http://nls-meta.cn-shanghai.aliyuncs.com/?' + queryStringWithSign)\nvar res = JSON.parse(body)\nif (res.Message) {\n throw new Error(res.Message)\n}\nvar header = { \"X-NLS-Token\": res.Token.Id };\nsource.putLoginHeader(JSON.stringify(header))", "loginUrl": "var loginInfo = source.getLoginInfoMap();\nvar accessKeyId = loginInfo.get('AccessKeyId');\nvar accessKeySecret = loginInfo.get('AccessKeySecret');\nvar timestamp = java.timeFormatUTC(new Date().getTime(), \"YYYY-MM-dd'T'HH:mm:ss'Z'\", 0);\nvar aly = new JavaImporter(Packages.javax.crypto.Mac, Packages.javax.crypto.spec.SecretKeySpec, Packages.javax.xml.bind.DatatypeConverter, Packages.java.net.URLEncoder, Packages.java.lang.String, Packages.android.util.Base64);\nwith (aly) {\n function percentEncode(value) {\n return URLEncoder.encode(value, \"UTF-8\").replace(\"+\", \"%20\")\n .replace(\"*\", \"%2A\").replace(\"%7E\", \"~\")\n }\n\n function sign(stringToSign, accessKeySecret) {\n var mac = Mac.getInstance('HmacSHA1');\n mac.init(new SecretKeySpec(String(accessKeySecret + '&').getBytes(\"UTF-8\"), \"HmacSHA1\"));\n var signData = mac.doFinal(String(stringToSign).getBytes(\"UTF-8\"));\n var signBase64 = Base64.encodeToString(signData, Base64.NO_WRAP);\n var signUrlEncode = percentEncode(signBase64);\n return signUrlEncode;\n }\n}\nvar query = 'AccessKeyId=' + accessKeyId + '&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=' + java.randomUUID() + '&SignatureVersion=1.0&Timestamp=' + percentEncode(timestamp) + '&Version=2019-02-28';\nvar signStr = sign('GET&' + percentEncode('/') + '&' + percentEncode(query), accessKeySecret);\nvar queryStringWithSign = \"Signature=\" + signStr + \"&\" + query;\nvar body = java.ajax('http://nls-meta.cn-shanghai.aliyuncs.com/?' + queryStringWithSign)\nvar res = JSON.parse(body)\nif (res.Message) {\n throw new Error(res.Message)\n}\nvar header = { \"X-NLS-Token\": res.Token.Id };\nsource.putLoginHeader(JSON.stringify(header))",
"loginUi": [ "loginUi": [
{ {

@ -16,7 +16,7 @@ val appDb by lazy {
} }
@Database( @Database(
version = 41, version = 42,
exportSchema = true, exportSchema = true,
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,

@ -37,7 +37,8 @@ object DatabaseMigrations {
migration_37_38, migration_37_38,
migration_38_39, migration_38_39,
migration_39_40, migration_39_40,
migration_40_41 migration_40_41,
migration_41_42
) )
} }
@ -329,4 +330,10 @@ object DatabaseMigrations {
database.execSQL("ALTER TABLE `httpTTS` ADD `concurrentRate` TEXT") database.execSQL("ALTER TABLE `httpTTS` ADD `concurrentRate` TEXT")
} }
} }
private val migration_41_42 = object : Migration(41, 42) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE 'httpTTS' ADD `contentType` TEXT")
}
}
} }

@ -17,6 +17,7 @@ data class HttpTTS(
val id: Long = System.currentTimeMillis(), val id: Long = System.currentTimeMillis(),
var name: String = "", var name: String = "",
var url: String = "", var url: String = "",
var contentType: String? = null,
override var concurrentRate: String? = null, override var concurrentRate: String? = null,
override var loginUrl: String? = null, override var loginUrl: String? = null,
override var loginUi: String? = null, override var loginUi: String? = null,

@ -8,6 +8,7 @@ import io.legado.app.constant.AppPattern
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.NoStackTraceException
import io.legado.app.model.ReadAloud import io.legado.app.model.ReadAloud
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
@ -133,6 +134,13 @@ class HttpReadAloudService : BaseReadAloudService(),
response = analyzeUrl.evalJS(checkJs, response) as Response response = analyzeUrl.evalJS(checkJs, response) as Response
} }
} }
httpTts.contentType?.let { contentTypeRegex ->
response.headers["Content-Type"]?.let { contentType ->
if (!contentType.matches(contentTypeRegex.toRegex())) {
throw NoStackTraceException(response.body!!.string())
}
}
}
response.body!!.bytes().let { bytes -> response.body!!.bytes().let { bytes ->
ensureActive() ensureActive()
val file = createSpeakFileAsMd5IfNotExist(fileName) val file = createSpeakFileAsMd5IfNotExist(fileName)
@ -321,7 +329,7 @@ class HttpReadAloudService : BaseReadAloudService(),
play() play()
return true return true
} }
AppLog.put("朗读错误,($what, $extra)") AppLog.put("朗读错误($what, $extra)\n${contentList[nowSpeak]}")
playErrorNo++ playErrorNo++
if (playErrorNo >= 5) { if (playErrorNo >= 5) {
toastOnUi("朗读连续5次错误, 最后一次错误代码($what, $extra)") toastOnUi("朗读连续5次错误, 最后一次错误代码($what, $extra)")

Loading…
Cancel
Save