在上一篇文章,我们写了一个小小的打飞机demo,感受到了Trae的牛逼的代码逻辑。 现在我们只做了飞机的画面。还有打飞机的声音呢,能不能从视频网站自动下载并生成mp3文件呢?ok,说干就干。
去B站逛了一下,发现有热心网友已经把我喜欢的"加纳战机"小游戏的视频文件传上去了。可惜是视频。
那么我们的需求就是这样了:
- 用Trae写个python脚本,自动从Bilibli网站下载"加纳战机"的影片,保存成mp4格式。
- 自动把mp4文件转换成mp3文件。
提示词给Trae: 帮我写个python脚本,从B站下载视频保存成mp4格式,并把这个mp4文件转换成mp3格式文件:
python
import yt_dlp
import os
import sys
import moviepy as mp
import logging
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 配置选项
DEFAULT_FORMAT = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'
# 修改 download_and_convert 函数以使用配置选项
def download_and_convert(url, output_dir="."):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 配置yt-dlp下载选项
ydl_opts = {
'format': DEFAULT_FORMAT, # 使用配置选项
'outtmpl': os.path.join(output_dir, '%(title)s.%(ext)s'),
}
try:
# 下载视频
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
if 'entries' in info:
# 处理多个视频的情况
for entry in info['entries']:
if entry is not None:
video_title = entry.get('title', 'unknown_title')
video_ext = entry.get('ext', 'mp4')
video_file = f"{video_title}.{video_ext}"
video_path = os.path.join(output_dir, video_file)
try:
ydl.download([entry['webpage_url']])
if os.path.exists(video_path) and os.access(video_path, os.R_OK):
video = mp.VideoFileClip(video_path)
audio = video.audio
audio_path = os.path.join(output_dir, f"{video_title}.mp3")
audio.write_audiofile(audio_path)
logging.info(f'已生成音频文件: {audio_path}')
else:
logging.error(f'无法访问视频文件: {video_path}')
except Exception as e:
logging.error(f'处理视频 {video_title} 时出错: {str(e)}')
else:
# 处理单个视频的情况
video_title = info.get('title', 'unknown_title')
video_ext = info.get('ext', 'mp4')
video_file = f"{video_title}.{video_ext}"
video_path = os.path.join(output_dir, video_file)
ydl.download([url])
if os.path.exists(video_path) and os.access(video_path, os.R_OK):
video = mp.VideoFileClip(video_path)
audio = video.audio
audio_path = os.path.join(output_dir, f"{video_title}.mp3")
audio.write_audiofile(audio_path)
logging.info(f'已生成音频文件: {audio_path}')
else:
logging.error(f'无法访问视频文件: {video_path}')
except Exception as e:
logging.error(f'处理过程中出错: {str(e)}')
if __name__ == "__main__":
if len(sys.argv) < 2:
print("使用方法: python bilibili_downloader.py <B站视频URL> [输出目录]")
sys.exit(1)
url = sys.argv[1]
output_dir = sys.argv[2] if len(sys.argv) > 2 else "downloads"
download_and_convert(url, output_dir)
ok,下载的mp3,mp4文件如下:
其实中间也是报了不少错了的。比如提示:
python
python .\bilibili_downloader.py https://www.bilibili.com/video/BV1cZ4y1x7k4 downloads
Traceback (most recent call last):
File "C:\Users\EDY\AppData\Local\Programs\Python\Python313\Lib\site-packages\pydub\utils.py", line 14, in <module>
import audioop
ModuleNotFoundError: No module named 'audioop'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\EDY\workspace\traeproject\fly\bilibili_downloader.py", line 2, in <module>
from pydub import AudioSegment
File "C:\Users\EDY\AppData\Local\Programs\Python\Python313\Lib\site-packages\pydub\__init__.py", line 1, in
<module>
from .audio_segment import AudioSegment
File "C:\Users\EDY\AppData\Local\Programs\Python\Python313\Lib\site-packages\pydub\audio_segment.py", line 11, in <module>
from .utils import mediainfo_json, fsdecode
File "C:\Users\EDY\AppData\Local\Programs\Python\Python313\Lib\site-packages\pydub\utils.py", line 16, in <module>
import pyaudioop as audioop
ModuleNotFoundError: No module named 'pyaudioop'
中间还是需要手动操作一些东西的: 比如这个错误后,让用mp.VideoFileClip(video_path)
方法。需要下载 'ffmpeg-2025-03-17-git-5b9356f18e-full_build'并配置环境变量。
比如他用 moviepy.editor 模块,没找到,我也问了腾讯元宝半天,发现,直接用moviepy就可以了。
比如他一开始用 yt_dlp.YoutubeDL()
方法下载mp4,其实可以一次性把链接中的多个视频都下载下载。那就没办法一个个mp4文件转mp3了,因为默认就是一个mp4.我这么提示:
shell
给的下载链接是一个包含多个mp4的链接,所以需要调整一下代码逻辑,所以调用yt_dlp.YoutubeDL方法下载了多个,处理一下这种情况。
他就帮我把代码改成上面的一个个处理mp4,然后转mp3了。
ok,下载的文件依然给大家分享链接。 上面的python代码,大家也可以跑一跑,改成别的什么音乐链接。
加纳战机bgm:pan.baidu.com/s/1wdTOuiUJ... 提取码: qtgx