Project Icon

amazon-chime-sdk-android

Android实时音视频通信SDK助力开发

Amazon Chime SDK for Android是一个开源工具包,用于在Android应用中集成音频通话、视频通话和屏幕共享功能。该SDK提供全面的API用于配置会议、管理设备、共享屏幕和处理媒体事件。开发者可以利用它快速构建自定义通信功能,并使用与Amazon Chime相同的底层基础设施。

适用于 Android 的 Amazon Chime SDK

Amazon Chime SDK 项目看板

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

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

适用于 Android 的 Amazon Chime SDK 通过使用为 Amazon Chime 服务上的会议提供支持的相同基础设施服务,可以轻松地将协作音频通话、视频通话和屏幕共享查看功能添加到 Android 应用程序中。

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

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

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

并查看以下指南:

设置

注意:如果您只想运行演示应用程序,请跳到运行演示应用程序

适用于 Android 的移动 SDK 可以从 Maven Central 存储库下载,通过集成到您的 Android 项目的 Gradle 文件中,或者可以通过 .aar 文件直接嵌入。

为了设置,您项目的根文件夹将被称为 root

从 Maven 获取

要从 Maven 获取依赖项,请将依赖项添加到您的应用程序的(模块级)build.gradle 中。

更新 root/app 中的 build.gradle,并在 dependencies 下添加以下内容:

dependencies {
    implementation 'software.aws.chimesdk:amazon-chime-sdk-media:$MEDIA_VERSION'
    implementation 'software.aws.chimesdk:amazon-chime-sdk:$SDK_VERSION'
}

版本号可以从最新的发布版本获取。

如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用 amazon-chime-sdk-media-no-video-codecs 来减小大小。从 amazon-chime-sdk 的传递依赖中排除 amazon-chime-sdk-media 模块和/或 amazon-chime-sdk-machine-learning 模块的使用:

dependencies {
    implementation 'software.aws.chimesdk:amazon-chime-sdk-media-no-video-codecs:$MEDIA_VERSION'
    implementation ('software.aws.chimesdk:amazon-chime-sdk:$MEDIA_VERSION') {
        exclude module: 'amazon-chime-sdk-media'
        exclude module: 'amazon-chime-sdk-machine-learning'
    }
}

项目现在可以构建 Arm 和 x86 目标,这在打包应用程序时可能有用。x86 目标将无法运行,也不打算在任何 x86 设备或模拟器上安装或运行。 重要:仅支持 Arm 设备。

如果您需要媒体二进制文件中的非功能性 x86 存根以打包您的应用程序,可以在您选择的媒体依赖项后附加 -x86-stub。例如:

dependencies {
    implementation 'software.aws.chimesdk:amazon-chime-sdk-media-no-video-codecs-x86-stub:$MEDIA_VERSION'
    implementation ('software.aws.chimesdk:amazon-chime-sdk:$MEDIA_VERSION') {
        exclude module: 'amazon-chime-sdk-media'
        exclude module: 'amazon-chime-sdk-machine-learning'
    }
}

手动下载 SDK 二进制文件

要在您自己的项目中包含 SDK 二进制文件,请按照以下步骤操作。

1. 下载二进制文件

从最新的发布版本下载 amazon-chime-sdkamazon-chime-sdk-media 二进制文件。

如果您想使用更多机器学习功能,例如背景模糊/替换,还请从最新的发布版本下载 amazon-chime-sdk-machine-learning 二进制文件。否则,您可以忽略以下说明中所有关于 amazon-chime-sdk-machine-learning 的引用。

如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用 amazon-chime-sdk-media-no-video-codecs 代替 amazon-chime-sdk-media 来排除软件视频编解码器支持并减小大小。如果是这样,您可以在以下说明中将所有对 amazon-chime-sdk-media 的引用视为 amazon-chime-sdk-media-no-video-codecs

项目现在可以构建 Arm 和 x86 目标,这在打包应用程序时可能有用。x86 目标将无法运行,也不打算在任何 x86 设备或模拟器上安装或运行。 重要:仅支持 Arm 设备。

如果您需要非功能性 x86 存根与完全功能的 arm 架构结合以打包您的应用程序,可以使用 amazon-chime-sdk-media-x86-stubamazon-chime-sdk-media-no-video-codecs-x86-stub 媒体二进制文件,并在以下说明中将它们替换为 amazon-chime-sdk-media 引用。

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

解压缩它们并将 aar 文件复制到 root/app/libs

