感谢:
绿云牧歌提供的翻译文档方法:https://blog.csdn.net/qq_32069969/article/details/88360608
我扶奶奶过哈登提供的调用百度翻译API方法:https://blog.csdn.net/u014571132/article/details/53334930
百度翻译提供的免费API
为了使用此功能,你需要前往https://fanyi-api.baidu.com/doc/21获得百度翻译的调用API权限。
免费档的权限为每秒钟1条,每次上限5000字。
using System.Net.Http.Json;
using System.Reactive.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Xml.Linq;
/// <summary>
/// 百度翻译AIP,你需要从<see href ="https://fanyi-api.baidu.com/api/trans/product/desktop?req=developer"/>获取密钥
/// <br/>这是免费且无需审核的。
/// </summary>
public class BaiduTranslation
{
#region 语种常量
public const string 自动检测 = "auto";
public const string 中文 = "zh";
public const string 英语 = "en";
public const string 粤语 = "yue";
public const string 文言文 = "wyw";
public const string 日语 = "jp";
public const string 韩语 = "kor";
public const string 法语 = "fra";
public const string 西班牙语 = "spa";
public const string 泰语 = "th";
public const string 阿拉伯语 = "ara";
public const string 俄语 = "ru";
public const string 葡萄牙语 = "pt";
public const string 德语 = "de";
public const string 意大利语 = "it";
public const string 希腊语 = "el";
public const string 荷兰语 = "nl";
public const string 波兰语 = "pl";
public const string 保加利亚语 = "bul";
public const string 爱沙尼亚语 = "est";
public const string 丹麦语 = "dan";
public const string 芬兰语 = "fin";
public const string 捷克语 = "cs";
public const string 罗马尼亚语 = "rom";
public const string 斯洛文尼亚语 = "slo";
public const string 瑞典语 = "swe";
public const string 匈牙利语 = "hu";
public const string 繁体中文 = "cht";
public const string 越南语 = "vie";
#endregion
private readonly string ID;
private readonly string Key;
private readonly TimeSpan delay;
private DateTime last;
private const string API_URL = "http://api.fanyi.baidu.com/api/trans/vip/translate";
HttpClient http = new HttpClient();
/// <summary>
/// 实例化一个对接百度翻译的对象。你需要从这里获取使用权限:<see href ="https://fanyi-api.baidu.com/api/trans/product/desktop?req=developer"/>
/// </summary>
/// <param name="APPID">百度提供的ID</param>
/// <param name="Key">百度提供的密钥</param>
/// <param name="delay">每次请求前的延迟。默认为最低档的1000毫秒</param>
public BaiduTranslation(string APPID, string Key, int delay = 1000)
{
this.delay = TimeSpan.FromMilliseconds(delay);
ID = APPID;
this.Key = Key;
}
/// <summary>
/// 发送一个翻译请求
/// </summary>
/// <param name="source">源字符串,上限6000字节(约2000个中文)</param>
/// <param name="from">源语种</param>
/// <param name="to">目标语种</param>
/// <returns>序列化后的输出</returns>
public async Task<TransJson_Result> GetTranslationAsync(string source, string from = 自动检测, string to = 中文)
{
if (string.IsNullOrEmpty(source))
return null;
string md5string = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes($"{ID}{source}{last.Millisecond}{Key}"))).ToLower();
string utf8 = HttpUtility.UrlEncode(source, Encoding.UTF8);
string url = $"{API_URL}?q={utf8}&from={from}&to={to}&appid={ID}&salt={last.Millisecond}&sign={md5string}";
TimeSpan time = last + delay - (last = DateTime.Now);
await Task.Delay(time < TimeSpan.Zero ? default : time);
return await http.GetFromJsonAsync<TransJson_Result>(url);
}
public async IAsyncEnumerable<TransJson_Result> GetTranslationAsync(IEnumerable<string> source, string from = 自动检测, string to = 中文)
{
var erator = source.GetEnumerator();
StringBuilder sb = new StringBuilder(6000);
while (erator.MoveNext())
{
sb.AppendLine(erator.Current);
if (HttpUtility.UrlEncode(sb.ToString(), Encoding.UTF8).Length > 5000)
{
sb.Remove(sb.Length - erator.Current.Length - 1, erator.Current.Length);
yield return await GetTranslationAsync(sb.ToString(), from, to);
sb.Clear();
sb.AppendLine(erator.Current);
}
}
yield return await GetTranslationAsync(sb.ToString(), from, to);
}
public async Task TranslationXmlAsync(string path, string from = 自动检测, string to = 中文)
{
XElement xml;
using (var read = File.OpenRead(path))
{
xml = await XElement.LoadAsync(File.OpenRead(path), LoadOptions.None, CancellationToken.None);
}
List<XText> list = new List<XText>();
foreach (var item in xml.DescendantNodes())
{
if (item is XText text && item.Parent.Name != "code")
{
list.Add(text);
}
}
List<string> src = list.SelectMany(t => t.Value.Split("\n"))
.Select(s => s.Trim()).Distinct().ToList();
Dictionary<string, string> dic = new Dictionary<string, string>();
await foreach (var item in GetTranslationAsync(src, from, to))
{
foreach (var item2 in item)
{
dic[item2.src] = item2.dst;
}
await Console.Out.WriteLineAsync($"{1.0 * dic.Count / src.Count:P2}");
}
foreach (var text in list)
{
if (dic.TryGetValue(text.Value.Trim(), out var val))
{
text.Value = val;
}
else
{
StringBuilder sb = new StringBuilder();
foreach (var item in text.Value.Split("\n"))
{
if (string.IsNullOrWhiteSpace(item))
continue;
else if (dic.TryGetValue(item.Trim(), out val))
{
sb.AppendLine(val);
}
else
{
goto Exception;
}
}
text.Value = sb.ToString();
}
continue;
Exception:
await Console.Out.WriteLineAsync("无法找到" + text.Value);
}
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(path), "zh-hans"));
using var write = File.Open(Path.Combine(Path.GetDirectoryName(path), "zh-hans", Path.GetFileName(path)), FileMode.Create);
await xml.SaveAsync(write, SaveOptions.None, CancellationToken.None);
}
}
/// <summary>
/// 返回的翻译结果
/// </summary>
public class TransJson_Result
{
/// <summary>
/// 错误码
/// <list type="table">
/// <item>
/// <term>52000</term>
/// <description>成功。</description>
/// </item>
/// <item>
/// <term>52001</term>
/// <description>请求超时。请重试</description>
/// </item>
/// <item>
/// <term>52002</term>
/// <description>系统错误。请重试</description>
/// </item>
/// <item>
/// <term>52003</term>
/// <description>未授权用户。请检查appid是否正确或者服务是否开通</description>
/// </item>
/// <item>
/// <term>54000</term>
/// <description>必填参数为空。请检查是否少传参数</description>
/// </item>
/// <item>
/// <term>54001</term>
/// <description>签名错误。请检查您的签名生成方法</description>
/// </item>
/// <item>
/// <term>54003</term>
/// <description>访问频率受限。请降低您的调用频率,或进行身份认证后切换为高级版/尊享版</description>
/// </item>
/// <item>
/// <term>54004</term>
/// <description>账户余额不足。请前往<see href ="https://api.fanyi.baidu.com/api/trans/product/desktop">管理控制台</see>为账户充值</description>
/// </item>
/// <item>
/// <term>54005</term>
/// <description>长query请求频繁。请降低长query的发送频率,3s后再试</description>
/// </item>
/// <item>
/// <term>58000</term>
/// <description>客户端IP非法。检查个人资料里填写的IP地址是否正确,可前往<see href ="https://api.fanyi.baidu.com/access/0/3">开发者信息-基本信息</see> 修改 </description>
/// </item>
/// <item>
/// <term>58001</term>
/// <description>译文语言方向不支持。检查译文语言是否在语言列表里</description>
/// </item>
/// <item>
/// <term>58002</term>
/// <description>服务当前已关闭。请前往<see href ="https://api.fanyi.baidu.com/choose">管理控制台</see>开启服务</description>
/// </item>
/// <item>
/// <term>90107</term>
/// <description>认证未通过或未生效。请前往<see href ="https://api.fanyi.baidu.com/myIdentify">我的认证</see>查看认证进度</description>
/// </item>
///</list>
///</summary>
public string error_code { get; set; }
/// <summary>
/// 错误消息
/// </summary>
public string error_msg { get; set; }
/// <summary>
/// 源语种
/// </summary>
public string from { get; set; }
/// <summary>
/// 目标语种
/// </summary>
public string to { get; set; }
public Trans_Result[] trans_result { get; set; }
public IEnumerator<Trans_Result> GetEnumerator()
{
foreach (var item in trans_result)
{
yield return item;
}
}
public class Trans_Result
{
/// <summary>
/// 源字符串
/// </summary>
public string src { get; set; }
/// <summary>
/// 翻译后的字符串
/// </summary>
public string dst { get; set; }
public void Deconstruct(out string src, out string dst)
{
src = this.src;
dst = this.dst;
}
}
}
使用方法:
找到你的unity安装路径,然后搜索xml。找到xml很多的文件夹
然后遍历这个文件夹,筛选所有后缀为xml的文件。执行翻译。
var baidu = new BaiduTranslation("2022", "OPEN_AI_GPT");
foreach (var item in Directory.GetFiles("B:\\Unity\\2022.2.9f1c1\\Editor\\Data\\Managed\\UnityEngine"))
{
if (Path.GetExtension(item).ToLower() == ".xml")
{
await baidu.TranslationXmlAsync(item);
}
}