如何在 YouTube Music 下载歌曲

今天学到用 yt-dlp 下载 YouTube Music 歌曲的方法。该方法来自文章「嗯,我还是喜欢下载mp3」。
原文章写得比较简略,针对有一定计算机基础人士。我在 Google Gemini 帮助下,终于搞懂完整过程,怕自己忘记,现记录如下:
首先,安装 yt-dlp。
brew install yt-dlp
接着,需要安装依赖 FFmpeg(第一次因为没有安装这个依赖,导致转换mp3错误)。
brew install ffmpeg
最后,在终端执行如下指令:
yt-dlp -x --audio-format mp3 \
--audio-quality 0 \
--embed-metadata --embed-thumbnail \
--postprocessor-args "ExtractAudio:-q:a 0 -id3v2_version 3" \
--postprocessor-args "FFmpegMetadata:-metadata comment=YouTubeID=%(id)s" \
-o "%(artist,uploader)s-%(track,title)s.%(ext)s" \
'https://music.youtube.com/playlist?list=PLJQHrLUqwS07gskhUSN5akj_2fbs3oIvz'实现原码率下载 mp3,如果有视频则忽略视频只保留音频,并将视频的元数据(如标题、艺术家、发布者等)作为 ID3 标签嵌入到最终的 MP3 文件中,完美。
上面命令第7行 “https://music.youtube.com/playlist?list=PLJQHrLUqwS07gskhUSN5akj_2fbs3oIvz' Music " YouTube Music 播放列表地址,可以替换成自己的播放列表地址,下载相应歌曲。
以上是使用 Mac OS 执行成功,其他如Linux、Windows 等系统方法类似,仅供参考。
原作者还给出如何给已下载歌曲配上歌词的方法:原理是在 mp3 文件里,基本上已包含“不带时间轴”的歌词,但存在 user_text_frames 字段的 description 里,而 Music.app 只认 USLT 这个 frame,于是利用 Python 语言一段代码实现歌词匹配。代码如下:
import sys
import os
import eyed3
from eyed3.id3.frames import LyricsFrame, LYRICS_FID
def process_file(file_path):
"""处理单个 MP3 文件,将 description 字段的内容复制到 USLT 帧"""
file_name = os.path.basename(file_path)
try:
# 1. 加载音频文件
audio = eyed3.load(file_path)
if audio is None:
print(f"{file_name}: ❌ 无法加载文件")
return False
tag = audio.tag
if tag is None:
print(f"{file_name}: ⚠️ 没有 ID3 标签,跳过")
return False
# 2. 查找 description 字段中的歌词内容
lyrics_text = None
for frame in tag.user_text_frames:
if frame.description == "description":
if isinstance(frame.text, list):
lyrics_text = "\n".join(frame.text)
else:
lyrics_text = str(frame.text)
break
if not lyrics_text:
print(f"{file_name}: ⚠️ 未找到名为 'description' 的文本字段")
return False
# 3. 写入 USLT 帧(苹果音乐/Music App 识别的歌词格式)
# 先清除已有的 USLT 帧以防冲突
if tag.frame_set:
frames_to_remove = [fid for fid in tag.frame_set.keys() if fid == LYRICS_FID]
for fid in frames_to_remove:
del tag.frame_set[fid]
# 创建新歌词帧:lang='chi' 代表中文,description为空是兼容性最好的做法
uslt_frame = LyricsFrame(text=lyrics_text, description="", lang=b"chi")
tag.frame_set[LYRICS_FID] = uslt_frame
# 保存为 ID3 v2.3 版本,这是兼容性最好的版本
tag.save(version=eyed3.id3.ID3_V2_3)
print(f"{file_name}: ✅ 成功写入歌词 ({len(lyrics_text)} 字符)")
return True
except Exception as e:
print(f"{file_name}: ❌ 发生错误 - {str(e)}")
return False
# 主程序入口
if __name__ == "__main__":
# 获取命令行参数(排除脚本名本身)
input_files = sys.argv[1:]
if not input_files:
print("用法: python3 edit-ly.py <mp3文件路径或通配符>")
print("示例: python3 edit-ly.py ~/Downloads/*.mp3")
sys.exit(1)
print(f"开始处理 {len(input_files)} 个文件...")
print("-" * 30)
success = 0
fail = 0
for path in input_files:
if process_file(path):
success += 1
else:
fail += 1
print("-" * 30)
print(f"处理完成!成功: {success}, 失败: {fail}")将上面代码拷贝存为文件 edit-ly.py, 在终端输入以下命令行,实现歌词转换。
python3 edit-ly.py ~/Downloads/liubin-song/*.mp3