无法将含音频的BytesIO正确传入AudioSegment.from_file的问题
PyTube + BytesIO 转MP3解码错误解决办法
问题场景
使用PyTube下载YouTube音频文件,尝试通过BytesIO流转码为MP3时,AudioSegment.from_file执行失败,触发FFmpeg解码错误。
原始代码
yt = YouTube(youtube_link) # Download file audio = yt.streams.filter(only_audio=True).first() audio_bytes = io.BytesIO() print('Getting audio bytes') audio.stream_to_buffer(audio_bytes) print('Converting format') sound = AudioSegment.from_file(file=audio_bytes).export(io.BytesIO(), 'mp3') return dcc.send_bytes(sound.getvalue(), f'{yt.streams[0].title}.mp3')
错误信息
raise CouldntDecodeError( pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1 Output from ffmpeg/avlib: ffmpeg version 2022-07-04-git-dba7376d59-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers built with gcc 12.1.0 (Rev2, Built by MSYS2 project) configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint libavutil 57. 27.100 / 57. 27.100 libavcodec 59. 36.100 / 59. 36.100 libavformat 59. 26.100 / 59. 26.100 libavdevice 59. 6.100 / 59. 6.100 libavfilter 8. 41.100 / 8. 41.100 libswscale 6. 6.100 / 6. 6.100 libswresample 4. 6.100 / 4. 6.100 libpostproc 56. 5.100 / 56. 5.100 [cache @ 0000022fcb016200] Statistics, cache hits:0 cache misses:0 cache:pipe:0: Invalid data found when processing input
解决办法
核心原因
audio.stream_to_buffer(audio_bytes)执行后,BytesIO的文件指针停留在缓冲区末尾,AudioSegment.from_file读取时从末尾开始,无法获取有效音频数据,导致FFmpeg解码失败。
修复步骤
- 在调用
AudioSegment.from_file前,重置BytesIO指针到起始位置:audio_bytes.seek(0) - 可选但推荐:明确指定音频格式(PyTube下载的音频通常为mp4或webm),帮助FFmpeg精准识别解码格式:
audio_format = audio.mime_type.split('/')[-1]
完整修复代码
import io from pytube import YouTube from pydub import AudioSegment import dash_core_components as dcc def download_convert_yt_audio(youtube_link): yt = YouTube(youtube_link) # 筛选仅音频流 audio = yt.streams.filter(only_audio=True).first() audio_bytes = io.BytesIO() print('Getting audio bytes') audio.stream_to_buffer(audio_bytes) # 重置缓冲区指针到起始位置 audio_bytes.seek(0) print('Converting format') # 获取音频格式,辅助FFmpeg解码 audio_format = audio.mime_type.split('/')[-1] sound_segment = AudioSegment.from_file(file=audio_bytes, format=audio_format) mp3_buffer = io.BytesIO() sound_segment.export(mp3_buffer, format='mp3') mp3_buffer.seek(0) return dcc.send_bytes(mp3_buffer.getvalue(), f'{yt.title}.mp3')
额外注意事项
- 确保FFmpeg已正确安装并添加至系统环境变量,pydub依赖FFmpeg完成格式转换
- 若仍存在解码问题,可手动指定FFmpeg路径:
AudioSegment.converter = "你的FFmpeg可执行文件路径"
内容的提问来源于stack exchange,提问作者Gus Montano
相关产品推荐
相关产品推荐