2. 更新 gradle 文件

root 中更新 build.gradle,在 allprojectsrepositories 下添加以下内容:

allprojects {
   repositories {
      jcenter()
      flatDir {
        dirs 'libs'
      }
   }
}

root/app 中更新 build.gradle,并在 dependencies 下添加以下内容:

implementation(name: 'amazon-chime-sdk', ext: 'aar')
implementation(name: 'amazon-chime-sdk-media', ext: 'aar')

如果您使用 amazon-chime-sdk-machine-learning 库,那么也在 dependencies 下添加以下语句:

implementation(name: 'amazon-chime-sdk-machine-learning', ext: 'aar')

root/appbuild.gradle 中的 compileOptions 下更新:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

运行演示应用程序

注意:这仅用于运行演示应用程序,并使用 SDK 作为代码而不是 aar 库。

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

注意:请确保您在支持 ARM 的设备(真实设备)或支持 arm 的模拟器上运行。我们目前不支持 x86,因此带有 x86 的模拟器将无法工作。

1. 部署无服务器演示

amazon-chime-sdk-js 部署无服务器演示,它将返回 https://xxxxx.xxxxx.xxx.com/Prod/

为移动演示应用程序提供 https://xxxxx.xxxxx.xxx.com/Prod/

2. 下载二进制文件

从最新的发布版本下载 amazon-chime-sdk-media 二进制文件。

下载 amazon-chime-sdk-machine-learning 二进制文件以获取机器学习功能。

解压缩并将 aar 文件复制到 amazon-chime-sdk-android/amazon-chime-sdk/libs

3. 更新演示应用程序

amazon-chime-sdk-android/app/src/main/res/values 路径下的 strings.xml 中更新 test_url,使用步骤 1 中部署的无服务器演示的 URL。

注意:使用 https://xxxxx.xxxxx.xxx.com/Prod/

报告疑似漏洞

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

使用方法

开始会话

用例 1. 开始会话。

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

使用默认配置开始会话:

meetingSession.audioVideo.start()

使用自定义配置开始会话:

meetingSession.audioVideo.start(audioVideoConfiguration)

audioVideoConfiguration 中可用的配置包括:

  • audioMode
  • audioDeviceCapabilities
  • audioStreamType
  • audioRecordingPresetOverride
  • enableAudioRedundancy
  • reconnectTimeoutMs

音频模式:默认音频格式是立体声/48KHz,即采样率为48KHz的立体声音频(Stereo48K)。其他支持的音频格式包括单声道/48KHz(Mono48K)或单声道/16KHz(Mono16K)。您可以在 AudioVideoConfiguration 中指定非默认音频模式,然后开始会议会话。 AudioDeviceCapabilities:默认的音频设备功能是同时启用音频输入和输出设备(InputAndOutput),即麦克风和扬声器都处于启用状态。InputAndOutput需要MODIFY_AUDIO_SETTINGSRECORD_AUDIO权限。其他选项包括OutputOnly(麦克风禁用,扬声器启用;需要MODIFY_AUDIO_SETTINGS权限)和None(麦克风和扬声器都禁用;不需要任何音频权限)。

AudioStreamType:默认值为VoiceCall。可用选项有VoiceCallMusic,它们分别等同于AudioManager中的STREAM_VOICE_CALLSTREAM_MUSIC。此配置用于解决Oculus Quest 2上的音量问题。如果你不了解这个问题,可能不需要担心它。更多信息请参考Android文档:STREAM_VOICE_CALLSTREAM_MUSIC

注意:尽管Android中有更多可用的流选项,但目前Amazon Chime SDK for Android仅支持STREAM_VOICE_CALLSTREAM_MUSIC

AudioRecordingPresetOverride:默认值为None。可用选项有NoneGenericCamcorderVoiceRecognitionVoiceCommunication。这些相当于此处提到的Android AudioRecorder配置中的选项。

EnableAudioRedundancy:默认值为true。启用时,SDK将在检测到数据包丢失时发送冗余音频数据,以帮助减少其对音频质量的影响。更多详情可以在冗余音频部分找到。

ReconnectTimeoutMs:默认值为180,000毫秒。使用此配置来控制由于网络状况不佳导致的会话重新连接超时。

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

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

