当前位置: 首页 > article >正文

调用百度翻译API翻译日语srt字幕

先了解下srt字幕的格式:

1
00:00:00,003 --> 00:00:01,003
第一句

2
00:00:02,520 --> 00:00:03,090
第二句

语句序号占一行,起止时间轴点占一行,语句占接下来的一行(或多行) 然后带一个空行
格式比较简单,node.js有第三方库subtitles-parser可以解析srt格式字符串

const fs=require('fs');
const srtpath="yoursrtpath"; //srt路径
const srtContent = fs.readFileSync(srtpath+process.argv.slice(2)[0]+'.srt', 'utf8');
const SubtitlesParser = require('subtitles-parser');
const subtitles = SubtitlesParser.fromSrt(srtContent);

解析后得到一个subtitles对象数组,对象包含起止时间和语句文本,
注意下:srt文件最好是utf8 without bom的编码。

要调用百度翻译api,首先你需要在百度翻译注册账号开通通用文本翻译服务,注册后得到appid和密钥,可以根据自己的情况开通不同级别的服务。标准版(注册后未认证):每月前5万字符免费(QPS=1),超出要收取超出部分费用;单次最长请求1000字符。高级版(个人认证):每月前100万字符免费(QPS=10),超出要收取超出部分费用;单次最长请求6000字符。
调用方式也比较简单,get方式访问翻译url,传入query参数,其中包含源语言,目标语言,待翻译语句,appid和盐和签名,其中盐可以是时间戳,签名是包含APP ID 、 待翻译语句、盐和密钥这些字符串连接起来的串的md5值的16进制码。具体代码如下:

const axios = require('axios');
const crypto = require('crypto');
const APP_ID = 'yourbaiduappid';
const SECRET_KEY = 'yourbaiduappkey';
const URL = 'https://fanyi-api.baidu.com/api/trans/vip/translate';

async function translateText(query, from, to) {
	const salt = Date.now();
	const sign = crypto.createHash('md5').update(APP_ID + query + salt + SECRET_KEY).digest('hex');

	const params = {
		q: query,
		from: from,
		to: to,
		appid: APP_ID,
		salt: salt,
		sign: sign
		};

	try {
		const response = await axios.get(URL, { params });
		return response.data;
		} catch (error) { console.error('Error calling Baidu Translate API:', error); }
	}

为降低api调用频次,可以将srt中多条语句合并起来成批发送。这里提醒下,调用百度翻译api是get方式,请求中翻译语句会采用url编码,这样一个日语字符会占用9个字符位,由于url也有长度限制,所以需要自行调整下每次最大传输字符数。

const maxlength=600; //根据具体情况调整
let rows=subtitles.length; //srt文件中语句数量
let bufrows="";
let start=0;

(async()=>{
//批量翻译 减少调用百度翻译服务次数,翻译结果覆盖subtitles数组中对象的text值
for (let i=0;i<rows;i++) {
	if (bufrows.length+subtitles[i]["text"].length+2>maxlength) {
		let data=await translateText(bufrows, 'jp', 'zh');
		if (data.error_code) console.log(data)
		else for (let j=0;j<data.trans_result.length;j++) subtitles[start+j]["text"]=data.trans_result[j]["dst"];
		bufrows=subtitles[i]["text"]+"\n";
		start=i;
		}
	else bufrows+=subtitles[i]["text"]+"\n";
	}

let data=await translateText(bufrows, 'jp', 'zh');
if (data.error_code) { console.log(data); }
else {
for (let j=0;j<data.trans_result.length;j++) {
	subtitles[start+j]["text"]=data.trans_result[j]["dst"];
	}
}

//保存subtitles到srt文件
const newSrtContent = SubtitlesParser.toSrt(subtitles);
fs.writeFileSync(srtpath+process.argv.slice(2)[0]+'.cn.srt', newSrtContent);
})();

