#!/usr/bin/env dash # shellcheck source=/dev/null SHELL_LIBRARY_VERSION="1.10.2" . %SHELL_LIBRARY_PATH # CONSTANTS {{{ CONCURRENT=4 OUTPUT_PATH="/tmp/ytcc"; STATUS_FILE="$XDG_RUNTIME_DIR/ytcc/running"; STATUS_PATH="$(dirname "$STATUS_FILE")"; col() { echo "$1" | csvtool -t ';' -u ';' col "$2" - } play() { msg2 "Playing: '$1'" info_json="$(echo "$1" | sed 's|\(.*\)\.[a-z0-9]\+|\1.info.json|')"; [ -L "$STATUS_FILE" ] && rm "$STATUS_FILE" ln -s "$(readlink -f "$info_json")" "$STATUS_FILE" mpv "$1" --speed=2.7 --volume=75 output="$?"; if [ "$output" -eq 0 ]; then msg2 "Removing: $1" rm "$1" msg2 "Marking: " "$2" ytcc mark "$2" fi return "$output" } escape() { echo "$1" | awk '{gsub(/;/, ","); print}' } yt_flags="$(mktmp)" cat << EOF > "$yt_flags" --format bestvideo[height<=?1080]+bestaudio/best --embed-chapters --progress --write-comments --extractor-args youtube:max_comments=150,all,100;comment_sort=top --write-info-json --sponsorblock-mark default --sponsorblock-remove sponsor EOF # }}} if [ "$1" = "id" ]; then # This is here to keep the sorting in tack shift 1 bases="$(mktmp)"; for id in "$@"; do ytcc --output json list --attributes url --ids "$id" | jq --raw-output 'map("\(.url);\(.id)") | join("\n")' >> "$bases"; done elif [ "$1" = "url" ]; then shift 1 bases="$(mktmp)"; for url in "$@"; do # use 0 as a noop id echo "$url;0" >> "$bases"; done else die "The first arg must be one of id or url, but it was: '$1'" fi [ -d "$STATUS_PATH" ] || mkdir "$STATUS_PATH"; [ -d "$OUTPUT_PATH" ] || mkdir "$OUTPUT_PATH"; cd "$OUTPUT_PATH" || die "(Bug): Was created" filename_file="$(mktmp)"; files_to_play="$(mktmp)"; while read -r base; do url="$(col "$base" 1)"; id="$(col "$base" 2)" if [ "$old_filename" ]; then echo "$(escape "$old_filename");$old_id" >> "$files_to_play" # Check if the process (pid) exists dbg "PID is '$pid'" if ! kill -0 "$pid"; then saved_base="$(head -n 1 "$files_to_play")"; sed -i '1d' "$files_to_play"; saved_name="$(col "$saved_base" 1)"; saved_id="$(col "$saved_base" 2)" dbg "Started play for '$saved_name'" play "$saved_name" "$saved_id" & pid=$! else dbg "Storing for later '$old_filename'" fi fi # The sub shell needs to be unquoted, as the arguments may not be treated as one. # shellcheck disable=2046 yt-dlp $(cat "$yt_flags") --output "%(channel)s/%(title)s.%(ext)s" "$url" --print-to-file after_move:filepath "$filename_file" filename="$(cat "$filename_file")" printf "" > "$filename_file" if [ "$old_filename" ]; then if [ "$(wc -l < "$files_to_play")" -gt "$CONCURRENT" ]; then msg2 "Waiting for '$pid' to finish as we already have '$(wc -l < "$files_to_play")' files cached" wait "$pid" fi fi old_filename="$filename"; old_id="$id"; done < "$bases" wait "$pid" echo "$(escape "$old_filename");$old_id" >> "$files_to_play" while read -r base; do name="$(col "$base" 1)"; id="$(col "$base" 2)" dbg "Started play for '$name'" play "$name" "$id" done < "$files_to_play" # vim: ft=sh