val observer = object : AudioVideoObserver {
    override fun onAudioSessionStartedConnecting(reconnecting: Boolean) {
        if (reconnecting) {
            // 例如,网络连接断开
        }
    }
    override fun onAudioSessionStarted(reconnecting: Boolean) {
        // 会议会话开始。
        // 可以使用实时和设备API。
    }
    override fun onAudioSessionDropped(reconnecting: Boolean) {}
    override fun onAudioSessionStopped(sessionStatus: MeetingSessionStatus) {
        // 参见"停止会话"部分了解详情。
    }
    override fun onAudioSessionCancelledReconnect() {}
    override fun onConnectionRecovered() {}
    override fun onConnectionBecamePoor() {}
    override fun onVideoSessionStartedConnecting() {}
    override fun onVideoSessionStarted(sessionStatus: MeetingSessionStatus) {
        // 视频会话开始。
        // 可以使用视频API。
    }
    override fun onVideoSessionStopped(sessionStatus: MeetingSessionStatus) {}
}

meetingSession.audioVideo.addAudioVideoObserver(observer)

设备

用例3. 列出音频设备。

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

val audioDevices = meetingSession.audioVideo.listAudioDevices()

// MediaDevice对象列表
audioDevices.forEach {
    logger.info(TAG, "设备类型:${it.type},标签:${it.label}")
}

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

注意:你应该在会话开始后调用chooseAudioDevice,否则它将不会执行任何操作。你还应该使用listAudioDevices返回的设备之一来调用chooseAudioDevice。

// 过滤掉当前不支持选择的OTHER类型
val audioDevices = meetingSession.audioVideo.listAudioDevices().filter {
    it.type != MediaDeviceType.OTHER)
}
val device = /* audioDevices中的一个项目 */
meetingSession.audioVideo.chooseAudioDevice(device)

用例5. 切换摄像头。

注意:如果你使用自定义摄像头捕获源,switchCamera()将不会执行任何操作。请参考自定义视频了解更多详情。

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

meetingSession.audioVideo.switchCamera()

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

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

val observer = object: DeviceChangeObserver {
    override fun onAudioDeviceChanged(freshAudioDeviceList: List<MediaDevice>) {
        // 更新后的MediaDevice对象列表
        freshAudioDeviceList.forEach {
            logger.info(TAG, "设备类型:${it.type},标签:${it.label}")
        }
    }
}

meetingSession.audioVideo.addDeviceChangeObserver(observer)

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

注意:getActiveAudioDevice API需要API级别24或更高。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    val activeAudioDevice = meetingSession.audioVideo.getActiveAudioDevice()
}

对于较低的API级别,开发者可以通过以下逻辑跟踪所选设备来实现相同的功能:

var activeAudioDevice: MediaDevice? = null
override fun onAudioDeviceChanged(freshAudioDeviceList: List<MediaDevice>) {
    val device = /* freshAudioDeviceList中的一个项目 */
    meetingSession.audioVideo.chooseAudioDevice(device)
    activeAudioDevice = device // 更新当前设备
}

音频

用例8. 选择音频配置。

加入会议时,如果在开始音频会话时未明确指定,每个配置都会有一个默认值。

  • 支持的AudioMode选项:Mono/16KHzMono/48KHzStereo/48KHz。默认为Stereo/48KHz
  • 支持的AudioDeviceCapabilities选项:Input and OutputOutput OnlyNone。默认为Input and Output
  • 支持的AudioStreamType选项:VoiceCallMusic。默认为VoiceCall
  • 支持的AudioRecordingPresetOverride选项:NoneGenericCamcorderVoiceRecognitionVoiceCommunication。默认为None
  • 支持的enableAudioRedundancy选项:truefalse。默认为true
  • 支持的reconnectTimeoutMs值:大于或等于0的整数。默认为180,000
meetingSession.audioVideo.start() // 使用上述默认值启动音频视频会话

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

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

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

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

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

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

你可以使用这个来构建实时指示器UI,并根据数组传递的变化进行更新。

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

val observer = object : RealtimeObserver {
    override fun onVolumeChanged(volumeUpdates: Array<VolumeUpdate>) {
        volumeUpdates.forEach { (attendeeInfo, volumeLevel) ->
            logger.info(TAG, "${attendeeInfo.attendeeId}的音量变化:" +
                $volumeLevel // Muted, NotSpeaking, Low, Medium, High
            )
        }
    }

    override fun onSignalStrengthChanged(signalUpdates: Array<SignalUpdate>) {
        signalUpdates.forEach { (attendeeInfo, signalStrength) ->
            logger.info(TAG, "${attendeeInfo.attendeeId}的信号强度变化:" +
                $signalStrength // None, Low, High
            )
        }
    }

    override fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}加入了会议") }
    }

    override fun onAttendeesLeft(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}离开了会议") }
    }

    override fun onAttendeesDropped(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}从会议中掉线") }
    }

    override fun onAttendeesMuted(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}已静音") }
    }

    override fun onAttendeesUnmuted(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}已取消静音") }
    }
}

