다운로드 중인 비디오를 백그라운드 명령으로 엽니다.

다운로드 중인 비디오를 백그라운드 명령으로 엽니다.

다음 명령은 sed를 사용하여 youtube-dl의 출력을 처리하여 비디오의 파일 이름을 가져옵니다.

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

youtube-dl이 HTML 가져오기 및 구문 분석을 마치고 비디오 다운로드를 시작한 직후(실행 시작 후 몇 초/초), 다운로드가 완료된 후 비디오의 파일 이름을 출력합니다(접미사에 재생 시간이 추가됨) .part. 다운로드되었습니다)

그래서 문제의 핵심과 내가 막고 있는 것은 어떻게 위 명령을 백그라운드에 넣고(계속 다운로드되도록) 표준 출력에서 ​​비디오 파일 이름을 가져와서 열 수 있느냐 하는 것입니다. 다운로드가 완료되기 전에 비디오 파일.

답변1

당신이 사용할 수있는 inotifywait:

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

거기에는 경쟁 조건이 있습니다. 연결이 매우 빠른 경우(저는 그렇죠) 플레이어가 파일을 열기 전에 파일을 다운로드하고 이름을 바꿀 수 있습니다. 또한 youtube-dl오디오와 비디오를 별도로 다운로드하는 등의 작업을 수행하면 잘못된 파일을 열 수도 있습니다.

답변2

@fra-san의 의견은 출력 라인을 한 줄씩/프로그래밍 방식으로 처리하는 데 사용할 수 있는 while read루프를 생각나게 했습니다(기능적으로 파이프를 사용하는 대신). 연산자를 사용하여 <파일의 출력을 다음 루프로 파이프 할 수 있습니다. youtube-dl 명령을 대체하는 Bash 프로세스를 사용하면 while 루프를 추가하여 백그라운드로 보낼 수도 있으며 &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)&

관련 정보