你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

为 Teams 互操作性启用隐藏式字幕

了解如何允许用户在 Teams 互操作性应用场景中启用隐藏式字幕,在这些应用场景中,用户可能正在参加 Azure 通信服务用户与 Teams 客户端用户之间的会议,或者用户正在通过其 Microsoft 365 表示使用 Azure 通信服务调用 SDK。

先决条件

注意

请注意,你需要具有使用 Azure 通信服务通话 SDK 进行语音通话的应用,以访问本指南中所述的隐藏式字幕功能。

模型

名称 说明
CaptionsCallFeature 用于字幕调用功能的 API
TeamsCaptions 适用于 Teams 字幕的 API
StartCaptionOptions 隐藏式字幕选项,如口语
TeamsCaptionsReceivedEventArgs 为每个 Teams 字幕接收事件接收的数据对象

获取隐藏式字幕功能

外部标识用户和 Microsoft 365 用户

如果要构建允许 Azure 通信服务用户加入 Teams 会议的应用程序

CaptionsCallFeature captionsCallFeature = call.Features.Captions;
CallCaptions callCaptions = await captionsCallFeature.GetCaptionsAsync();
if (callCaptions.CaptionsKind == CaptionsKind.TeamsCaptions)
{
    TeamsCaptions teamsCaptions = callCaptions as TeamsCaptions;
} 

订阅侦听器

添加侦听器以接收已启用/禁用字幕状态

teamsCaptions.CaptionsEnabledChanged += OnIsCaptionsEnabledChanged;

private void OnIsCaptionsEnabledChanged(object sender, PropertyChangedEventArgs args)
{
    if (teamsCaptions.IsEnabled)
    {
    }
}

为收到的字幕数据添加侦听器

teamsCaptions.CaptionsReceived += OnCaptionsReceived;

private void OnCaptionsReceived(object sender, TeamsCaptionsReceivedEventArgs eventArgs)
{
    // Information about the speaker.
    // eventArgs.Speaker
    // The original text with no transcribed.
    // eventArgs.SpokenText
    // language identifier for the captions text.
    // eventArgs.CaptionLanguage
    // language identifier for the speaker.
    // eventArgs.SpokenLanguage
    // The transcribed text.
    // eventArgs.CaptionText
    // Timestamp denoting the time when the corresponding speech was made.
    // eventArgs.Timestamp
    // CaptionsResultKind is Partial if text contains partially spoken sentence.
    // It is set to Final once the sentence has been completely transcribed.
    // eventArgs.ResultKind
}

添加侦听器以接收主动口语更改状态

teamsCaptions.ActiveSpokenLanguageChanged += OnIsActiveSpokenLanguageChanged;

private void OnIsActiveSpokenLanguageChanged(object sender, PropertyChangedEventArgs args)
{
    // teamsCaptions.ActiveSpokenLanguage
}

添加侦听器以接收活动字幕语言更改状态

teamsCaptions.ActiveCaptionLanguageChanged += OnIsActiveCaptionLanguageChanged;

private void OnIsActiveCaptionLanguageChanged(object sender, PropertyChangedEventArgs args)
{
    // teamsCaptions.ActiveCaptionLanguage
}

开始字幕

设置所有侦听器后,现在可以开始添加字幕。


private async void StartCaptions()
{
    var options = new StartCaptionsOptions
    {
        SpokenLanguage = "en-us"
    };
    try
    {
        await teamsCaptions.StartCaptionsAsync(options);
    }
    catch (Exception ex)
    {
    }
}

停止字幕

private async void StopCaptions()
{
    try
    {
        await teamsCaptions.StopCaptionsAsync();
    }
    catch (Exception ex)
    {
    }
}

移除字幕接收侦听器

teamsCaptions.CaptionsReceived -= OnCaptionsReceived;

口语支持

获取支持的口语列表

获取启用隐藏式字幕时用户可以选择的受支持口语的列表。

// bcp 47 formatted language code
IReadOnlyList<string> sLanguages = teamsCaptions.SupportedSpokenLanguages;```

### Set spoken language 
When the user selects the spoken language, your app can set the spoken language that it expects captions to be generated from. 

``` cs 
public async void SetSpokenLanguage()
{
    try
    {
        await teamsCaptions.SetSpokenLanguageAsync("en-us");
    }
    catch (Exception ex)
    {
    }
}

字幕语言支持

获取支持的字幕语言

