はじめに、この小さなツールの由来について話しましょう。私は11月16日に東京で「AI応用開発の旅」というコミュニティイベントを開催する予定です(https://www.just-agi.com/event.html)。主に中国人向けのイベントなので中国語を使用しますが、友人が日本人を連れてくる予定で、日本語の字幕があるかどうか聞かれました。Teamsを見てみたところ、リアルタイム字幕はあるものの翻訳はありませんでしたので、自分でツールを作ることにしました。
このツールはWinFormで開発されており、源言語と翻訳後のテキストのみを表示し、その他の部分は透明化しています。リアルタイム翻訳にはMicrosoft Speechの翻訳APIを利用しており、開発には10分ほどしかかからなかったです。
MainForm.Designer.cs ファイル:
namespace JapneseHelper
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
ZhLab = new Label();
JaLab = new Label();
SuspendLayout();
//
// ZhLab
//
ZhLab.BackColor = Color.Transparent;
ZhLab.Dock = DockStyle.Bottom;
ZhLab.Font = new Font("Microsoft YaHei UI", 24F);
ZhLab.ForeColor = Color.White;
ZhLab.Location = new Point(0, 530);
ZhLab.Margin = new Padding(5, 0, 5, 0);
ZhLab.Name = "ZhLab";
ZhLab.Size = new Size(2259, 67);
ZhLab.TabIndex = 0;
ZhLab.Text = "这里是字幕";
ZhLab.TextAlign = ContentAlignment.MiddleCenter;
ZhLab.MouseDown += ControlMouseDown;
ZhLab.MouseMove += ControlMouseMove;
ZhLab.MouseUp += ControlMouseUp;
//
// JaLab
//
JaLab.BackColor = Color.Transparent;
JaLab.Dock = DockStyle.Fill;
JaLab.Font = new Font("Microsoft YaHei UI", 32F);
JaLab.ForeColor = Color.White;
JaLab.Location = new Point(0, 0);
JaLab.Margin = new Padding(5, 0, 5, 0);
JaLab.Name = "JaLab";
JaLab.Size = new Size(2259, 530);
JaLab.TabIndex = 1;
JaLab.TextAlign = ContentAlignment.BottomCenter;
JaLab.MouseDown += ControlMouseDown;
JaLab.MouseMove += ControlMouseMove;
JaLab.MouseUp += ControlMouseUp;
//
// MainForm
//
AutoScaleDimensions = new SizeF(19F, 41F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Black;
BackgroundImageLayout = ImageLayout.Stretch;
ClientSize = new Size(2259, 597);
Controls.Add(JaLab);
Controls.Add(ZhLab);
DoubleBuffered = true;
Font = new Font("Microsoft YaHei UI", 16F);
FormBorderStyle = FormBorderStyle.None;
Margin = new Padding(5);
Name = "MainForm";
Text = "字幕";
TopMost = true;
TransparencyKey = Color.Black;
Load += MainForm_Load;
ResumeLayout(false);
}
#endregion
private Label ZhLab;
private Label JaLab;
}
}
MainForm.cs ファイル:
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Translation;
namespace JapneseHelper
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
var sourceLanguage = System.Configuration.ConfigurationManager.AppSettings["sourceLanguage"];
var targetLanguage = System.Configuration.ConfigurationManager.AppSettings["targetLanguage"];
var apikey = System.Configuration.ConfigurationManager.AppSettings["apikey"];
var region = System.Configuration.ConfigurationManager.AppSettings["region"];
var config = SpeechTranslationConfig.FromSubscription(apikey, region);
config.SpeechRecognitionLanguage = sourceLanguage;
config.AddTargetLanguage(targetLanguage);
var recognizer = new TranslationRecognizer(config);
recognizer.Recognizing += (s, e) =>
{
this.Invoke(() =>
{
ZhLab.Text = e.Result.Text;
foreach (var element in e.Result.Translations)
{
JaLab.Text = element.Value;
}
});
};
recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false).GetAwaiter();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
var x = (workingArea.Width - this.Width) / 2 + workingArea.Left;
var y = workingArea.Bottom - this.Height;
this.Location = new Point(x, y);
}
private Point mouseOffset;
private bool isMouseDown = false;
private void ControlMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseOffset = new Point(-e.X, -e.Y);
isMouseDown = true;
}
}
private void ControlMouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouseOffset.X, mouseOffset.Y - this.Height / 2);
this.Location = mousePos;
}
}
private void ControlMouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isMouseDown = false;
}
}
}
}
効果画像:
ちょうど今週、営業部との会議で数回試用しましたが、全体的な意味は理解でき、現場の環境とも少し関係がありました。
(Translated by GPT)