Project Icon

amazon-chime-sdk-ios

助力iOS应用集成音视频通话与屏幕共享

Amazon Chime SDK for iOS是一款用于iOS应用开发的音视频通信工具包。它基于Amazon Chime服务基础设施,提供API用于配置会议、管理设备和处理媒体事件。该SDK支持音频通话、视频通话和屏幕共享功能,还包括自定义视频源和背景虚化等高级特性。开发者可通过CocoaPods或SPM将其集成到项目中,快速实现高质量的实时通信功能。

Amazon Chime iOS SDK

Amazon Chime SDK 项目看板

注意:如果使用SDK源代码构建,development分支包含最新的更改,可能无法与公开可用的Chime媒体库一起构建,或者可能不如公开发布版本稳定。

使用Amazon Chime构建视频通话、音频通话和屏幕共享应用程序。

Amazon Chime iOS SDK可以轻松地将协作式音频通话、视频通话和屏幕共享查看功能添加到iOS应用程序中,它使用与Amazon Chime服务上的会议相同的基础设施服务。

这个Amazon Chime iOS SDK通过连接到您在AWS账户中创建的会议会话资源来工作。SDK包含在iOS应用程序中构建自定义通话和协作体验所需的一切,包括以下方法:配置会议会话、列出和选择音频设备、切换视频设备、开始和停止屏幕共享查看、在发生媒体事件(如音量变化)时接收回调,以及管理会议功能,如音频静音和视频图块绑定。

我们还有一个Amazon Chime SDK项目看板,您可以在那里找到社区请求及其状态。

要开始使用,请参阅以下资源:

并查看以下指南:

在您的项目中包含Amazon Chime SDK

您可以通过SPM、CocoaPods或GitHub发布的二进制文件将Amazon Chime SDK集成到您的项目中。

为了设置,您项目的根文件夹(可以找到.xcodeproj文件的地方)将被称为root

通过CocoaPods

  1. Amazon Chime SDK可通过CocoaPods获得。如果您尚未安装CocoaPods,请运行以下命令安装CocoaPods:

    $ gem install cocoapods
    $ pod setup
    

    根据您的系统设置,您可能需要使用sudo来安装cocoapods,如下所示:

    $ sudo gem install cocoapods
    $ pod setup
    
  2. 在根目录(*.xcodeproj文件所在的目录)中,运行以下命令在项目中创建Podfile:

    $ pod init
    
  3. 编辑Podfile以将AmazonChimeSDK包含到您的项目中:

    target 'YourTarget' do
        pod 'AmazonChimeSDK'
        ...
    end
    

    如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用AmazonChimeSDKNoVideoCodecs来减少大小:

    target 'YourTarget' do
        pod 'AmazonChimeSDKNoVideoCodecs'
        ...
    end
    
  4. (可选)如果您想使用背景模糊和替换功能,请添加:

    target 'YourTarget' do
      pod 'AmazonChimeSDKMachineLearning'
      ...
    end
    
  5. 然后运行以下命令安装pods:

    $ pod install --repo-update
    
  6. 要打开您的项目,请使用XCode打开根目录中新生成的*.xcworkspace文件。您可以通过在项目文件夹中发出以下命令来执行此操作

     $ xed .
    

    注意:请不要使用*.xcodeproj打开项目。

  7. 如果您正在使用背景模糊和替换功能,在Build Settings选项卡下,在Linking部分,将-framework AmazonChimeSDKMachineLearning添加到Other Linker Flags中。

image

通过SPM

Amazon Chime SDK可通过SPM获得。如果您不需要视频和内容共享功能,或软件视频编解码器支持,您可以选择使用无视频编解码器SPM

  1. 在Xcode中打开您的项目

  2. 转到File > Swift Packages > Add Package Dependency...

  3. Enter package repository URL字段中,输入"https://github.com/aws/amazon-chime-sdk-ios-spm"。要使用无视频编解码器媒体模块,请输入"https://github.com/aws/amazon-chime-sdk-ios-no-video-codecs-spm"。

  4. 输入最新版本(例如0.23.1)并点击Next

  5. 为您的项目选择软件包,然后点击FinishAmazonChimeSDKAmazonChimeSDKMedia是必需的。如果您想使用背景模糊和背景替换,请选中AmazonChimeSDKMachineLearning