如果组织具有有效的 Teams 高级版许可证,则只要会议的组织者具有 Teams 高级版许可证,Azure 通信服务用户就可以启用翻译的字幕。 对于具有 Microsoft 365 标识的用户,如果会议组织者没有 Teams 高级版许可证,则根据其自己的用户帐户进行此检查。

// ISO 639-1 formatted language code
IReadOnlyList<string> cLanguages = teamsCaptions.SupportedCaptionLanguages;

设置字幕语言

public async void SetCaptionLanguage()
{
    try
    {
        await teamsCaptions.SetCaptionLanguageAsync("en");
    }
    catch (Exception ex)
    {
    }
}

先决条件

注意

请注意,你需要具有使用 Azure 通信服务通话 SDK 进行语音通话的应用,以访问本指南中所述的隐藏式字幕功能。

模型

名称 说明
CaptionsCallFeature 字幕的 API
CaptionsCommon 字幕的基类
StartCaptionOptions 隐藏式字幕选项,如口语
TeamsCaptionHandler 用于处理 CaptionsReceivedEventType 事件的回叫定义
TeamsCaptionsInfo 为每个 CaptionsReceivedEventType 事件接收的数据结构

获取隐藏式字幕功能

外部标识用户

如果要构建允许 Azure 通信服务用户加入 Teams 会议的应用程序。

let captionsCallFeature: SDK.CaptionsCallFeature = call.feature(SDK.Features.Captions);

Microsoft 365 用户

let captionsCallFeature: SDK.CaptionsCallFeature = teamsCall.feature(SDK.Features.Captions);

获取 Teams 字幕对象

需要获取并强制转换 Teams Captions 对象以利用 Teams Captions 特定功能

let teamsCaptions: SDK.TeamsCaptions;
if (captionsCallFeature.captions.kind === 'TeamsCaptions') {
    teamsCaptions = captionsCallFeature.captions as SDK.TeamsCaptions;
}

订阅侦听器

添加侦听器以接收字幕活动/非活动状态

const captionsActiveChangedHandler = () => {
    if (teamsCaptions.isCaptionsFeatureActive) {
        /* USER CODE HERE - E.G. RENDER TO DOM */
    }
}
teamsCaptions.on('CaptionsActiveChanged', captionsActiveChangedHandler);

为收到的字幕数据添加侦听器

处理返回的 TeamsCaptionsInfo 数据对象。

注意:该对象包含一个 resultType 属性,用于指示数据是部分字幕还是最终版本的字幕。 ResultType partial 指示未经编辑的实时字幕,而 final 指示句子的最终解释版本(即包括标点和大写)。

let currentCaptionLanguage : string;
const captionsReceivedHandler : TeamsCaptionsHandler = (data: TeamsCaptionsInfo) => { 
    /** USER CODE HERE - E.G. RENDER TO DOM 
     * data.captionLanguage
     * data.captionText
     * data.resultType
     * data.speaker
     * data.spokenText
     * data.timeStamp
    */
   // Example code:
   // Create a dom element, i.e. div, with id "captionArea" before proceeding with the sample code
    if (!this._currentCaptionLanguage || this._currentCaptionLanguage === data.captionLanguage) {
        let mri: string;
        switch (data.speaker.identifier.kind) {
            case 'communicationUser': { mri = data.speaker.identifier.communicationUserId; break; }
            case 'microsoftTeamsUser': { mri = data.speaker.identifier.microsoftTeamsUserId; break; }
            case 'phoneNumber': { mri = data.speaker.identifier.phoneNumber; break; }
        }
        const outgoingCaption = `prefix${mri.replace(/:/g, '').replace(/-/g, '')}`;

        let captionArea = document.getElementById("captionArea");
        const captionText = `${data.timestamp.toUTCString()}
            ${data.speaker.displayName}: ${data.captionText ?? data.spokenText}`;

        let foundCaptionContainer = captionArea.querySelector(`.${outgoingCaption}[isNotFinal='true']`);
        if (!foundCaptionContainer) {
            let captionContainer = document.createElement('div');
            captionContainer.setAttribute('isNotFinal', 'true');
            captionContainer.style['borderBottom'] = '1px solid';
            captionContainer.style['whiteSpace'] = 'pre-line';
            captionContainer.textContent = captionText;
            captionContainer.classList.add(newClassName);

            captionArea.appendChild(captionContainer);
        } else {
            foundCaptionContainer.textContent = captionText;

            if (captionData.resultType === 'Final') {
                foundCaptionContainer.setAttribute('isNotFinal', 'false');
            }
        }
    }
}; 
teamsCaptions.on('CaptionsReceived', captionsReceivedHandler); 

