使用moviepy提取视频音频生成对数梅尔频谱图遇问题求助
视频片段音频提取对数梅尔频谱图的问题
我有一段长视频,希望截取其中一部分并提取对应片段的对数梅尔频谱图。使用moviepy加载MP4原文件,通过subclip提取目标片段,再用.audio获取该片段的音频。
提取音频数据的代码与结果
with VideoFileClip(input_file) as video: # 截取视频前3秒 clip = video.subclip(0, 3) # 获取音频数据和采样率 y = clip.audio.to_soundarray() sr = clip.audio.fps l = clip.audio.duration print(f'y:{y.shape}, sr:{sr}, length:{l}')
执行结果:
y:(132300, 2), sr:44100, length:3
遇到的问题1:转换频谱图时报错
运行以下代码时出现错误:
with VideoFileClip(input_file) as video: # 截取视频 clip = video.subclip(start_time_sec, end_time_sec) # 获取截取后视频时长 length = end_time_sec-start_time_sec # 获取音频数据和采样率 y = clip.audio.to_soundarray() sr = clip.audio.fps l = clip.audio.duration # 处理音频数据 spectrogram = librosa.feature.melspectrogram(y=y, n_fft=2048, hop_length=512) librosa.display.specshow(spectrogram, sr=sr)
报错信息:
ValueError: For X (129) and Y (132301) with flat shading, A should have shape (132300, 128, 3) or (132300, 128, 4) or (132300, 128) or (16934400,), not (132300, 128, 1)
遇到的问题2:频谱图结果不符合预期
使用power_to_db和plt.imshow运行以下代码:
ps = librosa.feature.melspectrogram(y=y, sr=sr) ps_db= librosa.power_to_db(ps) # librosa.display.specshow(ps_db, x_axis='s', y_axis='log') plt.imshow(ps_db, origin="lower", cmap=plt.get_cmap("magma"))
得到的频谱图不符合预期。
请问这是重叠窗口大小的问题吗?
问题解决与分析
报错原因与解决
报错核心是音频为双声道(形状(132300,2)),而librosa的melspectrogram默认处理单声道数据。传入双声道数据时,返回的频谱图会包含多通道维度,导致specshow无法解析。
解决方法:将双声道转为单声道,比如取均值合并:
y = y.mean(axis=1) # 把(132300,2)转为(132300,)
频谱图不符合预期的原因
用plt.imshow直接显示时,没有匹配梅尔频谱图的维度逻辑:librosa生成的梅尔频谱图ps_db形状是(梅尔频段数, 时间帧数量),而plt.imshow默认轴映射逻辑与频谱图的时间-频率对应关系不符,且未设置自适应宽高比,导致图形变形。
正确处理方式:
- 先转单声道音频
- 使用
librosa.display.specshow显示(自动处理轴映射):import numpy as np import librosa.display import matplotlib.pyplot as plt y = y.mean(axis=1) # 转单声道 ps = librosa.feature.melspectrogram(y=y, sr=sr, n_fft=2048, hop_length=512) ps_db = librosa.power_to_db(ps, ref=np.max) librosa.display.specshow(ps_db, sr=sr, hop_length=512, x_axis='time', y_axis='mel', cmap='magma') plt.colorbar(format='%+2.0f dB') plt.show()
若坚持用plt.imshow,需手动调整参数:
plt.imshow(ps_db, origin='lower', aspect='auto', cmap='magma') plt.xlabel('时间帧') plt.ylabel('梅尔频段') plt.colorbar(format='%+2.0f dB') plt.show()
其中aspect='auto'是避免图形拉伸变形的关键。
关于重叠窗口的问题
你的问题和重叠窗口(由hop_length与n_fft决定)无关,核心是双声道处理错误和频谱图显示的轴映射问题。
内容的提问来源于stack exchange,提问作者David Harar
相关产品推荐
相关产品推荐

