Python中使用ffmpeg处理Django内存上传文件字节流拆分音视频的方法
问题修复方案
核心错误原因
- 调用
subprocess.run时同时指定stdin=subprocess.PIPE和input参数属于冲突用法:input参数已经内部封装了标准输入写入逻辑,无需额外声明stdin参数 - 错误将字节类型的
stream变量作为ffmpeg命令行参数传入:命令行参数仅支持字符串类型,你要处理的媒体内容是通过标准输入传递给ffmpeg的,不能放在参数列表中 - 使用ffmpeg-python时错误指定输入格式为
rawvideo:你的输入是正常封装的音视频文件(如MP4、MKV等),不是原始未封装的视频裸流,ffmpeg无法识别输入格式直接闪退,进而触发BrokenPipeError
方案1:提取音频保存到本地文件
import subprocess wav_path = f'{basename}.wav' command = [ "ffmpeg", '-i', '-', '-acodec', 'pcm_s16le', '-ar', '11025', '-ac', '1', '-y', wav_path ] # 仅传入input参数即可,不需要指定stdin subprocess.run(command, input=stream, check=True)
方案2:提取音频直接输出到内存(无需落盘,适配GCP上传)
不需要写入本地磁盘,直接拿到音频字节的类文件对象,可以直接传给GCP的upload_from_file方法:
import subprocess from io import BytesIO command = [ "ffmpeg", '-i', '-', '-acodec', 'pcm_s16le', '-ar', '11025', '-ac', '1', '-vn', '-sn', '-map_metadata', '-1', '-f', 'wav', 'pipe:1' ] result = subprocess.run( command, input=stream, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, # 不需要排查报错时可加这个屏蔽ffmpeg输出 check=True ) # 转成类文件对象直接上传 audio_file = BytesIO(result.stdout) blob_audio.upload_from_file(audio_file)
方案3:同时拆分音视频流到内存
如果需要同时拿到独立的音频、视频流,直接复用stream字节串分别调用两次ffmpeg即可,逻辑更简单不易出错:
import subprocess from io import BytesIO # 提取音频 audio_command = [ "ffmpeg", '-i', '-', '-acodec', 'pcm_s16le', '-ar', '11025', '-ac', '1', '-vn', '-sn', '-map_metadata', '-1', '-f', 'wav', 'pipe:1' ] audio_result = subprocess.run(audio_command, input=stream, stdout=subprocess.PIPE, check=True) audio_file = BytesIO(audio_result.stdout) # 提取视频(可根据需要调整编码、格式参数) video_command = [ "ffmpeg", '-i', '-', '-vcodec', 'copy', # 不需要转码直接复用原编码时用copy,处理速度更快 '-an', '-sn', '-map_metadata', '-1', '-f', 'mp4', 'pipe:1' # 输出格式可根据你的需求调整 ] video_result = subprocess.run(video_command, input=stream, stdout=subprocess.PIPE, check=True) video_file = BytesIO(video_result.stdout)
内容的提问来源于stack exchange,提问作者vipul petkar
相关产品推荐
相关产品推荐