执行后没有提示报错就可以得到翻译好的汉语字幕了。
有报错的话,要检查下看是哪里的问题。我就遇到百度翻译提示命中敏感词而拒绝当次调用的情况,这种情况下,其实你也没有必要去定位找哪一句命中了,可以考虑用百度翻译的网页版。
从原始字幕文件中提取语句文本出来,

//srt2txt.js
const fs=require('fs');
const srtpath="yoursrtpath"; //srt路径

const SubtitlesParser = require('subtitles-parser');
const srtContent = fs.readFileSync(srtpath+process.argv.slice(2)[0]+'.srt', 'utf8');
const subtitles = SubtitlesParser.fromSrt(srtContent);

let newstr="";
subtitles.forEach(item=>{ newstr+=item.text.replace(/[\r\n]/g, " ")+"\n"; });

fs.writeFileSync(srtpath+process.argv.slice(2)[0]+'.txt', newstr);

将全部语句内容粘贴进网页原文处(注意有10000个字符长度限制,如果超出就先分成几段分别翻译),待翻译完成后,把翻译结果保存到本地txt文件,再使用源字幕的时间轴保存为新的字幕文件。

const fs=require('fs');
const srtpath="yoursrtpath"; //srt路径

const data = fs.readFileSync(srtpath+process.argv.slice(2)[0]+'.cn.txt', 'utf8');//百度翻译网页版翻译结果保存的文件
const lines = data.split('\r\n');

const SubtitlesParser = require('subtitles-parser');
const srtContent = fs.readFileSync(srtpath+process.argv.slice(2)[0]+'.srt', 'utf8');//原始srt字幕文件
const subtitles = SubtitlesParser.fromSrt(srtContent);

let len=subtitles.length;
for (let i=0;i<len;i++) subtitles[i]["text"]=lines[i];

const newSrtContent = SubtitlesParser.toSrt(subtitles);
fs.writeFileSync(srtpath+process.argv.slice(2)[0]+'.cn.srt', newSrtContent);//翻译后的字幕文件

什么,只有视频,没有字幕文件怎么办,推荐一下集成了语言识别vosk的视频字幕工具SubtitleEdit,其实它也支持自动翻译功能,不过它调用的是google翻译或微软bing翻译API,目前我们这里访问有些问题,所以只好退而求其次,整出srt字幕,再自行翻译处理,国内能免费使用的翻译api其实也有好几个,比较了下,百度的给的免费额度大一些。


http://www.kler.cn/a/531584.html

相关文章:

  • Baklib如何在知识管理领域成为领军者与六款产品的综合评析
  • Linux - 进程间通信(3)
  • 一个开源 GenBI AI 本地代理(确保本地数据安全),使数据驱动型团队能够与其数据进行互动,生成文本到 SQL、图表、电子表格、报告和 BI
  • Flask数据的增删改查(CRUD)_flask删除数据自动更新
  • 在ubuntu下一键安装 Open WebUI
  • 9 点结构模块(point.rs)
  • MATLAB实现单层竞争神经网络数据分类
  • 95,【3】 buuctf web [安洵杯 2019]easy_web
  • DeepSeek推动大语言模型发展进入新阶段
  • Turing Complete-1位开关
  • 2022 年 6 月大学英语四级考试真题(第 3 套)——纯享题目版
  • 四川正熠法律咨询有限公司正规吗可信吗?
  • blender 相机参数
  • 求水仙花数,提取算好,打表法。或者暴力解出来。
  • 利用Vue和javascript分别编写一个“Hello World”的定时更新
  • OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)
  • 【16届蓝桥杯寒假刷题营】第2期DAY2
  • mysql操作语句与事务
  • C++STL(一)——string类
  • “深度强化学习揭秘:掌握DQN与PPO算法的精髓“
  • ubuntu磁盘扩容
  • 分析哲学:从 语言解剖到 思想澄清的哲学探险
  • Linux 权限 详细版!!
  • 使用朴素贝叶斯对自定义数据集进行分类
  • 2024联想春招硬件嵌入式开发真题及答案解析
  • Unity-编译构建Android的问题记录