本篇文章将介绍一段用于分析音频文件特征的代码。在介绍过程中,我们将分析代码的功能、实现方式,并对关键代码进行解释。
在多媒体处理中,音频分析是一项重要任务。通过分析音频文件中的特征,如响度、基频、音调等,我们可以对音频内容进行更深入的理解和处理。本代码的需求是从音频文件中提取关键特征,并将结果保存为CSV文件。
本代码主要实现了以下功能:
为了读取音频文件,我们使用了 pydub 库的 AudioSegment 类。此外,我们还需要获取音频的采样率。以下是读取音频文件的关键代码:
pydub
AudioSegment
def load_audio_file(file_path): audio = AudioSegment.from_file(file_path) audio_samples = audio.get_array_of_samples() audio_samples = np.array(audio_samples, dtype=np.float32) return audio_samples, audio.frame_rate
我们使用 librosa 库来计算音频文件的关键特征。以下是计算各种特征的关键代码:
librosa
# 计算响度 loudness = librosa.feature.rms(y=audio_samples, frame_length=n_fft, hop_length=hop_length) # 计算基频 pitches, _ = librosa.piptrack(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算音调 chroma = librosa.feature.chroma_stft(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算MFCC mfcc = librosa.feature.mfcc(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算谱质心 spectral_centroid = librosa.feature.spectral_centroid(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算谱衰减 spectral_rolloff = librosa.feature.spectral_rolloff(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算零交叉率 zero_crossing_rate = librosa.feature.zero_crossing_rate(y=audio_samples, frame_length=n_fft, hop_length=hop_length)
将计算得到的各种特征数据整合为 pandas 数据框,然后将数据框合并,并将合并后的数据框保存为CSV文件。
pandas
data_df = pd.concat([loudness_df, pitch_df, chroma_df, mfcc_df, spectral_centroid_df, spectral_rolloff_df, zero_crossing_rate_df], axis=1) data_df.to_csv('/Volumes/SSD/Data_demo/video/{}/{}_sound_1fps.csv'.format(bvid, bvid), index=True)
在使用本代码时,请确保已经安装了所需的第三方库,如 numpy 、 pandas 、 pydub 和 librosa 。另外,请确保音频文件路径和CSV文件保存路径与实际情况相符。
numpy
以下是本文介绍的完整代码:
import numpy as np import pandas as pd from pydub import AudioSegment import librosa from tqdm import tqdm import os def load_audio_file(file_path): audio = AudioSegment.from_file(file_path) audio_samples = audio.get_array_of_samples() audio_samples = np.array(audio_samples, dtype=np.float32) return audio_samples, audio.frame_rate def analyze_audio(audio_samples, frame_rate, bvid): # 设置参数 FRAMES = 1 hop_length = int(round(frame_rate / FRAMES)) # 计算每秒30帧所需的hop_length n_fft = 2048 # 计算响度 loudness = librosa.feature.rms(y=audio_samples, frame_length=n_fft, hop_length=hop_length) # 计算基频 pitches, _ = librosa.piptrack(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算音调 chroma = librosa.feature.chroma_stft(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算MFCC mfcc = librosa.feature.mfcc(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算谱质心 spectral_centroid = librosa.feature.spectral_centroid(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算谱衰减 spectral_rolloff = librosa.feature.spectral_rolloff(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length) # 计算零交叉率 zero_crossing_rate = librosa.feature.zero_crossing_rate(y=audio_samples, frame_length=n_fft, hop_length=hop_length) # 创建数据序列 data = { 'loudness': loudness[0], 'pitch': pitches, 'chroma': chroma, 'mfcc': mfcc, 'spectral_centroid': spectral_centroid[0], 'spectral_rolloff': spectral_rolloff[0], 'zero_crossing_rate': zero_crossing_rate[0] # 将数据序列保存到CSV文件 loudness_df = pd.DataFrame(loudness.T, columns=['loudness']) pitch_df = pd.DataFrame(pitches.T, columns=[f'pitch_{i}' for i in range(pitches.shape[0])]) chroma_df = pd.DataFrame(chroma.T, columns=[f'chroma_{i}' for i in range(chroma.shape[0])]) mfcc_df = pd.DataFrame(mfcc.T, columns=[f'mfcc_{i}' for i in range(mfcc.shape[0])]) spectral_centroid_df = pd.DataFrame(spectral_centroid.T, columns=['spectral_centroid']) spectral_rolloff_df = pd.DataFrame(spectral_rolloff.T, columns=['spectral_rolloff']) zero_crossing_rate_df = pd.DataFrame(zero_crossing_rate.T, columns=['zero_crossing_rate']) data_df = pd.concat( [loudness_df, pitch_df, chroma_df, mfcc_df, spectral_centroid_df, spectral_rolloff_df, zero_crossing_rate_df], axis=1) data_df.to_csv('/Volumes/SSD/Data_demo/video/{}/{}_sound_1fps.csv'.format(bvid, bvid), index=True) if __name__ == "__main__": # 读取csv中的bvid、cid video_list = pd.read_csv('/Volumes/SSD/Data/getVideoinfo/getVideoinfo_byhot_1.csv') bvid_list = video_list['bvid'].values.tolist() cid_list = video_list['cid'].values.tolist()