如何用Python将Kinesis Video Stream GetMedia输出转存为S3的WAV文件
Python实现从Kinesis Video Stream提取语音信箱音频并转存S3为WAV文件
完全可以用Python实现该需求,无需局限于Java。以下是具体的实现步骤和代码示例:
核心依赖库
boto3:AWS官方Python SDK,用于调用KVS和S3 APIpymkv:解析MKV格式文件(KVS存储的媒体流为MKV封装)wave:Python标准库,用于生成WAV音频文件- (可选)
ffmpeg-python:更便捷的音频格式转换(若对MKV解析不熟悉,推荐使用)
实现步骤
1. 获取KVS数据端点并调用GetMedia API
KVS的GetMedia需要使用数据平面端点,需先通过GetDataEndpoint获取:
import boto3 import io import wave from pymkv import MKVFile # 初始化客户端 region = 'us-east-1' # 替换为你的AWS区域 stream_name = 'your-connect-voicemail-stream' # 替换为你的KVS流名称 kvs_client = boto3.client('kinesisvideo', region_name=region) data_endpoint = kvs_client.get_data_endpoint( StreamName=stream_name, APIName='GET_MEDIA' )['DataEndpoint'] kvs_media_client = boto3.client('kinesis-video-media', endpoint_url=data_endpoint, region_name=region) # 获取媒体流(这里选择最早的片段,也可指定FRAGMENT_NUMBER) media_response = kvs_media_client.get_media( StreamName=stream_name, StartSelector={'StartSelectorType': 'EARLIEST'} ) media_stream = media_response['Payload']
2. 解析MKV流并提取原始音频
将GetMedia返回的流写入内存或临时文件,再提取音频轨道:
# 将媒体流写入内存缓冲区 mkv_buffer = io.BytesIO() for chunk in media_stream.iter_chunks(chunk_size=1024*1024): mkv_buffer.write(chunk) mkv_buffer.seek(0) # 保存为临时MKV文件(pymkv暂不支持直接读取内存对象) with open('temp_voicemail.mkv', 'wb') as f: f.write(mkv_buffer.getvalue()) # 读取MKV并提取音频轨道(AWS Connect留言默认是轨道0,编码为PCMU/G.711 μ-law) mkv_file = MKVFile('temp_voicemail.mkv') audio_track = mkv_file.get_track(track_id=0) raw_audio = audio_track.extract_raw()
3. 将原始音频转换为WAV格式
AWS Connect的留言音频参数为:单声道、8kHz采样率、PCMU编码(每个样本1字节),用wave库生成标准WAV文件:
wav_buffer = io.BytesIO() with wave.open(wav_buffer, 'wb') as wav_file: wav_file.setnchannels(1) wav_file.setsampwidth(1) wav_file.setframerate(8000) wav_file.writeframes(raw_audio) wav_buffer.seek(0)
4. 上传WAV文件到S3
s3_client = boto3.client('s3', region_name=region) s3_bucket = 'your-voicemail-bucket' # 替换为你的S3桶名称 s3_key = 'voicemails/20240520_customer_message.wav' # 替换为目标S3键 s3_client.put_object( Bucket=s3_bucket, Key=s3_key, Body=wav_buffer )
可选方案:用FFmpeg简化转换
若觉得MKV解析繁琐,可直接用FFmpeg处理媒体流,无需手动解析轨道:
import ffmpeg # 将MKV流直接转成WAV ffmpeg.input('temp_voicemail.mkv').output( 'converted_voicemail.wav', acodec='pcm_u8', ar=8000, ac=1 ).run() # 上传到S3 with open('converted_voicemail.wav', 'rb') as f: s3_client.put_object(Bucket=s3_bucket, Key=s3_key, Body=f)
关键注意事项
- IAM权限:确保执行代码的角色拥有
kinesisvideo:GetDataEndpoint、kinesisvideo:GetMedia、s3:PutObject权限,以及对应KVS流的读取权限 - 片段选择:若需提取特定时间段的留言,可将
StartSelectorType设为SERVER_TIMESTAMP并指定时间范围 - 编码适配:若音频是PCMA(G.711 A-law),需将WAV的编码格式调整为
pcm_a(FFmpeg参数acodec='pcm_alaw')
内容的提问来源于stack exchange,提问作者Sundar kailasam
相关产品推荐
相关产品推荐

