2e57634877
Both tools: yt-dlp calls via spawn (honor DRY_RUN; --dry-run prints the command and skips dep checks), -o/--output, --no-playlist, --cookies (with file check), clean ffmpeg/yt-dlp guards, POS_FLAGS for completion, full embedded metadata (--embed-metadata --embed-chapters --embed-thumbnail --no-overwrites; mp3 adds --convert-thumbnails jpg + artist-from-uploader parse-metadata). mp3 gains --by-artist (~/Music/<artist>/<title>.mp3). mp4: -f <id>/--best/--worst skip the prompt (mutual-exclusion validated), and the interactive picker now shows a curated [audio]/[video]/[combo] format table on stderr (stdout carries only the chosen id — ui_pick lesson), validates the id against the real -F output, and defaults empty input to best. Docs: howto/media.md rewritten.
81 lines
2.5 KiB
Bash
Executable File
81 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
# POS: media mp3 — Download audio as MP3 (yt-dlp)
|
|
# POS_FLAGS: --output --no-playlist --cookies --by-artist --dry-run
|
|
|
|
source "$(dirname "$0")/../lib/common.sh" 2>/dev/null || source "$(dirname "$0")/common.sh"
|
|
|
|
OUT_DIR="$HOME/Music"
|
|
BY_ARTIST=0
|
|
EXTRA_ARGS=()
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: pos media mp3 [options] <url>
|
|
|
|
Download audio from a URL and convert to MP3 via yt-dlp.
|
|
|
|
Options:
|
|
-o, --output <dir> Output directory (default: $OUT_DIR)
|
|
--by-artist Organize as <dir>/<artist>/<title>.mp3
|
|
--no-playlist Download only the single video
|
|
--cookies <file> Netscape cookies.txt for age-gated content
|
|
--dry-run Print the yt-dlp command without running it
|
|
-h, --help This help
|
|
|
|
Examples:
|
|
pos media mp3 https://youtube.com/watch?v=dQw4w9WgXcQ
|
|
pos media mp3 --by-artist --no-playlist https://youtu.be/dQw4w9WgXcQ
|
|
pos media mp3 --cookies ~/cookies.txt https://vimeo.com/123
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
DRY_RUN=0
|
|
URL=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-h|--help) usage ;;
|
|
-o|--output)
|
|
[ $# -ge 2 ] || err "--output needs a value"
|
|
OUT_DIR="$2"; shift 2 ;;
|
|
--by-artist) BY_ARTIST=1; shift ;;
|
|
--no-playlist) EXTRA_ARGS+=(--no-playlist); shift ;;
|
|
--cookies)
|
|
[ $# -ge 2 ] || err "--cookies needs a value"
|
|
[ -f "$2" ] || err "cookies file not found: $2"
|
|
EXTRA_ARGS+=(--cookies "$2"); shift 2 ;;
|
|
--dry-run) DRY_RUN=1; shift ;;
|
|
-*) err "Unknown option: $1 (see --help)" ;;
|
|
*)
|
|
[ -z "$URL" ] && URL="$1" && shift || err "Unexpected argument: $1" ;;
|
|
esac
|
|
done
|
|
[ -n "$URL" ] || usage
|
|
|
|
# Dependency checks (skipped under --dry-run: the command is only previewed).
|
|
if [ "$DRY_RUN" -eq 0 ]; then
|
|
command -v yt-dlp &>/dev/null || err "yt-dlp not found — install it with: sudo apt install yt-dlp"
|
|
command -v ffmpeg &>/dev/null || err "ffmpeg not found (needed for MP3 conversion) — install it with: sudo apt install ffmpeg"
|
|
fi
|
|
|
|
if [ "$BY_ARTIST" -eq 1 ]; then
|
|
OUT_TEMPLATE="$OUT_DIR/%(artist,uploader)s/%(title)s.%(ext)s"
|
|
else
|
|
OUT_TEMPLATE="$OUT_DIR/%(title)s.%(ext)s"
|
|
fi
|
|
|
|
args=(yt-dlp -x --audio-format mp3 --audio-quality 0
|
|
--embed-metadata --embed-chapters
|
|
--embed-thumbnail --convert-thumbnails jpg
|
|
--parse-metadata "%(artist,uploader)s:%(artist)s"
|
|
--no-overwrites
|
|
-o "$OUT_TEMPLATE"
|
|
"${EXTRA_ARGS[@]}" "$URL")
|
|
|
|
if [ "$DRY_RUN" -eq 1 ]; then
|
|
echo "yt-dlp ${args[*]:1}"
|
|
else
|
|
spawn "downloading audio → $OUT_DIR" "${args[@]}"
|
|
fi
|