从GitHub发布的二进制文件

1. 下载二进制文件

  • 从最新的发布版本下载AmazonChimeSDKAmazonChimeSDKMedia二进制文件。
    • 如果您想使用背景模糊和背景替换功能,还需下载AmazonChimeSDKMachineLearning二进制文件。否则,您可以忽略以下说明中所有关于AmazonChimeSDKMachineLearning的引用。
    • 如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用AmazonChimeSDKMediaNoVideoCodecs二进制文件代替AmazonChimeSDKMedia,并在以下说明中将所有对AmazonChimeSDKMedia的引用视为AmazonChimeSDKMediaNoVideoCodecs

注意:我们不支持混合使用来自不同发布版本的二进制文件。

  • 解压缩并将.framework.xcframework复制到root,具体取决于您的项目使用哪种框架。对于Xcode12.3及更高版本,如果遇到编译问题,请使用.xcframework.xcframework在Amazon Chime SDK iOS v0.15.0之后可用。

2. 更新项目文件

  • 在Xcode中打开您的.xcodeproj文件,并点击您的构建目标。

  • Build Settings选项卡下,

    • $(PROJECT_DIR)添加到Framework Search Path

    • @executable_path/Frameworks添加到Runpath Search Paths

    • Linking部分,将以下两个标志添加到Other Linker Flags中:

      • -lc++
      • -ObjC

image

  • General选项卡下,查找Frameworks, Libraries, and Embedded Content部分。点击+,然后Add Others,再点击Add Files

    • 如果您使用传统的.framework,请指定步骤1中AmazonChimeSDK.frameworkAmazonChimeSDKMedia.frameworkAmazonChimeSDKMachineLearning.framework的位置。如果在使用传统的.framework时遇到编译错误(在Xcode 12.3及更高版本中可能发生),请使用.xcframework,它在Amazon Chime SDK iOS v0.15.0之后可用。
    • 如果您使用.xcframework,请指定步骤1中AmazonChimeSDK.xcframeworkAmazonChimeSDKMedia.xcframeworkAmazonChimeSDKMachineLearning.xcframework的位置。
    • 对于AmazonChimeSDK.frameworkAmazonChimeSDKMedia.framework框架,确认在Embed选项下选择了Embed & Sign。对于AmazonChimeSDKMachineLearning.framework,选择Do Not Embed

image

运行演示应用

要运行演示应用程序,请按照以下步骤操作。

1. 克隆Git仓库

git clone git@github.com:aws/amazon-chime-sdk-ios.git

2. 导入Amazon Chime SDK

通过CocoaPods

对于/AmazonChimeSDKDemo/Podfile中的两个目标,将AMAZON_CHIME_SDK_VERSION替换为特定的SDK版本,例如0.19.3,或者如果使用最新版本的Amazon Chime SDK,则将其删除。

/AmazonChimeSDKDemo下,运行以下命令安装pods:

$ pod install --repo-update

或从下载的二进制文件

  • 从最新的发布版本下载AmazonChimeSDKMediaAmazonChimeSDKMachineLearning二进制文件。

  • 解压缩并将AmazonChimeSDKMedia.xcframework复制到amazon-chime-sdk-ios/AmazonChimeSDK文件夹,将AmazonChimeSDKMachineLearning.xcframework复制到amazon-chime-sdk-ios/AmazonChimeSDKDemo文件夹。

3. 部署无服务器演示

amazon-chime-sdk-js 部署无服务器演示

4. 更新 AmazonChimeSDKDemo 项目文件

  • AmazonChimeDemoSDKBroadcast.appex 是 AmazonChimeSDKDemo 用于设备级屏幕共享的广播扩展,请确认在 Embed 选项下选择了 Embed without Signing。如果您不想测试这项功能,可以将其从 Frameworks, Libraries, and Embedded Content 部分移除。

image

  • 对于每个目标,在 Signing & Capabilities 标签下,

    • Signing 部分,使用您自己的 Apple 开发者团队和 Bundle 标识符。
    • (可选)App Groups 部分,如果您想测试共享设备级屏幕捕获,请选择您自己的应用组。详情请参阅 内容共享

image image

