バックグラウンドコマンドでダウンロード中のビデオを開く

バックグラウンドコマンドでダウンロード中のビデオを開く

以下のコマンドは、youtube-dlの出力をsedで処理して、ビデオのファイル名を取得します。

youtube-dl "$URL" 2> /dev/null | \
sed -n 's/^\[download\] Destination: //p; s/^\[download\] \(.*\) has already been downloade.*/\1/p'

youtube-dl が HTML の取得と解析を終了し、ビデオのダウンロードを開始するとすぐに (実行開始から数秒後)、ダウンロードが完了するとビデオのファイル名が出力されます (ダウンロード中を示す「.partwhile it's downloading」が末尾に付きます)。

問題の核心であり、私が行き詰まっているのは、上記のコマンドをバックグラウンドで実行し(ダウンロードを継続する)、標準出力からビデオ ファイル名を取得して、ダウンロードが完了する前にビデオ ファイルを開くにはどうすればよいかということです。

答え1

次のように使用できますinotifywait:

$ youtube-dl "$URL" &
$ inotifywait  --event create --format '"%f"' . | xargs vlc

競合状態が発生し、接続が非常に高速な場合 (私の場合は現在高速です)、プレーヤーがファイルを開く前に、ファイルがダウンロードされ、名前が変更される可能性があります。また、youtube-dlオーディオとビデオを別々にダウンロードするような操作を行うと、間違ったファイルを開いてしまう可能性があります。

答え2

@fra さんのコメントで、while ループを思い出しました。whilereadループは、出力を行ごとに/手続き的に処理するために使用できます (パイプを使用して機能的に処理するのではなく)。youtube <-dl コマンドの Bash プロセス置換を使用して、演算子を使用してファイルの出力をそのループにパイプできます。また、 を追加してバックグラウンドに送信することもできます。while&ループは、その出力を読み取ることができます (BPS が作成したファイルを読み取るだけです)。

テストの結果、ダウンロードが完了して名前が変更された後でも、ビデオを正常に再生し続けることができることがわかりましたが、これは mpv の機能である可能性があります。

#!/bin/bash
# ytdl-stream - use youtube-dl to stream videos i.e watch videos as they download
# usage: ytdl-stream [YOUTUBE_DL_OPTIONS] URL 
# you can pipe into it a command to open you video player, e.g:
# echo mpv --mute=yes | ytdl-stream -f 'best[width<=1920,height<=1080]' --write-auto-sub [URL]

test ! -t 0 && player_cmd="$(cat /dev/stdin)" || player_cmd="mpv"

while IFS="" read -r line; do
  filename=$(echo "$line" | sed -n 's/^\[download\] Destination: //p')
  if [[ -z "$filename" ]]; then
    filename=$(echo "$line" | sed -n 's/^\[download\] \(.*\) has already been downloade.*/\1/p')
    [[ -z "$filename" ]] && continue || notify-send "file already downloaded, opening.."
  else
    notify-send "downloading.."
  fi
  withoutExtensions="${filename%.*}"
  withoutExtensions="${withoutExtensions%.*}"
  if [[ -e "$filename" ]]; then
    sleep 0.5 && ($player_cmd "$filename")&
  elif [[ -e "$filename".part ]]; then
    sleep 2
    if [[ -e "$filename".part ]]; then
      notify-send "found .part after sleep again"
      ($player_cmd "$filename".part)&
    else
      sleep 0.5 && ($player_cmd "$withoutExtensions"*)&
    fi
  fi
done < <(youtube-dl "$@" 2> /dev/null)&

関連情報