添加侦听器以接收口语更改后的状态

const spokenLanguageChangedHandler = () => {
    if (teamsCaptions.activeSpokenLanguage !== currentSpokenLanguage) {
        /* USER CODE HERE - E.G. RENDER TO DOM */
    }
}
teamsCaptions.on('SpokenLanguageChanged', spokenLanguageChangedHandler)

添加侦听器以接收字幕语言更改状态

const captionLanguageChangedHandler = () => {
    if (teamsCaptions.activeCaptionLanguage !== currentCaptionLanguage) {
        /* USER CODE HERE - E.G. RENDER TO DOM */
    }
}
teamsCaptions.on('CaptionLanguageChanged', captionLanguageChangedHandler)

开始字幕

设置所有侦听器后,现在可以开始添加字幕。

try {
    await teamsCaptions.startCaptions({ spokenLanguage: 'en-us' });
} catch (e) {
    /* USER ERROR HANDLING CODE HERE */
}

停止字幕

try {
    teamsCaptions.stopCaptions(); 
} catch (e) {
    /* USER ERROR HANDLING CODE HERE */
}

取消订阅侦听器

teamsCaptions.off('CaptionsActiveChanged', captionsActiveChangedHandler);
teamsCaptions.off('CaptionsReceived', captionsReceivedHandler); 

口语支持

获取支持的口语列表

获取启用隐藏式字幕时用户可以选择的受支持口语的列表。 该属性以 bcp 47 格式返回语言数组。

const spokenLanguages = teamsCaptions.supportedSpokenLanguages; 

设置口语

从支持的口语数组传入一个值,确保支持所请求的语言。 默认情况下,如果 contoso 未提供任何语言或提供的语言不受支持,则口语默认为“en-us”。

// bcp 47 formatted language code
const language = 'en-us'; 

// Altneratively, pass a value from the supported spoken languages array
const language = spokenLanguages[0]; 

try {
    teamsCaptions.setSpokenLanguage(language);
} catch (e) {
    /* USER ERROR HANDLING CODE HERE */
}

字幕语言支持

获取支持的字幕语言列表

如果组织具有有效的 Teams 高级版许可证,则可以允许用户使用 Teams 字幕提供的翻译字幕。 对于具有 Microsoft 365 标识的用户,如果会议组织者没有有效的 Teams 高级版许可证,则针对 Microsoft 365 用户帐户执行字幕语言检查。

该属性以 ISO 639-1 标准返回一组双字母语言代码。

const captionLanguages = teamsCaptions.supportedCaptionLanguages;

设置字幕语言

// ISO 639-1 formatted language code
const language = 'en'; 

// Altneratively, pass a value from the supported caption languages array
const language = captionLanguages[0];
try {
    teamsCaptions.setCaptionLanguage(language);
} catch (e) {
    /* USER ERROR HANDLING CODE HERE */
}

先决条件

注意

请注意,你需要具有使用 Azure 通信服务通话 SDK 进行语音通话的应用,以访问本指南中所述的隐藏式字幕功能。

模型

名称 说明
CaptionsCallFeature 用于字幕调用功能的 API
TeamsCaptions 适用于 Teams 字幕的 API
StartCaptionOptions 隐藏式字幕选项,如口语
TeamsCaptionsListener TeamsCaptions addOnCaptionsReceivedListener 的侦听器
TeamsCaptionsReceivedEvent 为每个 TeamsCaptionsListener 事件接收的数据对象

获取隐藏式字幕功能

外部标识用户和 Microsoft 365 用户

如果要生成允许用户加入 Teams 会议的应用程序

CaptionsCallFeature captionsCallFeature = call.feature(Features.CAPTIONS);
captionsCallFeature.getCaptions().whenComplete(
    ((captions, throwable) -> {
        if (throwable == null) {
            CallCaptions callCaptions = captions;
            if (captions.getCaptionsType() == CaptionsType.TEAMS_CAPTIONS) {
            // teams captions
            TeamsCaptions teamsCaptions = (TeamsCaptions) captions;
            }
        } else {
        // get captions failed
        // throwable is the exception/cause
        }
    }));

订阅侦听器

添加侦听器以接收已启用/禁用字幕状态