5. 更新演示应用

  • 更新服务器 URL 和区域:

    • 对于 Swift 演示,在 AppConfiguration.swift 中更新无服务器演示的服务器 URL 和区域。
    • 对于 ObjC 演示,在 ViewControllerObjC.h 中更新无服务器演示的服务器 URL 和区域。
  • (可选) 如果您想测试共享设备级屏幕捕获,请在 AppConfiguration.swiftSampleHandler.swift 中同时更新 broadcastBundleIdappGroupId,使用广播上传扩展包 ID 和 App Group ID。详情请参阅 内容共享

6. 使用演示应用加入会议

使用 CocoaPods 中的 Amazon Chime SDK 运行 AmazonChimeSDKDemoPods 目标

使用 XCode 打开 AmazonChimeSDKDemo/ 中的 AmazonChimeSDKDemo.xcworkspace 文件,从 Xcode IDE 顶部栏的方案下拉列表中选择 AmazonChimeSDKDemoPods,选择构建设备并点击运行按钮。

使用下载的 Amazon Chime SDK 二进制文件运行 AmazonChimeSDKDemo 目标

使用 XCode 打开 AmazonChimeSDKDemo/ 中的 AmazonChimeSDKDemo.xcworkspace 文件,从 Xcode IDE 顶部栏的方案下拉列表中选择 AmazonChimeSDKDemo,选择构建设备并点击运行按钮。

在加入界面上,选择不使用 CallKit 加入会议或通过 CallKit 拨入/拨出电话加入。由于演示应用没有推送通知,它会将通过拨入电话加入的时间延迟 10 秒,以给用户足够的时间将应用置于后台或锁定屏幕来模拟行为。

报告可疑漏洞

如果您在此项目中发现潜在的安全问题,我们请您通过我们的漏洞报告页面通知 AWS/Amazon 安全团队。请不要创建公开的 GitHub 问题。

使用方法

开始会话

用例 1. 开始会话。

您需要启动会议会话才能开始发送和接收音频。

meetingSession.audioVideo.start()

默认配置为:

  • 音频格式为立体声/48KHz,即采样率为 48KHz 的立体声音频(stereo48K)
  • 音频设备功能为输入和输出,即同时启用麦克风和扬声器,这需要音频录制权限(使用 .outputOnly.none 可避免需要音频录制权限)
  • CallKit 禁用
  • 音频冗余启用

您可以在 AudioVideoConfiguration 中指定非默认选项,然后启动会议会话。

var audioVideoConfig = AudioVideoConfiguration(
    audioMode: .mono48k,
    audioDeviceCapabilities: .outputOnly,
    callKitEnabled: true,
    enableAudioRedundancy: false, 
    reconnectTimeoutMs: 180 * 1000)
meetingSession.audioVideo.start(audioVideoConfiguration: audioVideoConfig)

用例 2. 添加观察者以接收音频和视频会话生命周期事件。

注意:为避免错过任何事件,请在会话开始前添加观察者。您可以通过调用 meetingSession.audioVideo.removeAudioVideoObserver(observer) 来移除观察者。

class MyAudioVideoObserver: AudioVideoObserver {
    func audioSessionDidStartConnecting(reconnecting: Bool) {
        if (reconnecting) {
            // 例如,网络连接中断。
        }
    }
    func audioSessionDidStart(reconnecting: Bool) {
        // 会议会话开始。
        // 可以使用实时和设备 API。
    }
    func audioSessionDidDrop() {}
    func audioSessionDidStopWithStatus(sessionStatus: MeetingSessionStatus) {
         // 详见"结束会话"部分。
    }
    func audioSessionDidCancelReconnect() {}
    func connectionDidRecover() {}
    func connectionDidBecomePoor() {}
    func videoSessionDidStartConnecting() {}
    func videoSessionDidStartWithStatus(sessionStatus: MeetingSessionStatus) {
        // 视频会话开始。
        // 可以使用视频 API。
    }
    func videoSessionDidStopWithStatus(sessionStatus: MeetingSessionStatus) {}

    meetingSession.audioVideo.addAudioVideoObserver(observer: self)
}

设备

用例 3. 列出音频设备。

列出会议可用的音频设备。

// MediaDevice 对象的列表
let audioDevices = meetingSession.audioVideo.listAudioDevices()

for device in audioDevices {
    logger.info(msg: "设备类型: \(device.type), 标签: \(device.label)")
}

用例 4. 通过传递 MediaDevice 对象选择音频设备。

