mcpField
Y
youtube-to-bookplayer

youtube-to-bookplayer

github.com/terrylicaクリエイティブ・メディア173 回インストール1 日前に更新
リポジトリ

youtube-to-bookplayer について

youtube-to-bookplayer は YouTube の音声をダウンロードしてメタデータを付け、USB 経由で iPhone の BookPlayer に転送するスキルです。段階的な手順でデバイスを確認し、転送後のファイルも検証します。

主な機能

  1. 01YouTube音声をM4Aでダウンロード
  2. 02音声メタデータを編集
  3. 03USB経由でBookPlayerに転送
  4. 04デバイスとアプリの利用可否を確認
  5. 05転送後のファイルを検証

活用シーン

  1. 01BookPlayerでYouTubeの講義を聴く
  2. 02長尺のYouTube音声をiPhoneに移す
  3. 03タイトルとアーティスト情報で音声を整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/terrylica/cc-skills --skill youtube-to-bookplayer

インストール後、Claude Code で/youtube-to-bookplayerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
evolution-log.md
tool-reference.md
troubleshooting.md

詳細

youtube-to-bookplayer

YouTube 動画から音声をダウンロードして、メタデータをタグ付けし、USB 経由で iPhone の BookPlayer に転送します。

BookPlayer は、再生位置を記憶する iOS オーディオブックプレーヤーです。講義、オーディオブック、ポッドキャストなど、長時間の YouTube コンテンツに最適です。/Documents/ ディレクトリに転送したファイルは、次回のアプリ起動時に自動的に読み込まれます。


自己進化型スキル:このスキルは使用を通じて改善されます。指示に誤りがある場合、パラメーターにずれが生じた場合、または回避策が必要だった場合は、先送りせず、このファイルをすぐに修正してください。実際に再現できる問題がある場合のみ更新してください。

タスクテンプレート

フェーズ 0~5 を順番に実行します。各フェーズには、その性質を示す [Preflight]、[Ask]、[Execute]、または [Verify] タグが付いています。フェーズを省略しないでください。


Phase 0: 事前確認 [Preflight]

必要なツールとデバイスの接続状況を確認します。問題があれば即座に中断し、先に進まないでください。

# 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.14 --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)"

ツールが見つからない場合:

ツールインストールコマンド
yt-dlpbrew install yt-dlp
ffmpegbrew install ffmpeg
exiftoolbrew install exiftool
pymobiledevice3uvx --python 3.14 --from pymobiledevice3 pymobiledevice3 --help

デバイスの確認(ツールの確認にすべて合格した後のみ):

# Check for connected iOS device
pymobiledevice3 usbmux list 2>/dev/null || uvx --python 3.14 --from pymobiledevice3 pymobiledevice3 usbmux list

# Check BookPlayer is installed
pymobiledevice3 apps list --no-color 2>/dev/null | grep -i "audiobookplayer\|bookplayer" || \
  uvx --python 3.14 --from pymobiledevice3 pymobiledevice3 apps list --no-color 2>/dev/null | grep -i "audiobookplayer\|bookplayer"

デバイスが見つからない場合:USB 経由で iPhone を接続してロックを解除し、「このコンピュータを信頼」をタップするようユーザーに依頼します。 BookPlayer が見つからない場合:App Store から BookPlayer をインストールするようユーザーに依頼します。


Phase 1: URL の受け取りと確認 [Ask]

$ARGUMENTS[0] が指定されている場合は、それを YouTube URL として使用します。指定されていない場合は、AskUserQuestion を使って URL を尋ねます。

続行する前にメタデータをプレビューします:

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')}\")
"

AskUserQuestion を使って、次の点を確認します:

  • タイトル、チャンネル、再生時間が正しいか
  • メタデータ(タイトル/アーティスト/アルバム)をカスタマイズするか、yt-dlp のデフォルト値を使用するか

