Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

【Unity】DeepLで文書翻訳してみた

$
0
0
1. はじめに ノベルワークスR&Dチームのユウガです。現在は, バーチャルオフィスの開発を行っています。 バーチャルオフィスの機能の1つとして, DeepL文書翻訳をやってみたので紹介します。 主に新しい技術のリサーチをしているため, 最新のドキュメントはだいたい英語だったりします。「このドキュメント日本語にして読みたいなぁ」と思った時に, すぐに翻訳できると便利です。また, 外国人とチャットでやりとりしていて, ファイルを共有された時に, すぐに母国語に翻訳できると便利ですよね。 DeepLを使えば日本語で作った製品案内とかを瞬時に翻訳できるので, 海外への営業・販売など比較的容易に展開できるようになるかもしれませんね。 所見としては, 文書翻訳はベータ版ではありますが, かなり精度も良くて, 全然使えると思いました。また, 画像が添付されてる場合も, レイアウトが崩れる事なく, 翻訳できた印象です。 環境 ・windows10 ・Unity2020.3.2f.1 2. DeepL文書翻訳 翻訳できるファイル形式は, Word(.docx), PowerPoint(.pptx), Text(.txt), HTML(.html) です。 ファイルサイズ&文字数の制限は, Word(.docx), PowerPoint(.pptx)が, 10MBまたは100万文字。Text(.txt)が, 1MBまたは100万文字。 HTML(.html)が, 5MBまたは100万文字です。 DeepL API プランの場合は, 好きなだけ文書翻訳できるそうです。 このプランは従量課金制で, 1か月の基本料金630円に加え, 1文字あたり0.0025円として料金が請求されます。 注意点としては, 文字数が少ない場合も, 1ファイルにつき最低5万文字分が請求されます。5万文字以上の場合は, 文字数分の料金が請求されます。 なので, 1ファイルにつき最低でも125円かかります. テストしてる時, これに気が付かなくて焦りました(-_-;) 3. 実装 DeeplFileTranslator.cs using UnityEngine; using UnityEngine.Networking; using System; using System.IO; using System.Collections.Generic; using System.Threading.Tasks; public static class DeeplFileTranslator { [Serializable] public class ResponseForUpload { public string document_id; public string document_key; } [Serializable] public class ResponseForCheck { public string document_id; public string status; public string seconds_remaining; public string billed_characters; } private static readonly string auth_key = "XXX"; public static async Task<string> Upload(string path, string filename, string target_lang, string content_type) { // pathにあるファイルを読み込む byte[] rawdata = File.ReadAllBytes(path); List<IMultipartFormSection> requestData = new List<IMultipartFormSection>(); requestData.Add(new MultipartFormDataSection("auth_key",auth_key)); requestData.Add(new MultipartFormDataSection("target_lang",target_lang)); requestData.Add(new MultipartFormFileSection("file", rawdata, filename, content_type)); UnityWebRequest request = UnityWebRequest.Post("https://api.deepl.com/v2/document", requestData); await request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError) { Debug.LogError(request.error); return "error"; } return request.downloadHandler.text; } public static async Task<string> CheckStatus(string document_id, string document_key) { List<IMultipartFormSection> requestData = new List<IMultipartFormSection>(); requestData.Add(new MultipartFormDataSection("auth_key",auth_key)); requestData.Add(new MultipartFormDataSection("document_key",document_key)); UnityWebRequest request = UnityWebRequest.Post("https://api.deepl.com/v2/document/"+document_id, requestData); await request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError) { Debug.LogError(request.error); return "error"; } return request.downloadHandler.text; } public static async Task<string> Download(string document_id, string document_key, string output_path) { List<IMultipartFormSection> requestData = new List<IMultipartFormSection>(); requestData.Add(new MultipartFormDataSection("auth_key",auth_key)); requestData.Add(new MultipartFormDataSection("document_key",document_key)); UnityWebRequest request = UnityWebRequest.Post("https://api.deepl.com/v2/document/"+document_id+"/result", requestData); await request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError) { Debug.LogError(request.error); return "error"; } // output_pathにデータを書き込む byte[] rawdata = request.downloadHandler.data; File.WriteAllBytes(output_path, rawdata); return "success"; } } このコードは見てもらえば分かると思いますが, UnityWebRequestを使って, DeepLとやりとりしてます。 UnityWebRequestでasync/awaitを使いたかったので, こちらのコードも使いました。 auth_keyの所は, ダッシュボードにある Authentication Key を入力してください。 FileTranlateManager.cs using UnityEngine; using UnityEngine.UI; using System; using System.IO; using System.Threading.Tasks; public class FileTranslateManager : MonoBehaviour { [SerializeField] Button fileTranslateButton; private string document_id; private string document_key; void Start() { fileTranslateButton.onClick.AddListener(async () => { string path = @"C:\Users\username\Documetns\test.docx"; string target_lang = "EN-US"; await DeeplFileTranslate(path, target_lang); }); } private async Task DeeplFileTranslate(string path, string target_lang) { string ext = Path.GetExtension(path); string filenameWithoutExt = Path.GetFileNameWithoutExtension(path); string output_path = "C:\\Users\\" + Environment.UserName + "\\Downloads\\" + filenameWithoutExt + "_" + target_lang + ext; string jsonString = null; int millisecond = null; // Deeplにアップロード jsonString = await DeeplFileTranslator.Upload(path, filenameWithoutExt+ext, target_lang, GetContentType(ext)); if (jsonString == "error") return; var responsForUpload = JsonUtility.FromJson<DeeplFileTranslator.ResponseForUpload>(jsonString); document_id = responsForUpload.document_id; document_key = responsForUpload.document_key; // 翻訳状況をチェック while (true) { jsonString = await DeeplFileTranslator.CheckStatus(document_id, document_key); if (jsonString == "error") return; // 翻訳完了なら, ループを抜ける var responseForCheck = JsonUtility.FromJson<DeeplFileTranslator.ResponseForCheck>(jsonString); if (responseForCheck.status == "done") break; if (!String.IsNullOrEmpty(responseForCheck.seconds_remaining)) { millisecond = int.Parse(responseForCheck.seconds_remaining) * 1000; Debug.Log($"{millisecond / 1000}s remaining."); } else { millisecond = 1000; } await Task.Delay(millisecond); // ミリ秒待つ } // Deeplからダウンロード jsonString = await DeeplFileTranslator.Download(document_id, document_key, output_path); if (jsonString == "error") return; // 翻訳完了を知らせるために, ダウンロードフォルダを開く Application.OpenURL("file:C:\\Users\\" + Environment.UserName + "\\Downloads"); document_id = null; document_key = null; return; } private static string GetContentType(string ext) { switch(ext) { case ".docx": return "application/vnd.openxmlformats-officedocument.wordprocessingm"; case ".pptx": return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; case ".txt": return "text/plain"; case ".html": return "text/html"; default: return null; } } } このコードは, DeeplFileTranslatorのメソッドを呼び出して, 処理を実行してくれます。 翻訳状況をチェックの所で, 翻訳完了したらループを抜けるようにしてますが, あんまり良くないなぁと思ってるので, こう書いたら良いよって方がいたら教えてください!! 4. おわりに 個人的には, PDFも翻訳してくれたらありがたいのですが, DeeplAPIでは無理です。 なので, PDFを翻訳したければ, CloudConvertAPIを使って, word(.docx)に変換してから, DeepL翻訳すると良いかもしれません。

Viewing all articles
Browse latest Browse all 9703

Trending Articles