public void addOnIsCaptionsEnabledChangedListener() {
    teamsCaptions.addOnCaptionsEnabledChangedListener( (PropertyChangedEvent args) -> {
        if(teamsCaptions.isEnabled()) {
            // captions enabled
        }
    });
}

为收到的字幕数据添加侦听器

TeamsCaptionsListener captionsListener = (TeamsCaptionsReceivedEvent args) -> {
  // Information about the speaker.
  // CallerInfo participantInfo = args.getSpeaker();
  // The original text with no transcribed.
  // args.getSpokenText();
  // language identifier for the captions text.
  // args.getCaptionLanguage();
  // language identifier for the speaker.
  // args.getSpokenLanguage();
  // The transcribed text.
  // args.getCaptionText();
  // Timestamp denoting the time when the corresponding speech was made.
  // args.getTimestamp();
  // CaptionsResultType is Partial if text contains partially spoken sentence.
  // It is set to Final once the sentence has been completely transcribed.
  // args.getResultType() == CaptionsResultType.FINAL;
}; 
public void addOnCaptionsReceivedListener() {
  teamsCaptions.addOnCaptionsReceivedListener(captionsListener); 
}

添加侦听器以接收主动口语更改状态

public void addOnActiveSpokenLanguageChangedListener() {
    teamsCaptions.addOnActiveSpokenLanguageChangedListener( (PropertyChangedEvent args) -> {
       // teamsCaptions.getActiveSpokenLanguage()
    });
}

添加侦听器以接收活动字幕语言更改状态

public void addOnActiveCaptionLanguageChangedListener() {
    teamsCaptions.addOnActiveCaptionLanguageChangedListener( (PropertyChangedEvent args) -> {
       // teamsCaptions.getActiveCaptionLanguage()
    });
}

开始字幕

设置所有侦听器后,现在可以开始添加字幕。

public void startCaptions() {
    StartCaptionsOptions startCaptionsOptions = new StartCaptionsOptions();
    startCaptionsOptions.setSpokenLanguage("en-us");
    teamsCaptions.startCaptions(startCaptionsOptions).whenComplete((result, error) -> {
        if (error != null) {
        }
    });
}

停止字幕

public void stopCaptions() {
    teamsCaptions.stopCaptions().whenComplete((result, error) -> {
        if (error != null) {
        }
    });
}

移除字幕接收侦听器

public void removeOnCaptionsReceivedListener() {
    teamsCaptions.removeOnCaptionsReceivedListener(captionsListener);
}

口语支持

获取支持的口语列表

获取启用隐藏式字幕时用户可以选择的受支持口语的列表。

// bcp 47 formatted language code
teamsCaptions.getSupportedSpokenLanguages();

设置口语

当用户选择口语时,你的应用可以设置它期望用于生成字幕的口语。

public void setSpokenLanguage() {
    teamsCaptions.setSpokenLanguage("en-us").whenComplete((result, error) -> {
        if (error != null) {
        }
    });
}

字幕语言支持

获取支持的字幕语言

如果组织具有有效的 Teams 高级版许可证,则只要会议的组织者具有 Teams 高级版许可证,Azure 通信服务用户就可以启用翻译的字幕。 对于具有 Microsoft 365 标识的用户,如果会议组织者没有 Teams 高级版许可证,则根据其自己的用户帐户进行此检查。

// ISO 639-1 formatted language code
teamsCaptions.getSupportedCaptionLanguages();

设置字幕语言

public void setCaptionLanguage() {
    teamsCaptions.setCaptionLanguage("en").whenComplete((result, error) -> {
        if (error != null) {
        }
    });
}

先决条件

注意

请注意,你需要具有使用 Azure 通信服务通话 SDK 进行语音通话的应用,以访问本指南中所述的隐藏式字幕功能。

模型

名称 说明
CaptionsCallFeature 用于字幕调用功能的 API
TeamsCaptions 适用于 Teams 字幕的 API
StartCaptionOptions 隐藏式字幕选项,如口语
TeamsCaptionsDelegate Teams 字幕的代理
TeamsCaptionsReceivedEventArgs 为每个 Teams 字幕接收事件接收的数据对象

获取隐藏式字幕功能

外部标识用户和 Microsoft 365 用户

如果要构建允许 Azure 通信服务用户加入 Teams 会议的应用程序