meetingSession.audioVideo.addRealtimeObserver(observer)

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

你可以使用onActiveSpeakerDetected事件来放大或强调最活跃发言者的视频窗格(如果有)。通过设置scoreCallbackIntervalMs并实现onActiveSpeakerScoreChanged,你可以定期接收活跃发言者的分数。

val observer = object : ActiveSpeakerObserver {
    override fun onActiveSpeakerDetected(attendeeInfo: Array<AttendeeInfo>) {
        if (attendeeInfo.isNotEmpty()) {
            logger.info(TAG, "${attendeeInfo[0].attendeeId}是最活跃的发言者")
        }
    }
// 设置每1秒接收一次onActiveSpeakerScoreChanged事件
override val scoreCallbackIntervalMs: Int? get() = 1000

override fun onActiveSpeakerScoreChanged(scores: Map<AttendeeInfo, Double>) {
    val scoreString = scores.map { entry -> "${entry.key.attendeeId}: ${entry.value}" }.joinToString(",")
    logger.info(TAG, "活跃发言者的分数为: $scoreString")
}
}

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

视频

注意:你需要将视频绑定到VideoRenderView才能渲染它。

可以使用isLocalTile属性识别本地视频图块。

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

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

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

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

你可以调用startRemoteVideo来开始接收远程视频,因为这默认不会发生。

meetingSession.audioVideo.startRemoteVideo()

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

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

meetingSession.audioVideo.stopRemoteVideo()

用例14. 查看远程视频。

