クイック スタート: リアルタイムでの会話の文字起こしのマルチチャンネル ダイアライゼーション (プレビュー)
Note
現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。
会話の文字起こしのマルチチャンネル ダイアライゼーションを使用すると、音声を Speech サービスにストリーミングすることによって、複数の参加者を追加、削除、識別する機能を使用して、会議を文字起こしできます。 まず、REST API を使用して各参加者の音声署名を作成し、次に、それらの音声署名を Speech SDK で使用して会議を文字起こしします。 詳細については、会話の文字起こしの概要に関するページを参照してください。
重要
会話の文字起こしのマルチチャンネル ダイアライゼーション (プレビュー) は、2025 年 3 月 28 日に廃止されます。 他の音声テキスト変換機能への移行の詳細については、「会話の文字起こしマルチチャンネル ダイアライゼーションから移行する」を参照してください。
制限事項
- 次のサブスクリプション リージョンでのみ使用できます:
centralus
、eastasia
、eastus
、westeurope
- 7 つのマイクの循環マルチマイク配列が必要です。 このマイク配列は、Microsoft の仕様を満たす必要があります。
Note
会話の文字起こしのマルチチャンネル ダイアライゼーション機能では、ConversationTranscriber
ではなく MeetingTranscriber
を使用し、CreateConversationAsync
の代わりに CreateMeetingAsync
を使用します。
前提条件
- Azure サブスクリプション。 無料で作成できます。
- Azure ポータルで、音声リソースを作成します。
- Speech リソース キーとリージョンを取得します。 音声リソースがデプロイされたら、[リソースに移動] を選択して、キーを表示および管理します。
環境をセットアップする
何らかの操作を行うには、事前に Speech SDK for JavaScript をインストールしておく必要があります。 パッケージ名のインストールだけが必要な場合は、npm install microsoft-cognitiveservices-speech-sdk
を実行します。 詳しいインストール手順については、SDK のインストール ガイドを参照してください。
声紋を作成する
ユーザー プロファイルを登録する場合は、最初の手順で会議の参加者の声紋を作成して、一意の話者として識別できるようにします。 特定の参加者を識別するために、事前に登録したユーザー プロファイルを使用しない場合、これは必須ではありません。
声紋を作成するための入力 .wav
音声ファイルは、16 ビット、16 kHz のサンプル レート、およびシングル チャンネル (モノラル) 形式である必要があります。 各オーディオ サンプルの推奨される長さは、30 秒から 2 分です。 オーディオ サンプルが短すぎると、話者を認識するときの精度が低下します。 一意の音声プロファイルを作成するため、.wav
ファイルは 1 人の音声のサンプルである必要があります。
次の例は、JavaScript で REST API を使用して声紋を作成する方法を示しています。 subscriptionKey
、region
、サンプル .wav
ファイルへのパスを挿入する必要があります。
const fs = require('fs');
const axios = require('axios');
const formData = require('form-data');
const subscriptionKey = 'your-subscription-key';
const region = 'your-region';
async function createProfile() {
let form = new formData();
form.append('file', fs.createReadStream('path-to-voice-sample.wav'));
let headers = form.getHeaders();
headers['Ocp-Apim-Subscription-Key'] = subscriptionKey;
let url = `https://signature.${region}.cts.speech.microsoft.com/api/v1/Signature/GenerateVoiceSignatureFromFormData`;
let response = await axios.post(url, form, { headers: headers });
// get signature from response, serialize to json string
return JSON.stringify(response.data.Signature);
}
async function main() {
// use this voiceSignature string with meeting transcription calls below
let voiceSignatureString = await createProfile();
console.log(voiceSignatureString);
}
main();
このスクリプトを実行すると、voiceSignatureString
変数に声紋文字列が返されます。 この関数を 2 回実行して、下記の voiceSignatureStringUser1
および voiceSignatureStringUser2
変数への入力として使用する 2 つの文字列を作成します。
Note
声紋は、REST API を使用してのみ作成できます。
会議を文字起こしする
次のサンプル コードは、2 人の話者の会議をリアルタイムで文字起こしする方法を示しています。 上の手順に従って各話者の音声署名文字列が作成されていることを前提としています。 subscriptionKey
、region
、および文字起こしする音声のパス filepath
を、実際の情報に置き換えます。
事前登録されたユーザー プロファイルを使用しない場合、speaker1、speaker2 などとして不明なユーザーの最初の認識を完了するまでにさらに数秒かかります。
Note
署名の作成にアプリケーション全体で同じ subscriptionKey
が使用されていることを確認してください。そうでないと、エラーが発生します。
このサンプル コードは、次の処理を実行します。
- 文字起こしに使用するプッシュ ストリームを作成し、サンプル
.wav
ファイルをそれに書き込みます。 createMeetingAsync()
を使用してMeeting
を作成します。- コンストラクターを使用して
MeetingTranscriber
を作成します。 - 会議に参加者を追加します。 上記の手順の出力として、文字列
voiceSignatureStringUser1
とvoiceSignatureStringUser2
が得られます。 - イベントに登録し、文字起こしを開始します。
- 音声サンプルを提供せずに話者を区別したい場合は、会議の文字起こしの概要に関するページにあるように、
DifferentiateGuestSpeakers
機能を有効にします。
話者の識別または区別が有効になっている場合は、既に transcribed
結果を受け取っている場合でも、サービスは蓄積されたオーディオ情報によってそれらを評価します。 サービスで、以前の結果に正しくない speakerId
が割り当てられていることが検出された場合、ほぼ同じで speakerId
と UtteranceId
のみが異なる Transcribed
結果が再び送信されます。 UtteranceId
の形式は {index}_{speakerId}_{Offset}
であるため、transcribed
結果を受け取ると、UtteranceId
を使用して、現在の transcribed
結果が前の結果を修正するかどうかを判断できます。 クライアントまたは UI ロジックで、以前の出力の上書きなどの動作を決定したり、最新の結果を無視したりできます。
(function() {
"use strict";
var sdk = require("microsoft-cognitiveservices-speech-sdk");
var fs = require("fs");
var subscriptionKey = "your-subscription-key";
var region = "your-region";
var filepath = "audio-file-to-transcribe.wav"; // 8-channel audio
var speechTranslationConfig = sdk.SpeechTranslationConfig.fromSubscription(subscriptionKey, region);
var audioConfig = sdk.AudioConfig.fromWavFileInput(fs.readFileSync(filepath));
speechTranslationConfig.setProperty("ConversationTranscriptionInRoomAndOnline", "true");
// en-us by default. Adding this code to specify other languages, like zh-cn.
speechTranslationConfig.speechRecognitionLanguage = "en-US";
// create meeting and transcriber
var meeting = sdk.Meeting.createMeetingAsync(speechTranslationConfig, "myMeeting");
var transcriber = new sdk.MeetingTranscriber(audioConfig);
// attach the transcriber to the meeting
transcriber.joinMeetingAsync(meeting,
function () {
// add first participant using voiceSignature created in enrollment step
var user1 = sdk.Participant.From("user1@example.com", "en-us", voiceSignatureStringUser1);
meeting.addParticipantAsync(user1,
function () {
// add second participant using voiceSignature created in enrollment step
var user2 = sdk.Participant.From("user2@example.com", "en-us", voiceSignatureStringUser2);
meeting.addParticipantAsync(user2,
function () {
transcriber.sessionStarted = function(s, e) {
console.log("(sessionStarted)");
};
transcriber.sessionStopped = function(s, e) {
console.log("(sessionStopped)");
};
transcriber.canceled = function(s, e) {
console.log("(canceled)");
};
transcriber.transcribed = function(s, e) {
console.log("(transcribed) text: " + e.result.text);
console.log("(transcribed) speakerId: " + e.result.speakerId);
};
// begin meeting transcription
transcriber.startTranscribingAsync(
function () { },
function (err) {
console.trace("err - starting transcription: " + err);
});
},
function (err) {
console.trace("err - adding user1: " + err);
});
},
function (err) {
console.trace("err - adding user2: " + err);
});
},
function (err) {
console.trace("err - " + err);
});
}());
前提条件
- Azure サブスクリプション。 無料で作成できます。
- Azure ポータルで、音声リソースを作成します。
- Speech リソース キーとリージョンを取得します。 音声リソースがデプロイされたら、[リソースに移動] を選択して、キーを表示および管理します。
環境をセットアップする
Speech SDK は NuGet パッケージとして提供されていて、.NET Standard 2.0 が実装されています。 Azure Cognitive Service for Speech SDK は、このガイドの後半でインストールしますが、まず、これ以上要件がないかプラットフォーム固有のインストール手順を確認してください。
声紋を作成する
ユーザー プロファイルを登録する場合は、最初の手順で会議の参加者の声紋を作成して、一意の話者として識別できるようにします。 特定の参加者を識別するために、事前に登録したユーザー プロファイルを使用しない場合、これは必須ではありません。
声紋を作成するための入力 .wav
音声ファイルは、16 ビット、16 kHz のサンプル レート、およびシングル チャンネル (モノラル) 形式である必要があります。 各オーディオ サンプルの推奨される長さは、30 秒から 2 分です。 オーディオ サンプルが短すぎると、話者を認識するときの精度が低下します。 一意の音声プロファイルを作成するため、.wav
ファイルは 1 人の音声のサンプルである必要があります。
次の例は、C# で REST API を使用して音声署名を作成する方法を示しています。 subscriptionKey
、region
、サンプル .wav
ファイルへのパスを挿入する必要があります。
using System;
using System.IO;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Newtonsoft.Json;
[DataContract]
internal class VoiceSignature
{
[DataMember]
public string Status { get; private set; }
[DataMember]
public VoiceSignatureData Signature { get; private set; }
[DataMember]
public string Transcription { get; private set; }
}
[DataContract]
internal class VoiceSignatureData
{
internal VoiceSignatureData()
{ }
internal VoiceSignatureData(int version, string tag, string data)
{
this.Version = version;
this.Tag = tag;
this.Data = data;
}
[DataMember]
public int Version { get; private set; }
[DataMember]
public string Tag { get; private set; }
[DataMember]
public string Data { get; private set; }
}
private static async Task<string> GetVoiceSignatureString()
{
var subscriptionKey = "your-subscription-key";
var region = "your-region";
byte[] fileBytes = File.ReadAllBytes("path-to-voice-sample.wav");
var content = new ByteArrayContent(fileBytes);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
var response = await client.PostAsync($"https://signature.{region}.cts.speech.microsoft.com/api/v1/Signature/GenerateVoiceSignatureFromByteArray", content);
var jsonData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<VoiceSignature>(jsonData);
return JsonConvert.SerializeObject(result.Signature);
}
関数 GetVoiceSignatureString()
を実行すると、声紋文字列が正しい形式で返されます。 この関数を 2 回実行して、下記の voiceSignatureStringUser1
および voiceSignatureStringUser2
変数への入力として使用する 2 つの文字列を作成します。
Note
声紋は、REST API を使用してのみ作成できます。
会議を文字起こしする
次のサンプル コードは、2 人の話者の会議をリアルタイムで文字起こしする方法を示しています。 上の手順に従って各話者の音声署名文字列が作成されていることを前提としています。 subscriptionKey
、region
、および文字起こしする音声のパス filepath
を、実際の情報に置き換えます。
事前登録されたユーザー プロファイルを使用しない場合、speaker1、speaker2 などとして不明なユーザーの最初の認識を完了するまでにさらに数秒かかります。
Note
署名の作成にアプリケーション全体で同じ subscriptionKey
が使用されていることを確認してください。そうでないと、エラーが発生します。
このサンプル コードは、次の処理を実行します。
- 文字起こしするサンプル
.wav
ファイルからAudioConfig
を作成します。 CreateMeetingAsync()
を使用してMeeting
を作成します。- コンストラクターを使用して
MeetingTranscriber
を作成し、必要なイベントにサブスクライブします。 - 会議に参加者を追加します。 上記の手順の関数
GetVoiceSignatureString()
の出力として、文字列voiceSignatureStringUser1
とvoiceSignatureStringUser2
が得られます。 - 会議に参加し、文字起こしを開始します。
- 音声サンプルを提供せずに話者を区別したい場合は、会議の文字起こしの概要に関するページにあるように、
DifferentiateGuestSpeakers
機能を有効にします。
注意
AudioStreamReader
は GitHub で取得できるヘルパー クラスです。
話者の識別または区別が有効になっている場合は、既に Transcribed
結果を受け取っている場合でも、サービスは蓄積されたオーディオ情報によってそれらを評価します。 サービスで、以前の結果に正しくない UserId
が割り当てられていることが検出された場合、ほぼ同じで UserId
と UtteranceId
のみが異なる Transcribed
結果が再び送信されます。 UtteranceId
の形式は {index}_{UserId}_{Offset}
であるため、Transcribed
結果を受け取ると、UtteranceId
を使用して、現在の Transcribed
結果が前の結果を修正するかどうかを判断できます。 クライアントまたは UI ロジックで、以前の出力の上書きなどの動作を決定したり、最新の結果を無視したりできます。
関数 TranscribeMeetingsAsync()
を呼び出して、会議の文字起こしを開始します。
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using Microsoft.CognitiveServices.Speech.Transcription;
class TranscribeMeeting
{
// all your other code
public static async Task TranscribeMeetingsAsync(string voiceSignatureStringUser1, string voiceSignatureStringUser2)
{
var subscriptionKey = "your-subscription-key";
var region = "your-region";
var filepath = "audio-file-to-transcribe.wav";
var config = SpeechConfig.FromSubscription(subscriptionKey, region);
config.SetProperty("ConversationTranscriptionInRoomAndOnline", "true");
// en-us by default. Adding this code to specify other languages, like zh-cn.
// config.SpeechRecognitionLanguage = "zh-cn";
var stopRecognition = new TaskCompletionSource<int>();
using (var audioInput = AudioConfig.FromWavFileInput(filepath))
{
var meetingID = Guid.NewGuid().ToString();
using (var meeting = await Meeting.CreateMeetingAsync(config, meetingID))
{
// create a meeting transcriber using audio stream input
using (var meetingTranscriber = new MeetingTranscriber(audioInput))
{
meetingTranscriber.Transcribing += (s, e) =>
{
Console.WriteLine($"TRANSCRIBING: Text={e.Result.Text} SpeakerId={e.Result.UserId}");
};
meetingTranscriber.Transcribed += (s, e) =>
{
if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
Console.WriteLine($"TRANSCRIBED: Text={e.Result.Text} SpeakerId={e.Result.UserId}");
}
else if (e.Result.Reason == ResultReason.NoMatch)
{
Console.WriteLine($"NOMATCH: Speech could not be recognized.");
}
};
meetingTranscriber.Canceled += (s, e) =>
{
Console.WriteLine($"CANCELED: Reason={e.Reason}");
if (e.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}");
Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
stopRecognition.TrySetResult(0);
}
};
meetingTranscriber.SessionStarted += (s, e) =>
{
Console.WriteLine($"\nSession started event. SessionId={e.SessionId}");
};
meetingTranscriber.SessionStopped += (s, e) =>
{
Console.WriteLine($"\nSession stopped event. SessionId={e.SessionId}");
Console.WriteLine("\nStop recognition.");
stopRecognition.TrySetResult(0);
};
// Add participants to the meeting.
var speaker1 = Participant.From("User1", "en-US", voiceSignatureStringUser1);
var speaker2 = Participant.From("User2", "en-US", voiceSignatureStringUser2);
await meeting.AddParticipantAsync(speaker1);
await meeting.AddParticipantAsync(speaker2);
// Join to the meeting and start transcribing
await meetingTranscriber.JoinMeetingAsync(meeting);
await meetingTranscriber.StartTranscribingAsync().ConfigureAwait(false);
// waits for completion, then stop transcription
Task.WaitAny(new[] { stopRecognition.Task });
await meetingTranscriber.StopTranscribingAsync().ConfigureAwait(false);
}
}
}
}
}
前提条件
- Azure サブスクリプション。 無料で作成できます。
- Azure ポータルで、音声リソースを作成します。
- Speech リソース キーとリージョンを取得します。 音声リソースがデプロイされたら、[リソースに移動] を選択して、キーを表示および管理します。
環境をセットアップする
何らかの操作を行う前に、Speech SDK for Python をインストールしてください。 pip install azure-cognitiveservices-speech
を実行することで、PyPI から Speech SDK をインストールできます。
声紋を作成する
ユーザー プロファイルを登録する場合は、最初の手順で会議の参加者の声紋を作成して、一意の話者として識別できるようにします。 特定の参加者を識別するために、事前に登録したユーザー プロファイルを使用しない場合、これは必須ではありません。
声紋を作成するための入力 .wav
音声ファイルは、16 ビット、16 kHz のサンプル レート、およびシングル チャンネル (モノラル) 形式である必要があります。 各オーディオ サンプルの推奨される長さは、30 秒から 2 分です。 オーディオ サンプルが短すぎると、話者を認識するときの精度が低下します。 一意の音声プロファイルを作成するため、.wav
ファイルは 1 人の音声のサンプルである必要があります。
次の例は、Python で REST API を使用して声紋を作成する方法を示しています。 subscriptionKey
、region
、サンプル .wav
ファイルへのパスを挿入する必要があります。
import requests
from scipy.io.wavfile import read
import json
speech_key, service_region = "your-subscription-key", "your-region"
endpoint = f"https://signature.{service_region}.cts.speech.microsoft.com/api/v1/Signature/GenerateVoiceSignatureFromByteArray"
#Enrollment audio for each speaker. In this example, two speaker enrollment audio files are added.
enrollment_audio_speaker1 = "enrollment-audio-speaker1.wav"
enrollment_audio_speaker2 = "enrollment-audio-speaker2.wav"
def voice_data_converter(enrollment_audio):
with open(enrollment_audio, "rb") as wav_file:
input_wav = wav_file.read()
return input_wav
def voice_signature_creator(endpoint, speech_key, enrollment_audio):
data = voice_data_converter(enrollment_audio)
headers = {"Ocp-Apim-Subscription-Key":speech_key}
r = requests.post(url = endpoint,headers = headers, data = data)
voice_signature_string = json.dumps(r.json()['Signature'])
return voice_signature_string
voice_signature_user1 = voice_signature_creator(endpoint, speech_key, enrollment_audio_speaker1)
voice_signature_user2 = voice_signature_creator(endpoint, speech_key, enrollment_audio_speaker2)
これら 2 つの voice_signature_string をサンプル コードで後で変数 voice_signature_user1
と voice_signature_user2
への入力として使用できます。
Note
声紋は、REST API を使用してのみ作成できます。
会議を文字起こしする
次のサンプル コードは、2 人の話者の会議をリアルタイムで文字起こしする方法を示しています。 前の手順に従って各話者の音声署名文字列が作成されていることを前提としています。 subscriptionKey
、region
、および文字起こしする音声のパス filepath
を、実際の情報に置き換えます。
事前登録されたユーザー プロファイルを使用しない場合、speaker1、speaker2 などとして不明なユーザーの最初の認識を完了するまでにさらに数秒かかります。
Note
署名の作成にアプリケーション全体で同じ subscriptionKey
が使用されていることを確認してください。そうでないと、エラーが発生します。
サンプルは次のことを実行します。
- サブスクリプション情報を使用して Speech 構成を作成します。
- プッシュ ストリームを使用してオーディオ構成を作成します。
MeetingTranscriber
を作成し、会議の文字起こしによって発生したイベントをサブスクライブします。- 会議を作成するための会議識別子。
- 会議に参加者を追加します。 前の手順の出力として、文字列
voiceSignatureStringUser1
とvoiceSignatureStringUser2
が得られます。 - wave ファイル全体を一度に読み取り、SDK にストリーミングして文字起こしを開始します。
- 音声サンプルを提供せずに話者を区別したい場合は、会議の文字起こしの概要に関するページにあるように、
DifferentiateGuestSpeakers
機能を有効にします。
話者の識別または区別が有効になっている場合は、transcribed
の結果を受け取っている場合でも、サービスは蓄積されたオーディオ情報によってそれらを評価します。 サービスで、以前の結果に正しくない speakerId
が割り当てられていることが検出された場合、ほぼ同じで speakerId
と UtteranceId
のみが異なる Transcribed
結果が再び送信されます。 UtteranceId
の形式は {index}_{speakerId}_{Offset}
であるため、transcribed
結果を受け取ると、UtteranceId
を使用して、現在の transcribed
結果が前の結果を修正するかどうかを判断できます。 クライアントまたは UI ロジックで、以前の出力の上書きなどの動作を決定したり、最新の結果を無視したりできます。
import azure.cognitiveservices.speech as speechsdk
import time
import uuid
from scipy.io import wavfile
speech_key, service_region="your-subscription-key","your-region"
meetingfilename= "audio-file-to-transcribe.wav" # 8 channel, 16 bits, 16kHz audio
def meeting_transcription():
speech_config = speechsdk.SpeechConfig(subscription=speech_key, region=service_region)
speech_config.set_property_by_name("ConversationTranscriptionInRoomAndOnline", "true")
# If you want to differentiate speakers without providing voice samples, uncomment the following line.
# speech_config.set_property_by_name("DifferentiateGuestSpeakers", "true")
channels = 8
bits_per_sample = 16
samples_per_second = 16000
wave_format = speechsdk.audio.AudioStreamFormat(samples_per_second, bits_per_sample, channels)
stream = speechsdk.audio.PushAudioInputStream(stream_format=wave_format)
audio_config = speechsdk.audio.AudioConfig(stream=stream)
transcriber = speechsdk.transcription.MeetingTranscriber(audio_config)
meeting_id = str(uuid.uuid4())
meeting = speechsdk.transcription.Meeting(speech_config, meeting_id)
done = False
def stop_cb(evt: speechsdk.SessionEventArgs):
"""callback that signals to stop continuous transcription upon receiving an event `evt`"""
print('CLOSING {}'.format(evt))
nonlocal done
done = True
transcriber.transcribed.connect(lambda evt: print('TRANSCRIBED: {}'.format(evt)))
transcriber.session_started.connect(lambda evt: print('SESSION STARTED: {}'.format(evt)))
transcriber.session_stopped.connect(lambda evt: print('SESSION STOPPED {}'.format(evt)))
transcriber.canceled.connect(lambda evt: print('CANCELED {}'.format(evt)))
# stop continuous transcription on either session stopped or canceled events
transcriber.session_stopped.connect(stop_cb)
transcriber.canceled.connect(stop_cb)
# Note user voice signatures are not required for speaker differentiation.
# Use voice signatures when adding participants when more enhanced speaker identification is required.
user1 = speechsdk.transcription.Participant("user1@example.com", "en-us", voice_signature_user1)
user2 = speechsdk.transcription.Participant("user2@example.com", "en-us", voice_signature_user2)
meeting.add_participant_async(user1).get()
meeting.add_participant_async(user2).get()
transcriber.join_meeting_async(meeting).get()
transcriber.start_transcribing_async()
sample_rate, wav_data = wavfile.read(meetingfilename)
stream.write(wav_data.tobytes())
stream.close()
while not done:
time.sleep(.5)
transcriber.stop_transcribing_async()