if let call = self.call {
    @State var captionsCallFeature = call.feature(Features.captions)
    captionsCallFeature.getCaptions{(value, error) in
        if let error = error {
            // failed to get captions
        } else {
            if (value?.type == CaptionsType.teamsCaptions) {
                // teams captions
                @State var teamsCaptions = value as? TeamsCaptions
            }
        }
    }
}

订阅侦听器

添加侦听器以接收已启用/禁用的字幕、口语、更改的字幕语言状态和接收的数据

extension CallObserver: TeamsCaptionsDelegate {
    // listener for receive captions enabled/disabled status
    public func teamsCaptions(_ teamsCaptions: TeamsCaptions, didChangeCaptionsEnabledState args: PropertyChangedEventArgs) {
        // teamsCaptions.isEnabled
    }
    
    // listener for active spoken language state change
    public func teamsCaptions(_ teamsCaptions: TeamsCaptions, didChangeActiveSpokenLanguageState args: PropertyChangedEventArgs) {
        // teamsCaptions.activeSpokenLanguage
    }
    
    // listener for active caption language state change
    public func teamsCaptions(_ teamsCaptions: TeamsCaptions, didChangeActiveCaptionLanguageState args: PropertyChangedEventArgs) {
        // teamsCaptions.activeCaptionLanguage
    }
    
    // listener for captions data received
    public func teamsCaptions(_ teamsCaptions: TeamsCaptions, didReceiveCaptions:TeamsCaptionsReceivedEventArgs) {
            // Information about the speaker.
            // didReceiveCaptions.speaker
            // The original text with no transcribed.
            // didReceiveCaptions.spokenText
            // language identifier for the captions text.
            // didReceiveCaptions.captionLanguage
            // language identifier for the speaker.
            // didReceiveCaptions.spokenLanguage
            // The transcribed text.
            // didReceiveCaptions.captionText
            // Timestamp denoting the time when the corresponding speech was made.
            // didReceiveCaptions.timestamp
            // CaptionsResultType is Partial if text contains partially spoken sentence.
            // It is set to Final once the sentence has been completely transcribed.
            // didReceiveCaptions.resultType
    }
}

teamsCaptions.delegate = self.callObserver

开始字幕

设置所有侦听器后,现在可以开始添加字幕。

func startCaptions() {
    guard let teamsCaptions = teamsCaptions else {
        return
    }
    let startCaptionsOptions = StartCaptionsOptions()
    startCaptionsOptions.spokenLanguage = "en-us"
    teamsCaptions.startCaptions(startCaptionsOptions: startCaptionsOptions, completionHandler: { (error) in
        if error != nil {
            
        }
    })
}

停止字幕

func stopCaptions() {
    teamsCaptions.stopCaptions(completionHandler: { (error) in
        if error != nil {
            
        }
    })
}

移除字幕接收侦听器

teamsCaptions?.delegate = nil

口语支持

获取支持的口语列表

获取启用隐藏式字幕时用户可以选择的受支持口语的列表。

// bcp 47 formatted language code
let spokenLanguage : String = "en-us"
for language in teamsCaptions?.supportedSpokenLanguages ?? [] {
    // choose required language
    spokenLanguage = language
}

设置口语

当用户选择口语时,你的应用可以设置它期望用于生成字幕的口语。

func setSpokenLanguage() {
    guard let teamsCaptions = self.teamsCaptions else {
        return
    }

    teamsCaptions.set(spokenLanguage: spokenLanguage, completionHandler: { (error) in
        if let error = error {
        }
    })
}

字幕语言支持

获取支持的字幕语言

如果组织具有有效的 Teams 高级版许可证,则只要会议的组织者具有 Teams 高级版许可证,Azure 通信服务用户就可以启用翻译的字幕。 对于具有 Microsoft 365 标识的用户,如果会议组织者没有 Teams 高级版许可证,则根据其自己的用户帐户进行此检查。

// ISO 639-1 formatted language code
let captionLanguage : String = "en"
for language in teamsCaptions?.supportedCaptionLanguages ?? [] {
    // choose required language
    captionLanguage = language
}

设置字幕语言

func setCaptionLanguage() {
    guard let teamsCaptions = self.teamsCaptions else {
        return
    }

    teamsCaptions.set(captionLanguage: captionLanguage, completionHandler: { (error) in
        if let error = error {
        }
    })
}

清理资源

如果想要清理并删除通信服务订阅,可以删除资源或资源组。 删除资源组同时也会删除与之相关联的任何其他资源。 参阅此处了解清理资源的更多详细信息。

后续步骤

有关详细信息,请参阅以下文章: