如何无需写入本地文件,将YouTube音频流直接转为语音可识别格式?
问题
我原本使用以下代码转录YouTube视频的音频流:
from pytube import YouTube import speech_recognition as sr from moviepy.editor import * video = YouTube(url=link) audio_stream = video.streams.get_by_itag(140) recognizer = sr.Recognizer() audio_stream.download(filename="mp4_output.mp4") audio = AudioFileClip("mp4_output.mp4") audio.write_audiofile("wav_output.wav") with sr.AudioFile("./wav_output.wav") as audio_file: audio_data = recognizer.record(audio_file, duration=100) transcript = recognizer.recognize_sphinx(audio_data=audio_data)
但该流程需要先下载MP4文件再转换为WAV格式,效率较低。我尝试直接将流写入缓冲区处理,代码如下:
from pytube import YouTube import speech_recognition as sr video = YouTube(url=link) audio_stream = video.streams.get_by_itag(140) buffer = io.BytesIO() audio_stream.stream_to_buffer(buffer) recognizer = sr.Recognizer() with sr.AudioFile(buffer) as audio_file: audio_data = recognizer.record(audio_file, duration=100) transcript = recognizer.recognize_sphinx(audio_data=audio_data)
运行后出现报错:audio file could not be read as PCM WAV, AIFF/AIFF-C, or Native FLAC; check if file is corrupted or in another format,请问如何将缓冲区中的内容转换为支持的格式?
解决方案
报错的核心原因是:stream_to_buffer写入缓冲区的是MP4封装的音频数据,而speech_recognition的AudioFile仅支持PCM WAV、AIFF/AIFF-C或原生FLAC格式。要在内存中完成格式转换,无需落地文件,可采用以下两种方法:
方法1:使用moviepy处理内存缓冲区
通过两个BytesIO缓冲区分别存储MP4源数据和转换后的WAV数据,全程在内存中完成格式转换:
from pytube import YouTube import speech_recognition as sr from moviepy.editor import AudioFileClip import io # 获取YouTube音频流并写入MP4缓冲区 video = YouTube(url=link) audio_stream = video.streams.get_by_itag(140) mp4_buffer = io.BytesIO() audio_stream.stream_to_buffer(mp4_buffer) mp4_buffer.seek(0) # 重置缓冲区指针至起始位置 # 将MP4转换为WAV并写入新缓冲区 wav_buffer = io.BytesIO() with AudioFileClip(mp4_buffer) as audio_clip: audio_clip.write_audiofile(wav_buffer, codec='pcm_s16le') wav_buffer.seek(0) # 重置WAV缓冲区指针 # 执行语音识别 recognizer = sr.Recognizer() with sr.AudioFile(wav_buffer) as audio_file: audio_data = recognizer.record(audio_file, duration=100) transcript = recognizer.recognize_sphinx(audio_data=audio_data) print(transcript)
方法2:使用ffmpeg-python直接内存转码(更高效)
若本地已安装ffmpeg环境,使用ffmpeg-python可实现更高效的内存转码,避免moviepy的额外封装开销:
from pytube import YouTube import speech_recognition as sr import io import ffmpeg # 获取YouTube音频流的MP4字节数据 video = YouTube(url=link) audio_stream = video.streams.get_by_itag(140) mp4_buffer = io.BytesIO() audio_stream.stream_to_buffer(mp4_buffer) mp4_buffer.seek(0) # 用ffmpeg在内存中将MP4转码为WAV process = ( ffmpeg .input('pipe:', format='mp4') .output('pipe:', format='wav', acodec='pcm_s16le') .run_async(pipe_stdin=True, pipe_stdout=True) ) wav_data, _ = process.communicate(input=mp4_buffer.getvalue()) wav_buffer = io.BytesIO(wav_data) wav_buffer.seek(0) # 执行语音识别 recognizer = sr.Recognizer() with sr.AudioFile(wav_buffer) as audio_file: audio_data = recognizer.record(audio_file, duration=100) transcript = recognizer.recognize_sphinx(audio_data=audio_data) print(transcript)
关键注意点
- 每次写入缓冲区后必须调用
seek(0),否则后续读取操作会从缓冲区末尾开始,导致读取空数据。 - 使用moviepy需确保已安装
moviepy包;使用ffmpeg-python需安装ffmpeg-python包,且本地环境配置了ffmpeg可执行文件。
内容的提问来源于stack exchange,提问作者cdt123
相关产品推荐
相关产品推荐

