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

双声道MP4转独立单声道WAV:FFmpeg/Python解决方案求助

双声道MP4拆分单声道WAV问题求助

我是音频编码领域新手,想把双声道MP4文件拆成两个独立的单声道WAV文件,每个文件对应一个麦克风采集的音频,方便后续转文本并按声道标记说话人。但用FFmpeg命令和Python代码尝试后,两个文件内容完全一致。附上ffprobe检测结果、之前试的命令和代码,求正确的FFmpeg命令或Python脚本。

FFprobe检测信息

使用的命令:

ffprobe -i Two-Channel.mp4 -show_streams -select_streams a

检测结果:

Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Google
  Duration: 00:52:42.19, start: 0.000000, bitrate: 421 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 640x360 [SAR 1:1 DAR 16:9], 322 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
      Metadata:
        handler_name    : ISO Media file produced by Google Inc.
        vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 96 kb/s (default)
      Metadata:
        handler_name    : ISO Media file produced by Google Inc.
        vendor_id       : [0][0][0][0]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_tag_string=mp4a
codec_tag=0x6134706d
sample_fmt=fltp
sample_rate=44100
channels=2
channel_layout=stereo
bits_per_sample=0
initial_padding=0
id=0x2
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/44100
start_pts=0
start_time=0.000000
duration_ts=139452416
duration=3162.186304
bit_rate=96000
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=136184
nb_read_frames=N/A
nb_read_packets=N/A
extradata_size=16
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
DISPOSITION:non_diegetic=0
DISPOSITION:captions=0
DISPOSITION:descriptions=0
DISPOSITION:metadata=0
DISPOSITION:dependent=0
DISPOSITION:still_image=0
TAG:language=eng
TAG:handler_name=ISO Media file produced by Google Inc.
TAG:vendor_id=[0][0][0][0]
[/STREAM] 

此前尝试的FFmpeg命令

ffmpeg -i Two-Channel.mp4 -filter_complex "pan=mono|c0=0c0" left_channel.wav

此前尝试的Python代码

先通过FFmpeg将MP4转为WAV,之后用Python处理(原代码核心逻辑是读取WAV文件后尝试提取左右声道,但最终输出的两个文件内容完全一致)


正确的解决方案

方案1:直接用FFmpeg拆分声道

提取左声道:

ffmpeg -i Two-Channel.mp4 -map_channel 0.1.0 left_channel.wav

提取右声道:

ffmpeg -i Two-Channel.mp4 -map_channel 0.1.1 right_channel.wav

或者用channelsplit滤镜一次性输出两个文件,效率更高:
ffmpeg -i Two-Channel.mp4 -filter_complex "channelsplit=channel_layout=stereo[left][right]" -map "[left]" left.wav -map "[right]" right.wav

方案2:Python脚本(使用pydub库,简单易用)

先安装依赖:
pip install pydub

脚本代码:

from pydub import AudioSegment

# 加载MP4文件(需确保FFmpeg已添加到系统环境变量)
audio = AudioSegment.from_file("Two-Channel.mp4", format="mp4")

# 拆分左右声道
left_channel = audio.split_to_mono()[0]
right_channel = audio.split_to_mono()[1]

# 保存为单声道WAV文件
left_channel.export("left_channel.wav", format="wav")
right_channel.export("right_channel.wav", format="wav")

方案3:Python脚本(使用标准库,无需第三方依赖)

先通过FFmpeg将MP4转为PCM编码的WAV(避免编码问题):
ffmpeg -i Two-Channel.mp4 -acodec pcm_s16le -ar 44100 -ac 2 temp.wav

然后用标准库wave和struct处理:

import wave
import struct

with wave.open("temp.wav", "rb") as wav_file:
    params = wav_file.getparams()
    nchannels, sampwidth, framerate, nframes = params[:4]
    
    # 读取所有音频帧
    frames = wav_file.readframes(nframes)
    # 将二进制帧转成整数数组
    fmt = "<h" * nframes * nchannels
    samples = struct.unpack(fmt, frames)
    
    # 拆分左右声道:左声道取偶数索引,右声道取奇数索引
    left_samples = samples[0::2]
    right_samples = samples[1::2]
    
    # 保存左声道WAV
    with wave.open("left_channel.wav", "wb") as left_wav:
        left_wav.setparams((1, sampwidth, framerate, nframes, params.compname, params.descrip))
        left_frames = struct.pack("<h" * len(left_samples), *left_samples)
        left_wav.writeframes(left_frames)
    
    # 保存右声道WAV
    with wave.open("right_channel.wav", "wb") as right_wav:
        right_wav.setparams((1, sampwidth, framerate, nframes, params.compname, params.descrip))
        right_frames = struct.pack("<h" * len(right_samples), *right_samples)
        right_wav.writeframes(right_frames)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:42:04