You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebView传递大段SRT文本至谷歌翻译报错,寻求解决方案

解决WebView传递大SRT字符串到Google翻译的请求过大问题

问题根源

你遇到的报错核心原因是GET请求的URL长度存在浏览器/服务器限制,把完整SRT文本塞进URL的text参数时,超出了允许的最大长度,导致请求被拦截或失败。以下是几个实用的解决方案:


方案1:分块处理SRT内容

将SRT拆分为独立的字幕块(每个块包含序号、时间轴、字幕文本),仅翻译每个块中的文本部分,最后重新拼接成完整的SRT文件。这种方式既规避了超长URL,又能保证字幕结构不被破坏。

实现步骤:

  1. 解析SRT为字幕块:
data class SubtitleBlock(val index: String, val timestamp: String, val text: String)

fun parseSrt(srtContent: String): List<SubtitleBlock> {
    val blocks = mutableListOf<SubtitleBlock>()
    val lines = srtContent.split("\n")
    var i = 0
    while (i < lines.size) {
        val index = lines[i].trim()
        if (index.isEmpty()) {
            i++
            continue
        }
        val timestamp = lines[i+1].trim()
        val textBuilder = StringBuilder()
        i +=2
        while (i < lines.size && lines[i].trim().isNotEmpty()) {
            textBuilder.append(lines[i].trim()).append("\n")
            i++
        }
        blocks.add(SubtitleBlock(index, timestamp, textBuilder.toString().trim()))
        i++
    }
    return blocks
}
  1. 批量翻译并重组:
    循环调用翻译逻辑处理每个块的文本,完成后拼接回完整SRT:
fun translateSrtBlocks(blocks: List<SubtitleBlock>, from: String, into: String, webView: WebView, onComplete: (String) -> Unit) {
    val translatedBlocks = mutableListOf<SubtitleBlock>()
    var currentIndex = 0

    fun translateNextBlock() {
        if (currentIndex >= blocks.size) {
            val resultSrt = translatedBlocks.joinToString("\n\n") { "${it.index}\n${it.timestamp}\n${it.text}" }
            onComplete(resultSrt)
            return
        }
        val block = blocks[currentIndex]
        setupWebView(block.text, from, into, webView) { translatedText ->
            translatedBlocks.add(block.copy(text = translatedText))
            currentIndex++
            translateNextBlock()
        }
    }

    translateNextBlock()
}

方案2:改用POST请求提交文本

Google翻译支持通过POST方式提交待翻译文本,完全避开GET请求的URL长度限制。你可以在WebView中加载一个本地HTML表单,通过JavaScript自动提交POST请求。

修改后的setupWebView函数:

fun setupWebViewPost(
    input: String,
    from: String,
    into: String,
    webView: WebView,
    resultHandler: (String) -> Unit
) {
    webView.settings.javaScriptEnabled = true
    webView.addJavascriptInterface(JsInterface, "JsInterface")

    JsInterface.setResultCallback {
        resultHandler(it)
    }

    // 构造POST表单的HTML内容
    val html = """
        <html>
            <body>
                <form id="translateForm" action="https://translate.google.com/?sl=$from&tl=$into&op=translate" method="POST">
                    <textarea name="text" style="display:none">$input</textarea>
                </form>
                <script>
                    document.getElementById('translateForm').submit();
                </script>
            </body>
        </html>
    """.trimIndent()

    webView.loadDataWithBaseURL("https://translate.google.com/", html, "text/html", "UTF-8", null)

    webView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            view?.postDelayed({
                injectJavascript(view) // 保留你原有的注入JS提取结果的逻辑
            }, 2000) // 根据内容大小灵活调整延迟时间
        }
    }
}

方案3:过滤无需翻译的内容

SRT文件中的序号(如1、2)和时间轴(如00:00:01,000 --> 00:00:03,000)不需要翻译,可先剥离这些内容,仅发送纯字幕文本,翻译完成后再重新拼接。

示例代码:

fun extractTextFromSrt(srtContent: String): Pair<List<String>, List<String>> {
    val nonTranslatableParts = mutableListOf<String>()
    val translatableTexts = mutableListOf<String>()
    val lines = srtContent.split("\n")
    var i = 0
    while (i < lines.size) {
        val index = lines[i].trim()
        if (index.isEmpty()) {
            i++
            continue
        }
        val timestamp = lines[i+1].trim()
        nonTranslatableParts.add("$index\n$timestamp")
        val textBuilder = StringBuilder()
        i +=2
        while (i < lines.size && lines[i].trim().isNotEmpty()) {
            textBuilder.append(lines[i].trim()).append("\n")
            i++
        }
        translatableTexts.add(textBuilder.toString().trim())
        i++
    }
    return Pair(nonTranslatableParts, translatableTexts)
}

// 翻译后重新拼接成完整SRT
fun reconstructSrt(nonTranslatable: List<String>, translatedTexts: List<String>): String {
    return nonTranslatable.zip(translatedTexts).joinToString("\n\n") { "${it.first}\n${it.second}" }
}

额外优化建议

  • 动态调整postDelayed延迟:避免固定1秒等待,可根据文本长度设置更长的延迟,确保翻译结果完全加载。
  • 增加重试机制:如果某块翻译失败,自动重试1-2次,提升整体稳定性。

内容的提问来源于stack exchange,提问作者Roony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:44:53