Phase 2: 音声のダウンロード [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

注意:

  • --audio-quality 0 = 利用可能な最高音質
  • %(title).100B はファイル名を 100 バイトに切り詰めます(ファイルシステムの問題を防止します)
  • --no-playlist により、プレイリスト URL からも単一の動画だけをダウンロードします
  • M4A への変換には、yt-dlp によって ffmpeg が自動的に呼び出されます

Phase 3: メタデータのタグ付け [Execute]

yt-dlp の JSON からメタデータを抽出し、M4A ファイルに適用します:

# 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"

変数(Phase 1 の確認内容から取得):

  • $TITLE — 動画のタイトル(またはユーザーがカスタマイズしたもの)
  • $ARTIST — チャンネル名(またはユーザーがカスタマイズしたもの)
  • ユーザーが別の指定をしない限り、アルバム名は「YouTube Audio」になります

Phase 4: BookPlayer への転送 [Execute]

重要:documents_only=True を指定した Python API を使用してください。CLI の pymobiledevice3 apps push は VendContainer モードを使用するため、BookPlayer では動作しません。

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

uvx --python 3.14 --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

アンチパターン — 使用禁止:

# WRONG: This uses VendContainer mode and fails silently on BookPlayer
pymobiledevice3 apps push com.tortugapower.audiobookplayer /path/to/file.m4a

Phase 5: 検証 [Verify]

BookPlayer の /Documents/ ディレクトリを一覧表示し、ファイルが転送されたことを確認します:

uvx --python 3.14 --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

ユーザーへの報告:

  • BookPlayer 内のファイル名とサイズ
  • 再生時間(Phase 1 のメタデータから取得)
  • 新しいファイルを表示するには iPhone で BookPlayer を開くよう伝えます(表示されない場合は、アプリを強制終了してから再度開きます)

クリーンアップ:

# Remove temp working directory
rm -rf "$WORK_DIR"
echo "Cleaned up: $WORK_DIR"

トラブルシューティングのクイックリファレンス

問題簡単な解決方法
デバイスが見つからないiPhone のロックを解除し、USB を接続し直して、「信頼」をタップします
ファイルが BookPlayer に表示されないCLI を使用しています。documents_only=True を指定した Python API を使用する必要があります
表示されるメタデータが違う正しい -Title/-Artist 値を指定して Phase 3 を再実行します

詳細なトラブルシューティング:references/troubleshooting.md


参考資料


変更後のチェックリスト

このスキルを変更した場合は、次の点を確認してください。

  • フェーズ 0 の事前チェックで、不足しているすべてのツールを正しいインストールコマンドとともに検出できる
  • フェーズ 4 では、Python API で documents_only=True を使用している(CLI の apps push は決して使用しない)
  • ハードコードされたパスがない — $HOME、mktemp、command -v、create_using_usbmux() を使用している
  • Python コマンドで --python 3.14 を使用している(グローバルポリシーに準拠)
  • フェーズ 4 でアンチパターンの警告が保持されている

実行後の振り返り

このスキルの完了後、タスクを終了する前に振り返ってください。

  1. 現在の場所を確認します。 — 編集する前に、このスキルの SKILL.md の正規のパスを見つけます(このスキル名で Glob を実行)。修正の対象は必ずこのファイルとその sibling references/ です。他のドキュメントは対象にしません。
  2. 何が失敗しましたか? — 原因となった指示を修正します。再発する可能性がある場合は、アンチパターンとして追加します。
  3. 予想以上にうまくいったことは何ですか? — 推奨プラクティスにします。その理由も記録します。
  4. 何が実態とずれていましたか? — 現状に合わなくなったスクリプト、リファレンス、外部依存関係があれば、今すぐ修正します。
  5. 記録します。 — 変更のたびに、きっかけ、修正内容、根拠を記した進化ログのエントリーを追加します。

先送りしないでください。次の呼び出しには、残した状態がそのまま引き継がれます

コメント