youtube-to-bookplayer

youtube-to-bookplayer

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "youtube-to-bookplayer" with this command: npx skills add terrylica/cc-skills/terrylica-cc-skills-youtube-to-bookplayer

youtube-to-bookplayer

Download audio from a YouTube video, tag metadata, and push to BookPlayer on iPhone via USB.

BookPlayer is an iOS audiobook player that resumes playback position — ideal for long-form YouTube content (lectures, audiobooks, podcasts). Files pushed to its /Documents/ directory are auto-imported on next app launch.

Task Template

Execute phases 0–5 sequentially. Each phase has a [Preflight] , [Ask] , [Execute] , or [Verify] tag indicating its nature. Do not skip phases.

Phase 0: Preflight [Preflight]

Check all required tools and device connectivity. Fail fast — do not proceed if any check fails.

Tool availability

TOOLS_OK=true for tool in yt-dlp ffmpeg exiftool; do if command -v "$tool" &>/dev/null; then echo "$tool: OK ($(command -v "$tool"))" else echo "$tool: MISSING" TOOLS_OK=false fi done

pymobiledevice3 (may only be available via uvx)

if command -v pymobiledevice3 &>/dev/null; then echo "pymobiledevice3: OK ($(command -v pymobiledevice3))" else if uvx --python 3.13 --from pymobiledevice3 pymobiledevice3 --help &>/dev/null 2>&1; then echo "pymobiledevice3: OK (via uvx)" else echo "pymobiledevice3: MISSING" TOOLS_OK=false fi fi

echo "---" [ "$TOOLS_OK" = true ] && echo "All tools OK" || echo "BLOCKED: Install missing tools (see table below)"

If tools are missing:

Tool Install Command

yt-dlp

brew install yt-dlp

ffmpeg

brew install ffmpeg

exiftool

brew install exiftool

pymobiledevice3

uvx --python 3.13 --from pymobiledevice3 pymobiledevice3 --help

Device check (only after tools pass):

Check for connected iOS device

pymobiledevice3 usbmux list 2>/dev/null || uvx --python 3.13 --from pymobiledevice3 pymobiledevice3 usbmux list

Check BookPlayer is installed

pymobiledevice3 apps list --no-color 2>/dev/null | grep -i "audiobookplayer|bookplayer" ||
uvx --python 3.13 --from pymobiledevice3 pymobiledevice3 apps list --no-color 2>/dev/null | grep -i "audiobookplayer|bookplayer"

If no device found: ask user to connect iPhone via USB, unlock it, and tap "Trust This Computer". If BookPlayer not found: ask user to install BookPlayer from the App Store.

Phase 1: Accept URL & Confirm [Ask]

If $ARGUMENTS[0] is provided, use it as the YouTube URL. Otherwise, use AskUserQuestion to ask for the URL.

Preview metadata before proceeding:

yt-dlp --dump-json --no-download "$URL" 2>/dev/null | python3 -c " import json, sys d = json.load(sys.stdin) hrs, rem = divmod(int(d.get('duration', 0)), 3600) mins, secs = divmod(rem, 60) print(f"Title: {d.get('title', 'Unknown')}") print(f"Channel: {d.get('channel', 'Unknown')}") print(f"Duration: {hrs}h {mins}m {secs}s") print(f"Upload: {d.get('upload_date', 'Unknown')}") "

Use AskUserQuestion to confirm:

  • Title, channel, duration look correct

  • Whether to customize the metadata (title/artist/album) or use defaults from yt-dlp

Phase 2: Download Audio [Execute]

WORK_DIR=$(mktemp -d) echo "Working directory: $WORK_DIR"

yt-dlp -x --audio-format m4a --audio-quality 0 --no-playlist
-o "$WORK_DIR/%(title).100B.%(ext)s"
"$URL"

Show result

