You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Kinesis Video Stream提取的音频噪声大问题排查 - AWS Lambda Python

修复Amazon Connect音频流提取失真问题

核心问题分析

原代码的主要问题是直接将Kinesis Video返回的原始容器数据(MKV格式)当作PCM音频写入WAV文件,未处理以下关键环节:

  • Kinesis Video流的MKV容器封装结构
  • Amazon Connect音频采用的G.711 μ-law编码格式
  • 错误的片段选择逻辑导致获取的音频片段不完整

修复后的Lambda函数

需先为Lambda添加包含pyav库的层(Lambda默认环境无此库),再替换代码如下:

import boto3
import json
import wave
import io
import av

def lambda_handler(event, context):
    print("Lambda function started")
    
    # 替换为实际的StreamARN和目标片段编号
    stream_arn = 'arn:aws:kinesisvideo:ap-southeast-1:xxxxx:stream/audio-connect-e97b519c-b689-4dcf-a6e0-xxxxx/xxxxx'
    fragment_start_number = '91343852333xxxxx661842844xxxxx628'

    print(f"StreamARN: {stream_arn}")
    print(f"FragmentStartNumber: {fragment_start_number}")

    # 初始化Kinesis Video相关客户端
    kinesis_video_client = boto3.client('kinesisvideo')
    endpoint = kinesis_video_client.get_data_endpoint(StreamARN=stream_arn, APIName='GET_MEDIA')['DataEndpoint']
    kinesis_video_media_client = boto3.client('kinesis-video-media', endpoint_url=endpoint)

    # 修正片段选择:直接指定目标片段编号,避免跳过目标数据
    media_response = kinesis_video_media_client.get_media(
        StreamARN=stream_arn,
        StartSelector={
            'StartSelectorType': 'FRAGMENT_NUMBER',
            'FragmentNumber': fragment_start_number
        }
    )
    video_stream = media_response['Payload']

    # 解析MKV容器,提取并解码音频流
    container = av.open(video_stream)
    audio_frames = []
    for frame in container.decode(audio=0):
        # 将G.711 μ-law编码转换为标准16位PCM数据
        audio_frames.append(frame.to_ndarray().flatten())
    
    # 合并所有音频帧为完整PCM数据
    pcm_data = b''.join([frame.tobytes() for frame in audio_frames])

    # 生成标准WAV文件并上传到S3
    with io.BytesIO() as audio_buffer:
        with wave.open(audio_buffer, 'wb') as wav_file:
            wav_file.setnchannels(1)
            wav_file.setsampwidth(2)  # 16位PCM对应2字节采样宽度
            wav_file.setframerate(8000)
            wav_file.writeframes(pcm_data)
        
        s3_bucket = 'amazon-connect-xxxxx'
        s3_key = f'voicemails/{fragment_start_number}.wav'
        s3_client = boto3.client('s3')
        audio_buffer.seek(0)
        s3_client.upload_fileobj(audio_buffer, s3_bucket, s3_key)
    
    print("Lambda function completed successfully")
    return {
        'statusCode': 200,
        'body': json.dumps("Audio extraction and upload completed successfully")
    }

关键修复点说明

  • 容器解析与音频解码:使用pyav库解析Kinesis Video的MKV容器,将G.711 μ-law编码的音频转换为标准16位PCM,这是解决噪声与失真的核心。
  • 片段选择逻辑修正:将AfterFragmentNumber改为FragmentNumber,确保精准获取目标片段的音频数据,而非跳过该片段。
  • 音频参数匹配:严格对齐Amazon Connect的音频参数(单声道、8kHz采样率),生成符合WAV标准的音频文件。

Lambda层配置步骤

Lambda默认环境无pyav库,需创建对应层:

  1. 在Linux环境或Docker模拟Lambda环境中执行:pip install av -t python/
  2. 将python/目录打包为zip文件
  3. 在AWS控制台创建Lambda层,上传该zip包并关联到目标Lambda函数

内容的提问来源于stack exchange,提问作者Sami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:47:31