注意:您应该在会话开始后调用此方法,否则将不生效。您应该使用 listAudioDevices() 返回的设备之一调用 chooseAudioDevice。

let audioDevices = audioVideo.listAudioDevices()
val device = /* audioDevices 中的一项 */
meetingSession.audioVideo.chooseAudioDevice(mediaDevice: device)           

用例 5. 切换摄像头。

注意:如果您使用自定义摄像头捕获源,switchCamera() 将不生效。请参阅 自定义视频 获取更多详情。

切换使用设备的前置或后置摄像头(如果可用)。

meetingSession.audioVideo.switchCamera()

用例 6. 添加观察者以接收更新的设备列表。

添加 DeviceChangeObserver 以在新的音频设备连接或音频设备断开连接时接收回调。audioDeviceDidChange 包含更新后的设备列表。

class MyDeviceChangeObserver: DeviceChangeObserver {
    func audioDeviceDidChange(freshAudioDeviceList: [MediaDevice]) {
        // 更新后的 MediaDevice 对象列表
        for device in freshAudioDeviceList {
            logger.info(msg: "设备类型: \(device.type), 标签: \(device.label)")
        }    
    }

    meetingSession.audioVideo.addDeviceChangeObserver(observer: self)
}

用例 7. 获取当前选择的音频设备。

let activeAudioDevice = meetingSession.audioVideo.getActiveAudioDevice()

音频

用例 8. 选择音频配置。

加入会议时,支持 单声道/16KHz单声道/48KHz立体声/48KHz。如果在启动音频会话时未明确指定,立体声/48KHz 将被设置为默认音频模式。

meetingSession.audioVideo.start() // 以立体声/48KHz 音频、启用音频输入和输出设备、禁用 callkit 以及启用音频冗余的方式启动音视频会话

meetingSession.audioVideo.start(audioVideoConfiguration) // 使用指定的 [AudioVideoConfiguration] 启动音视频会话

注意:到目前为止,您已经添加了观察者来接收设备和会话生命周期事件。在以下用例中,您将使用实时 API 方法来发送和接收音量指示器并控制静音状态。

用例 9. 静音和取消静音音频输入。

let muted = meetingSession.audioVideo.realtimeLocalMute() // 如果静音成功返回 true,失败返回 false

let unmuted = meetingSession.audioVideo.realtimeLocalUnmute // 如果取消静音成功返回 true,失败返回 false

用例 10. 添加观察者以观察特定与会者的实时事件,如音量变化/信号变化/静音状态。

您可以使用此功能构建实时指示器 UI,并通过数组传递的变化来更新它们。

注意:这些回调将只包含与前一次回调的差异。

class MyRealtimeObserver: RealtimeObserver {
    func volumeDidChange(volumeUpdates: [VolumeUpdate]) {
        for currentVolumeUpdate in volumeUpdates {
            // 静音、未说话、低音量、中音量、高音量
            logger.info(msg: "\(currentVolumeUpdate.attendeeInfo.attendeeId) 的音量发生变化: \(currentVolumeUpdate.volumeLevel)")
        }
    }
    func signalStrengthDidChange(signalUpdates: [SignalUpdate]) {
        for currentSignalUpdate in signalUpdates {
            // 无信号、弱信号、强信号
            logger.info(msg: "\(currentSignalUpdate.attendeeInfo.attendeeId) 的信号强度发生变化: \(currentSignalUpdate.signalStrength)")
        }
    }
    func attendeesDidJoin(attendeeInfo: [AttendeeInfo]) {
        for currentAttendeeInfo in attendeeInfo {
            logger.info(msg: "\(currentAttendeeInfo.attendeeId) 加入了会议")
        }
    }
    func attendeesDidLeave(attendeeInfo: [AttendeeInfo]) {
        for currentAttendeeInfo in attendeeInfo {
            logger.info(msg: "\(currentAttendeeInfo.attendeeId) 离开了会议")
        }
    }
    func attendeesDidDrop(attendeeInfo: [AttendeeInfo]) {
        for currentAttendeeInfo in attendeeInfo {
            logger.info(msg: "\(currentAttendeeInfo.attendeeId) 从会议中掉线")
        }
    }
    func attendeesDidMute(attendeeInfo: [AttendeeInfo]) {
        for currentAttendeeInfo in attendeeInfo {
            logger.info(msg: "\(currentAttendeeInfo.attendeeId) 已静音")
        }
    }
    func attendeesDidUnmute(attendeeInfo: [AttendeeInfo]) {
        for currentAttendeeInfo in attendeeInfo {
            logger.info(msg: "\(currentAttendeeInfo.attendeeId) 已取消静音")
        }
    }