ls -lh "$WORK_DIR"/*.m4a

Notes:

  • --audio-quality 0 = best available quality

  • %(title).100B truncates filename to 100 bytes (prevents filesystem issues)

  • --no-playlist ensures single video download even from playlist URLs

  • ffmpeg is auto-invoked by yt-dlp for M4A conversion

Phase 3: Tag Metadata [Execute]

Extract metadata from yt-dlp JSON and apply to the M4A file:

Get the downloaded file path

M4A_FILE=$(ls "$WORK_DIR"/*.m4a | head -1)

Apply metadata (use values confirmed in Phase 1, or yt-dlp defaults)

exiftool -overwrite_original
-Title="$TITLE"
-Artist="$ARTIST"
-Album="YouTube Audio"
"$M4A_FILE"

Verify tags

exiftool -Title -Artist -Album "$M4A_FILE"

Variables (from Phase 1 confirmation):

  • $TITLE — Video title (or user-customized)

  • $ARTIST — Channel name (or user-customized)

  • Album defaults to "YouTube Audio" unless user specifies otherwise

Phase 4: Push to BookPlayer [Execute]

CRITICAL: Use the Python API with documents_only=True . The CLI pymobiledevice3 apps push uses VendContainer mode and will not work with BookPlayer.

M4A_FILE=$(ls "$WORK_DIR"/*.m4a | head -1) FILENAME=$(basename "$M4A_FILE")

uvx --python 3.13 --from pymobiledevice3 python3 << 'PYEOF' import sys from pathlib import Path from pymobiledevice3.lockdown import create_using_usbmux from pymobiledevice3.services.house_arrest import HouseArrestService

local_path = sys.argv[1] if len(sys.argv) > 1 else None if not local_path: # Find the m4a file from environment import glob, os work_dir = os.environ.get("WORK_DIR", "/tmp") files = glob.glob(os.path.join(work_dir, "*.m4a")) if not files: print("ERROR: No .m4a file found in work directory") sys.exit(1) local_path = files[0]

file_path = Path(local_path) filename = file_path.name file_data = file_path.read_bytes() size_mb = len(file_data) / (1024 * 1024)

print(f"Pushing: {filename} ({size_mb:.1f} MB)")

lockdown = create_using_usbmux() service = HouseArrestService( lockdown=lockdown, bundle_id="com.tortugapower.audiobookplayer", documents_only=True # CRITICAL: VendDocuments mode )

service.set_file_contents(f"/Documents/{filename}", file_data) print(f"SUCCESS: {filename} pushed to BookPlayer /Documents/") PYEOF

Anti-pattern — DO NOT USE:

WRONG: This uses VendContainer mode and fails silently on BookPlayer

pymobiledevice3 apps push com.tortugapower.audiobookplayer /path/to/file.m4a

Phase 5: Verify [Verify]

List BookPlayer's /Documents/ directory to confirm the file arrived:

uvx --python 3.13 --from pymobiledevice3 python3 << 'PYEOF' from pymobiledevice3.lockdown import create_using_usbmux from pymobiledevice3.services.house_arrest import HouseArrestService

lockdown = create_using_usbmux() service = HouseArrestService( lockdown=lockdown, bundle_id="com.tortugapower.audiobookplayer", documents_only=True )

files = service.listdir("/Documents/") print("BookPlayer /Documents/ contents:") for f in sorted(files): if f.startswith('.'): continue try: info = service.stat(f"/Documents/{f}") size_mb = info.get('st_size', 0) / (1024 * 1024) print(f" {f} ({size_mb:.1f} MB)") except Exception: print(f" {f}") PYEOF

Report to user:

  • File name and size in BookPlayer

  • Duration (from Phase 1 metadata)

  • Remind: open BookPlayer on iPhone to see the new file (force-quit and reopen if it doesn't appear)

Cleanup:

Remove temp working directory

rm -rf "$WORK_DIR" echo "Cleaned up: $WORK_DIR"

Troubleshooting Quick Reference

Problem Quick Fix

No device found Unlock iPhone, re-plug USB, tap "Trust"

File not in BookPlayer You used the CLI — must use Python API with documents_only=True

Wrong metadata shown Re-run Phase 3 with correct -Title /-Artist values

Full troubleshooting: references/troubleshooting.md

References

  • Tool Reference — yt-dlp flags, pymobiledevice3 API, exiftool tags

  • Troubleshooting — Known issues, diagnostic commands

  • Evolution Log — Origin and key discoveries

Post-Change Checklist

When modifying this skill, verify:

  • Phase 0 preflight catches all missing tools with correct install commands

  • Phase 4 uses Python API with documents_only=True (never CLI apps push )

  • No hardcoded paths — uses $HOME , mktemp , command -v , create_using_usbmux()

  • Python commands use --python 3.13 (per global policy)

  • Anti-pattern warning is preserved in Phase 4

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

pandoc-pdf-generation

No summary provided by upstream source.

Repository SourceNeeds Review
General

mql5-indicator-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

mise-tasks

No summary provided by upstream source.

Repository SourceNeeds Review
General

semantic-release

No summary provided by upstream source.

Repository SourceNeeds Review