python实现分离不同人声、wespeaker

张开发
2026/5/4 1:03:48 15 分钟阅读
python实现分离不同人声、wespeaker
文章目录方案选型步骤2、代码可用的几个模型其他如果遇到c问题wespeaker下载安装步骤其他文档剪映等工具都支持背景音和人声分离。那么如果想分离不同人声呢?例如想把郭靖和黄蓉的声音分开。方案选型1、本地运行、无需上传 # 上传的不但慢而且大多有限制2、最好是国内的如果需要注册hugging face国内经常连不上所以方案为ffmpegdemucs(Meta/Facebook开发的-人声分离专家)wespeaker(阿里达摩院-声纹识别专家)代码流程你可以把我们的程序想象成一个音频加工厂流程如下1、原料入库(FFmpeg)输入input.mp4(杂乱的视频文件)操作提取音频流-转为标准 WAV 产出input_temp.wav(纯净的音频原料)2、粗加工-分离人声(Demucs)输入input_temp.wav 操作AI 模型分析频谱-剥离背景音乐 产出input_vocals.wav(只有人声的干音)3、精加工-声纹识别(Wespeaker)输入input_vocals.wav 操作 切片检测哪里有人在说话(VAD)。 特征提取给每段话打上“声纹指纹”。 聚类把相同的指纹归为一类比如“说话人 A”、“说话人 B”。 产出speaker_0.wav,speaker_1.wav(按人分好的文件)步骤需要提前装好ffmpeg。1、安装依赖pip install torch torchaudio demucs scipy numpy pydub pip install s3prl pip install openai-whisper pip install pydub注wespeaker国内镜像没有先从git下载master包然后再安装到本地即可。2、代码importosimporttorchimporttorchaudioimportnumpyasnpfromscipy.cluster.hierarchyimportfcluster,linkagefromscipy.spatial.distanceimportpdistimportwarningsimportsubprocess# 过滤警告warnings.filterwarnings(ignore,message.*set_audio_backend.*)# 配置区域 INPUT_FILEinput.mp4# 你的原始 MP4 文件WESPEAKER_MODEL_PATHwespeaker_vox1_en_resnet34.ptOUTPUT_DIRoutput_speakers# print( 正在启动音频分离与声纹识别程序...)# --- 核心修复使用 Pydub/FFmpeg 预处理音频 ---defprepare_audio(input_file): 将任意格式音频转换为 WAV绕过 torchaudio 读取 MP4 的 Bug ifnotos.path.exists(input_file):print(f❌ 找不到输入文件:{input_file})returnNone# 如果已经是 wav直接返回ifinput_file.lower().endswith(.wav):returninput_file output_wavinput_file.rsplit(.,1)[0]_temp.wavprint(f 正在使用 FFmpeg 将{input_file}转换为 WAV...)# 调用系统 FFmpeg# 注意这里直接调用 ffmpeg依赖系统环境变量cmd[ffmpeg,-y,-i,input_file,-vn,# 不处理视频-acodec,pcm_s16le,# 编码为 PCM (WAV)-ar,44100,# 采样率 44100 (Demucs 标准)-ac,2,# 双声道output_wav]try:# 尝试直接运行 ffmpegsubprocess.run(cmd,checkTrue,stdoutsubprocess.PIPE,stderrsubprocess.PIPE)print(f✅ 转换成功:{output_wav})returnoutput_wavexceptsubprocess.CalledProcessErrorase:print(f❌ FFmpeg 转换失败:{e.stderr.decode()})print( 请确保在终端输入 ffmpeg 能直接运行)returnNone# --- 步骤 1: 使用 Demucs 去除背景音乐 ---defstep1_separate_vocals(input_file):print(\n*30)print( [步骤 1] 正在使用 Demucs 去除背景音乐...)print(*30)try:fromdemucs.pretrainedimportget_modelfromdemucs.applyimportapply_modelfromdemucs.audioimportsave_audio# 1. 加载模型modelget_model(htdemucs)# 2. 加载音频waveform,sample_ratetorchaudio.load(input_file)print(f 音频加载完成:{waveform.shape}, 采样率:{sample_rate})# 【关键修复】# demucs 需要 3 维输入: [Batch, Channels, Length]# torchaudio 输出 2 维: [Channels, Length]# 我们需要在第 0 维增加一个 Batch 维度ifwaveform.dim()2:waveformwaveform.unsqueeze(0)print(f 调整后的音频形状:{waveform.shape})# 3. 执行分离print( 正在分离音轨 (这可能需要几分钟)...)# 现在传入 3 维数据就不会报错了outapply_model(model,waveform,devicecpu,splitTrue,overlap0.25)# out 是 [Batch, Sources, Length]取第 0 个 batchsourcesout[0]print(f 分离完成共得到{sources.shape[0]}条音轨)# 4. 提取人声 (通常索引 0 是人声)vocalssources[0]# 5. 保存人声vocals_fileinput_file.rsplit(.,1)[0]_vocals.wavsave_audio(vocals,vocals_file,samplerate44100)print(f✅ 人声提取成功:{vocals_file})returnvocals_fileexceptExceptionase:print(f❌ 步骤 1 失败:{e})importtraceback traceback.print_exc()returnNone# --- 步骤 2: 简单的语音活动检测 ---defsimple_energy_vad(waveform,sample_rate,threshold_ratio0.02,min_duration0.5):ifwaveform.shape[0]1:monowaveform.mean(dim0)else:monowaveform.squeeze()energytorch.abs(mono)max_energyenergy.max()ifmax_energy0:return[]thresholdmax_energy*threshold_ratio maskenergythreshold segments[]start_sample0in_speechFalsefori,is_speechinenumerate(mask):ifis_speechandnotin_speech:start_samplei in_speechTrueelifnotis_speechandin_speech:end_samplei duration(end_sample-start_sample)/sample_rateifdurationmin_duration:segments.append((start_sample,end_sample))in_speechFalsereturnsegments# --- 步骤 3: 声纹聚类 ---defstep2_diarize_speakers(vocals_file,output_dir):print(\n*30)print( [步骤 2] 正在识别说话人...)print(*30)ifnotos.path.exists(WESPEAKER_MODEL_PATH):print(f❌ 找不到模型文件:{WESPEAKER_MODEL_PATH})returnwaveform,sample_ratetorchaudio.load(vocals_file)ifwaveform.shape[0]1:waveformtorch.mean(waveform,dim0,keepdimTrue)print(f⏳ 正在加载 Wespeaker 模型...)try:importwespeaker speaker_modelwespeaker.load_model(WESPEAKER_MODEL_PATH)devicecudaiftorch.cuda.is_available()elsecpuspeaker_model.set_device(device)print(✅ 模型加载成功)exceptExceptionase:print(f❌ 模型加载失败:{e})returnprint( 正在检测语音片段...)segmentssimple_energy_vad(waveform,sample_rate)print(f 检测到{len(segments)}个有效语音片段)iflen(segments)2:print(⚠️ 语音片段太少无法聚类)returnembeddings[]valid_segments[]print( 正在提取声纹特征...)forstart,endinsegments:segment_wavewaveform[:,start:end]embeddingspeaker_model.extract_embedding(segment_wave.numpy())ifembeddingisnotNone:embeddings.append(embedding)valid_segments.append((start,end))iflen(embeddings)2:print(❌ 无法提取足够的声纹特征)returnembeddingsnp.array(embeddings)print( 正在进行聚类分析...)distancespdist(embeddings,metriccosine)Zlinkage(distances,average)labelsfcluster(Z,t0.5,criteriondistance)unique_labelsset(labels)print(f✅ 识别出{len(unique_labels)}位说话人:{list(unique_labels)})os.makedirs(output_dir,exist_okTrue)forlabelinunique_labels:indicesnp.where(labelslabel)[0]longest_segmentNonemax_len0foridxinindices:start,endvalid_segments[idx]durationend-startifdurationmax_len:max_lenduration longest_segmentwaveform[:,start:end]output_pathos.path.join(output_dir,fspeaker_{label}.wav)torchaudio.save(output_path,longest_segment,sample_rate)print(f - 保存:{output_path}(时长:{max_len/sample_rate:.2f}s))# 主程序 if__name____main__:# 1. 预处理MP4 - WAVwav_fileprepare_audio(INPUT_FILE)ifwav_file:# 2. 分离vocals_pathstep1_separate_vocals(wav_file)# 3. 聚类ifvocals_path:step2_diarize_speakers(vocals_path,OUTPUT_DIR)print(\n 全部处理完成)# 可选清理临时文件# os.remove(wav_file)输出结果 正在启动音频分离与声纹识别程序... 正在使用 FFmpeg 将input.mp4 转换为 WAV...✅ 转换成功:input_temp.wav[步骤1]正在使用 Demucs 去除背景音乐...Downloading:https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/955717e8-8726e21a.thto C:\Users\user/.cache\torch\hub\checkpoints\955717e8-8726e21a.th100%|██████████|80.2M/80.2M[00:1500:00,5.29MB/s] 音频加载完成:torch.Size([2,13218240]),采样率:44100 调整后的音频形状:torch.Size([1,2,13218240]) 正在分离音轨(这可能需要几分钟)... 分离完成共得到4条音轨 ✅ 人声提取成功:input_temp_vocals.wav[步骤2]正在识别说话人...❌ 找不到模型文件:wespeaker_vox1_en_resnet34.pt 全部处理完成果然成功了效果还不错就是优点慢。可用的几个模型mdx_extra效果最好速度最慢龟速。htdemucs_ft效果不错速度中等推荐。htdemucs效果一般速度很快。其他如果遇到c问题安装visual studio装下wespeaker下载安装步骤1、下文git地址下载master分支zip包。2、pycharm所在虚拟环境中执行安装命令D:/PycharmProjects/transformer_demo/.venv/Scripts/python.exe-m install安装包路径其他文档wespeaker官网git地址(这里下载的master分支可以pip install成功)https://github.com/wenet-e2e/wespeaker

更多文章