    meetingSession.audioVideo.addRealtimeObserver(observer: self)
}

用例11. 检测活跃发言者和发言者的活跃分数。

您可以使用 activeSpeakerDidDetect 事件来放大或突出显示最活跃发言者的视频图块(如果可用)。通过设置 scoreCallbackIntervalMs 并实现 activeSpeakerScoreDidChange,您可以定期接收活跃发言者的分数。

class MyActiveSpeakerObserver: ActiveSpeakerObserver {
    let activeSpeakerObserverId = UUID().uuidString

    var observerId: String {
        return activeSpeakerObserverId
    }

    func activeSpeakerDidDetect(attendeeInfo: [AttendeeInfo]) {
        if !attendeeInfo.isEmpty {
            logger.info(msg: "\(attendeeInfo[0].attendeeId) 是最活跃的发言者")
        }
    }

    var scoresCallbackIntervalMs: Int {
        return 1000 // 1秒
    }

    func activeSpeakerScoreDidChange(scores: [AttendeeInfo: Double]) {
       let scoresInString = scores.map { (score) -> String in
            let (key, value) = score
            return "\(key.attendeeId): \(value)"
       }.joined(separator: ",")
       logger.info(msg: "活跃发言者的分数为: \(scoresInString)")
    }

    // 基于SDK提供的策略计算活跃发言者,您可以提供任何自定义算法
    meetingSession.audioVideo.addActiveSpeakerObserver(policy: DefaultActiveSpeakerPolicy(), observer: self)
}

视频

注意:您需要将视频绑定到 VideoRenderView 才能显示视频。

本地视频图块可以通过 isLocalTile 属性来识别。

内容视频图块可以通过 isContent 属性来识别。参见屏幕和内容共享

当同一远程参与者重新启动视频时,会使用新的图块ID创建一个图块。

您可以在使用Amazon Chime SDK在iOS上构建会议应用程序中找到更多关于添加/移除/查看视频的详细信息。

用例12. 开始接收远程视频。

您可以调用 startRemoteVideo 来开始接收远程视频,因为默认情况下不会自动接收。

meetingSession.audioVideo.startRemoteVideo()

用例13. 停止接收远程视频。

stopRemoteVideo 停止接收远程视频,并为现有的远程视频触发 onVideoTileRemoved

meetingSession.audioVideo.stopRemoteVideo()

用例14. 查看远程视频图块。

class MyVideoTileObserver: VideoTileObserver {
    func videoTileDidAdd(tileState: VideoTileState) {
        // 忽略本地视频(参见查看本地视频)和内容视频(参见屏幕和内容共享)
        if tileState.isLocalTile || tileState.isContent {
            return
        }

       let videoRenderView = /* 您应用程序中用于显示视频的VideoRenderView对象 */
       meetingSession.audioVideo.bind(videoView: videoRenderView, tileId: tileState.tileId)
    }

    func videoTileDidRemove(tileState: VideoTileState) {
        // 解绑视频视图以停止查看图块
        meetingSession.audioVideo.unbindVideoView(tileId: tileState.tileId)
    }

   meetingSession.audioVideo.addVideoTileObserver(observer: self)
}

用例15. 开始共享您的视频。

// 使用内部摄像头捕获本地视频
meetingSession.audioVideo.startLocalVideo()

// 使用内部摄像头捕获并为视频设置配置,例如启用模拟广播和最大比特率
// 如果未设置maxBitRateKbps,它将根据会议中的用户数量和视频数量自动调整
// 可以多次调用此方法来启用/禁用模拟广播并动态调整视频最大比特率
let localVideoConfig = LocalVideoConfiguration(simulcastEnabled: true, maxBitRateKbps: 600)
meetingSession.audioVideo.startLocalVideo(config: localVideoConfig)

// 您可以切换摄像头以更改视频输入设备
meetingSession.audioVideo.switchCamera()

// 或者,您可以为本地视频注入自定义视频源,请参阅自定义视频指南

