技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
ytmusic-hub【数据与研究】Read and write YouTube Music data using Python + ytmusicapi, authenticated via browser cookies obtained automatically with browser_use get_cookies — no manual copying required. Supports fetching playlists, liked songs, playlist details, creating/editing/deleting playlists, searching and adding songs, recommendations, charts, and lyrics. Trigger this …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Interact with YouTube Music using the ytmusicapi library, authenticated via browser cookies. Supports full playlist management, search, liked songs, and more.
pip install ytmusicapi
/var/minis/workspace/ytmusic_headers.json
Two steps: get cookies → generate auth file.
Navigate to YouTube Music and get cookies via browser_use:
browser_use navigate: https://music.youtube.com
browser_use get_cookies -> save env file path
Confirm the page is logged in (avatar visible in top-right), then call get_cookies and note the env file path.
Load the env file and run the auth setup script:
. /var/minis/offloads/env_cookies_youtube_com_xxx.sh
python3 /var/minis/skills/ytmusic-hub/scripts/setup_auth.py
The script reads all Cookie env vars and writes a browser-auth file with SAPISIDHASH to /var/minis/workspace/ytmusic_headers.json.
Use the unified client module — it automatically handles DNS pollution and SSL issues:
import sys
sys.path.insert(0, "/var/minis/skills/ytmusic-hub/scripts")
from ytmusic_client import get_client
yt = get_client()
get_client() will automatically:
socket.getaddrinfoRuntimeError with a clear message# Get all my playlists
playlists = yt.get_library_playlists(limit=25)
# Returns: [{playlistId, title, count, ...}, ...]
# Get playlist contents (all tracks)
playlist = yt.get_playlist(playlistId, limit=100)
# Returns: {title, description, trackCount, tracks: [{videoId, title, artists, ...}]}
# Create a new playlist
playlistId = yt.create_playlist(
title="Playlist name",
description="Description",
privacy_status="PRIVATE" # PUBLIC / PRIVATE / UNLISTED
)
# Edit playlist metadata
yt.edit_playlist(playlistId, title="New name", description="New description")
# Delete a playlist
yt.delete_playlist(playlistId)
# Add songs to a playlist
yt.add_playlist_items(playlistId, videoIds=["videoId1", "videoId2"])
# Remove songs from a playlist
# setVideoId is the track's unique ID within the playlist (different from videoId)
tracks = yt.get_playlist(playlistId)["tracks"]
yt.remove_playlist_items(playlistId, tracks=[
{"videoId": t["videoId"], "setVideoId": t["setVideoId"]}
for t in tracks if t["title"] == "Target song"
])
# Get liked songs
liked = yt.get_liked_songs(limit=100)
tracks = liked["tracks"] # [{videoId, title, artists, album, ...}]
# Get library songs / albums / artists
songs = yt.get_library_songs(limit=25)
albums = yt.get_library_albums(limit=25)
artists = yt.get_library_artists(limit=25)
# Like / unlike a song
yt.rate_song(videoId, "LIKE") # LIKE / DISLIKE / INDIFFERENT
# General search (mixed results)
results = yt.search("Jay Chou")
# Filter by type
songs = yt.search("Jay Chou", filter="songs")
videos = yt.search("Jay Chou", filter="videos")
albums = yt.search("Jay Chou", filter="albums")
artists = yt.search("Jay Chou", filter="artists")
# Get videoId for adding to playlist
videoId = songs[0]["videoId"]
# Home feed
home = yt.get_home()
# Charts (global or by country)
charts = yt.get_charts(country="US") # TW / HK / CN / JP / KR etc.
# Mood playlists
moods = yt.get_mood_categories()
mood_playlists = yt.get_mood_playlists(params=moods["Moods & moments"][0]["params"])
# Lyrics
watch = yt.get_watch_playlist(videoId="videoId")
lyrics_id = watch.get("lyrics")
if lyrics_id:
lyrics = yt.get_lyrics(lyrics_id)
print(lyrics["lyrics"])
artist = yt.get_artist(channelId)
album = yt.get_album(browseId)
user = yt.get_user(channelId)
user_playlists = yt.get_user_playlists(channelId, params)
results = yt.search("Gao Wu Ren - Love Missed", filter="songs")
videoId = results[0]["videoId"]
playlists = yt.get_library_playlists()
for i, pl in enumerate(playlists):
print(f"{i+1}. {pl['title']} [{pl['playlistId']}]")
yt.add_playlist_items(playlistId, videoIds=[videoId])
print("✅ Added to playlist")
new_id = yt.create_playlist("My Favorites", "Picked from liked songs", "PRIVATE")
liked = yt.get_liked_songs(limit=50)
ids = [t["videoId"] for t in liked["tracks"][:20]]
yt.add_playlist_items(new_id, videoIds=ids)
print(f"✅ Created playlist with {len(ids)} songs")
playlist = yt.get_playlist(playlistId, limit=200)
lines = [f"# {playlist['title']}", f"> {playlist.get('description', '')}", ""]
for i, t in enumerate(playlist["tracks"], 1):
artists = ", ".join(a["name"] for a in t.get("artists", []))
lines.append(f"{i}. **{t['title']}** — {artists}")
print("\n".join(lines))
ytmusic_headers.json contains login credentials — do not share it.music.youtube.com. The client module handles DNS pollution and SSL issues automatically.setVideoId (the track's position-specific ID), not videoId.