val observer = object : VideoTileObserver {
    override fun onVideoTileAdded(tileState: VideoTileState) {
        // 忽略本地视频(参见查看本地视频)和内容视频(参见屏幕和内容共享)
        if(tileState.isLocalTile || tileState.isContent) return

        val videoRenderView = /* 你应用程序中用于显示视频的VideoRenderView对象 */
        meetingSession.audioVideo.bindVideoView(videoRenderView, tileState.tileId)
    }

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

meetingSession.audioVideo.addVideoTileObserver(observer)

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

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

// 使用内部相机捕获本地视频
meetingSession.audioVideo.startLocalVideo()

// 使用内部相机捕获并设置视频配置,例如maxBitRateKbps
// 如果未设置maxBitRateKbps,它将根据会议中的用户数和视频数自动调整
// 可以多次调用此方法以动态调整视频配置
val localVideoConfig = LocalVideoConfiguration(600)
meetingSession.audioVideo.startLocalVideo(localVideoConfig)

// 你可以切换相机来更改视频输入设备
meetingSession.audioVideo.switchCamera()

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

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

meetingSession.audioVideo.stopLocalVideo()

用例17. 查看本地视频。

val observer = object : VideoTileObserver {
    override fun onVideoTileAdded(tileState: VideoTileState) {
        // 在调用startLocalVideo后会调用onVideoTileAdded
        val localVideoRenderView = /* 用于显示本地视频的VideoRenderView对象 */

        if (tileState.isLocalTile) {
            audioVideo.bindVideoView(localVideoRenderView, tileState.tileId)
        }
    }

    override onVideoTileRemoved(tileState: VideoTileState) {
        // 在调用stopLocalVideo后会调用onVideoTileRemoved
        if (tileState.isLocalTile) {
            logger.info(TAG, "本地视频已移除")
            audioVideo.unbindVideoView(tileState.tileId)
        }
    }
}

meetingSession.audioVideo.addVideoTileObserver(observer)

屏幕和内容共享

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

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

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

val observer = object : ContentShareObserver {
    override fun onContentShareStarted() {
        logger.info(TAG, "内容共享已开始")
    }

    override fun onContentShareStopped(status: ContentShareStatus) {
        logger.info(TAG, "内容共享已停止,状态为${status.statusCode}")
    }
}

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

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

val contentShareConfig = LocalVideoConfiguration(200)
meetingSession.audioVideo.startContentShare(contentShareSource, contentShareConfig)

有关更多详细信息,请参见内容共享

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

meetingSession.audioVideo.stopContentShare()

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

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

val observer = object : VideoTileObserver {
    override fun onVideoTileAdded(tileState: VideoTileState) {
        if (tileState.isContent) {
            // tileState.attendeeId的格式为"attendee-id#content"
            val attendeeId = tileState.attendeeId
            // 从"attendee-id#content"中获取attendee ID
            val baseAttendeeId = DefaultModality(attendeeId).base()
            logger.info(TAG, "$baseAttendeeId 正在共享屏幕")

            val contentVideoRenderView = /* 你应用程序中用于显示内容视频的VideoRenderView对象 */
            meetingSession.audioVideo.bindVideoView(contentVideoRenderView, tileState.tileId)
        }
    }

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

meetingSession.audioVideo.addVideoTileObserver(observer)

指标

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

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

val observer = object: MetricsObserver {
    override fun onMetricsReceived(metrics: Map<ObservableMetric, Any>) {
        metrics.forEach { (metricsName, metricsValue) ->
            logger.info(TAG, "$metricsName : $metricsValue")
        }
    }
}

meetingSession.audioVideo.addMetricsObserver(observer)

数据消息

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

启动会议会话后,你可以从多个主题接收实时消息。

注意:除非被限制,否则本地参与者发送的数据消息不会触发此回调。

val YOUR_ATTENDEE_ID = meetingSession.configuration.credentials.attendeeId

val observer = object: DataMessageObserver {
    override fun onDataMessageReceived(dataMessage: DataMessage) {
        // 后端返回的限制消息
        if (!dataMessage.throttled) {
            logger.info(TAG, "[${dataMessage.timestampMs}][{$dataMessage.senderAttendeeId}] : ${dataMessage.text()}")
    }
}

// 你可以订阅多个主题。
const val DATA_MESSAGE_TOPIC = "chat"
meetingSession.audioVideo.addRealtimeDataMessageObserver(DATA_MESSAGE_TOPIC, observer)

用例23. 发送数据消息。

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

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

const val DATA_MESSAGE_TOPIC = "chat"
const val DATA_MESSAGE_LIFETIME_MS = 1000

// 向订阅"chat"主题的任何订阅者发送"Hello Chime",生存时间为1秒
meetingSession.audioVideo.realtimeSendDataMessage(
    DATA_MESSAGE_TOPIC,
    "Hello Chime",
    DATA_MESSAGE_LIFETIME_MS
)

停止会话

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

用例24. 停止会话。

val observer = object: AudioVideoObserver {  
    override fun onAudioSessionStopped(sessionStatus: MeetingSessionStatus) {
        // 这里是会议结束的地方。
        // 你可以在这里进行一些清理工作。
    }

    override fun onVideoSessionStopped(sessionStatus: MeetingSessionStatus) {
        // 这也会被调用。
    }
}

meetingSession.audioVideo.addAudioVideoObserver(observer)
meetingSession.audioVideo.stop()

Amazon Voice Focus

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

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

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

val disabled = meetingSession.audioVideo.realtimeSetVoiceFocusEnabled(false) // 成功禁用Amazon Voice Focus

自定义视频源

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

背景模糊和替换

背景模糊/替换允许您对视频背景应用模糊效果或用图像替换背景。有关更多详细信息,请参阅背景滤镜

冗余音频

从版本0.18.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级别。因此,要获取所有日志(包括媒体日志),请按以下方式创建日志记录器:

val logger = ConsoleLogger(LogLevel.VERBOSE)

远程参与者听不到我的音频,我该怎么办?

SDK底层使用OpenSL ES,在打开与麦克风设备的连接时需要设置录音预设。我们发现没有一个特定的预设值能在所有可能的Android设备上都能很好地工作。SDK使用默认预设VoiceCommunication,这是我们在对我们拥有的设备进行一些测试后得出的结论。如果这个默认预设不起作用,导致远程方无法听到您的声音,请尝试通过在传递给start API的AudioVideoConfiguration中指定audioRecordingPresetOverride来使用不同的录音预设启动会话。

// 创建一个配置,其中预设被覆盖为Generic(例如)
val audioVideoConfig = AudioVideoConfiguration(audioRecordingPresetOverride = AudioRecordingPresetOverride.Generic)
// 启动音频视频
audioVideo.start(audioVideoConfig)

注意事项

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


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

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

豆包MarsCode

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

Project Cover

AI写歌

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

Project Cover

有言AI

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

Project Cover

Kimi

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

Project Cover

阿里绘蛙

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

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

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

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