用例16. 停止共享您的视频。

meetingSession.audioVideo.stopLocalVideo()

用例17. 查看本地视频。

注意:本地视频应该是镜像的。设置 VideoRenderView.mirror = true

class MyVideoTileObserver: VideoTileObserver {
    func videoTileDidAdd(tileState: VideoTileState) {
            if tileState.isLocalTile {
                let localVideoView = /* 您应用程序中用于显示视频的VideoRenderView对象 */
                meetingSession.audioVideo.bind(videoView: localVideoView, tileId: tileState.tileId)
            }
        }
    }

    func videoTileDidRemove(tileState: VideoTileState) {
        // 解绑视频视图以停止查看图块
        meetingSession.audioVideo.unbindVideoView(tileId: tileState.tileId)
    }

    meetingSession.audioVideo.addVideoTileObserver(observer: self)
}

有关更高级的视频图块管理,请查看视频分页

屏幕和内容共享

注意:当您或其他参与者共享内容(例如屏幕捕获或任何其他VideoSource对象)时,内容参与者(attendee-id#content)会加入会话,并像普通参与者共享视频一样共享内容。

例如,您的参与者ID是"my-id"。当您调用 meetingSession.audioVideo.startContentShare 时,内容参与者"my-id#content"将加入会话并共享您的内容。

用例18. 开始共享您的屏幕或内容。

class MyContentShareObserver: ContentShareObserver {
    func contentShareDidStart() {
        logger.info(msg: "内容共享已开始")
    }

    func contentShareDidStop(status: ContentShareStatus){
        logger.info(msg: "内容共享已停止")
    }

    meetingSession.audioVideo.addContentShareObserver(observer: self)
    let contentShareSource = /* ContentShareSource对象,可以使用InAppScreenCaptureSource进行屏幕共享或任何带有自定义视频源的子类 */
    // ContentShareSource对象不由SDK管理,开发者需要相应地启动、停止、释放
    meetingSession.audioVideo.startContentShare(source: contentShareSource)
}

您可以为内容共享设置配置,例如maxBitRateKbps。实际达到的质量可能会根据系统和网络的情况在通话过程中有所变化。

let contentShareConfig = LocalVideoConfiguration(maxBitRateKbps: 200)
meetingSession.audioVideo.startContentShare(source: contentShareSource, config: contentShareConfig)

更多详情请参见内容共享

用例19. 停止共享您的屏幕或内容。

meetingSession.audioVideo.stopContentShare()

用例20. 查看参与者的内容或屏幕。

Chime SDK允许每个会议同时进行两个内容共享。远程内容共享将触发 onVideoTileAdded,而本地共享则不会。要渲染预览视频,请将 VideoSink 添加到 ContentShareSource 中的 VideoSource

class MyVideoTileObserver: VideoTileObserver {
    func videoTileDidAdd(tileState: VideoTileState) {
        if (tileState.isContent) {
            // tileState.attendeeId 的格式为 "attendee-id#content"
            let attendeeId = tileState.attendeeId
            // 从 "attendee-id#content" 中获取参与者ID
            let baseAttendeeId = DefaultModality(attendeeId).base()
            logger.info(msg: "$baseAttendeeId 正在共享屏幕")

            let screenVideoView = /* 您应用程序中用于显示视频的VideoRenderView对象 */
            meetingSession.audioVideo.bindVideoView(videoView: screenVideoView, tileId: tileState.tileId)
        }
    }

    func videoTileDidRemove(tileState: VideoTileState) {
        meetingSession.audioVideo.unbindVideoView(tileId: tileState.tileId)
    }

    meetingSession.audioVideo.addVideoTileObserver(observer: self)
}

指标

用例21. 添加观察者以接收会议指标。

查看 ObservableMetric 以获取更多可用指标,并监控音频、视频和内容共享质量。

class MyMetricsObserver: MetricsObserver {
    func metricsDidReceive(metrics: [AnyHashable: Any]) {
        logger.info(msg: "已接收媒体指标: \(metrics)")
    }

    meetingSession.audioVideo.addMetricsObserver(observer: self)
}

数据消息

用例22. 添加观察者以接收数据消息。

启动会议会话后,您可以接收来自多个主题的实时消息。

class MyDataMessageObserver: DataMessageObserver {
    let dataMessageTopic = "chat"
    // 后端会返回本地发送者的节流消息
    func dataMessageDidReceived(dataMessage: DataMessage) {
        logger.info(msg: "\(dataMessage.timestampMs) \(dataMessage.text()) \(dataMessage.senderAttendeeId)")
    }

    // 您还可以订阅多个主题。
    meetingSession.audioVideo.addRealtimeDataMessageObserver(topic: dataMessageTopic, observer: self)
}

用例23. 发送数据消息。

您可以向任何主题发送实时消息,已订阅的观察者将会收到通知。

注意:主题需要是字母数字,可以包含连字符和下划线。数据不能超过2kb,生命周期是可选的,但必须是正整数。

let dataMessageTopic = "chat"
let dataMessageLifetimeMs = 1000

do {
    // 向订阅"chat"主题的任何订阅者发送"Hello Chime",生命周期为1秒
    try meetingSession
        .audioVideo
        .realtimeSendDataMessage(topic: dataMessageTopic,
                                 data: "Hello Chime",
                                 lifetimeMs: dataMessageLifetimeMs)
} catch let err as SendDataMessageError {
    logger.error(msg: "发送消息失败!\(err)")
} catch {
    logger.error(msg: "未知错误 \(error.localizedDescription)")
}

停止会话

注意:确保移除所有您添加的观察者并释放资源,以避免任何内存泄漏。

用例24. 停止会话。

class MyAudioVideoObserver: AudioVideoObserver {
    func audioSessionDidStopWithStatus(sessionStatus: MeetingSessionStatus) {
        // 这里是会议结束的地方。
        // 您可以在这里进行一些清理工作。
    }

    func videoSessionDidStopWithStatus(sessionStatus: MeetingSessionStatus) {
        // 这个方法也会被调用。
    }

    meetingSession.audioVideo.addAudioVideoObserver(observer: self)
    meetingSession.audioVideo.stop()
}

Amazon Voice Focus

Amazon Voice Focus 可以减少会议中的背景噪音,以获得更好的会议体验。有关更多详细信息,请参阅 Amazon Voice Focus

用例25. 启用/禁用 Amazon Voice Focus。

let enabled = audioVideo.realtimeSetVoiceFocusEnabled(enabled: true) // 成功启用 Amazon Voice Focus

let disabled = audioVideo.realtimeSetVoiceFocusEnabled(enabled: false) // 成功禁用 Amazon Voice Focus

自定义视频源

自定义视频源允许您控制视频,例如应用视频滤镜。有关更多详细信息,请参阅 自定义视频

冗余音频

从0.23.3版本开始,SDK在检测到丢包时开始向我们的服务器发送冗余音频数据,以帮助减少其对音频质量的影响。冗余音频数据包仅针对包含活跃音频(即语音或音乐)的数据包发送。这可能会使音频消耗的带宽增加到正常量的3倍,具体取决于检测到的丢包量。如果SDK在5分钟内没有检测到任何丢包,它将自动停止发送冗余数据。

如果您需要禁用此功能,可以在开始会话之前通过AudioVideoConfiguration进行设置。

meetingSession.audioVideo.start(AudioVideoConfiguration(enableAudioRedundancy: false))

虽然有选项可以禁用此功能,但我们建议保持启用以提高音频质量。禁用它的一个可能原因是如果您的客户有非常严格的带宽限制。

常见问题

有关Amazon Chime SDK的常见问题,请参阅常见问题

调试

我如何获取Amazon Chime SDK的日志进行调试?

应用程序可以通过在创建MeetingSession时传递Logger实例来获取Chime SDK的日志。Amazon Chime SDK有一些默认的日志记录器实现,您的应用程序可以使用,例如ConsoleLogger,它将日志输出到控制台。ConsoleLogger默认设置为INFO级别。因此,为了获取所有日志,包括媒体日志,请按以下方式创建日志记录器:

logger = ConsoleLogger(name: "logger", level: .DEFAULT)

注意

您和您的最终用户对用于背景替换的所有内容(包括任何图像)负责,并且必须确保此类内容不违反法律,不侵犯或盗用任何第三方的权利,也不以其他方式违反您与亚马逊的协议的重要条款(包括文档、AWS服务条款或可接受使用政策)。


版权所有 Amazon.com, Inc. 或其附属公司。保留所有权利。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号