FFPLAY - 신호가 수신될 때까지 사운드를 반복합니다.

FFPLAY - 신호가 수신될 때까지 사운드를 반복합니다.

ffplay백그라운드에서 시작하여 짧은 사운드 샘플을 무한히 반복하는 bash 스크립트가 있습니다 . 그런 다음 다른 작업을 수행하고 마침내 ffplay를 종료합니다.

foo() {
    ffplay -loop 0 sound.wav &>/dev/null &
    trap "kill $!" RETURN

    (do work...)
}

나는 ffplay가 죽기 전에 현재 재생 중인 샘플 재생을 끝내기를 원합니다. 가능합니까?

답변1

ffplay다음과 같이 캐리지 리턴(^M)으로 끝나는 줄이 포함된 연속 통계 또는 디버그 출력을 얻을 수 있습니다 .

    nan M-A:    nan fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   ^M
  -0.07 M-A: -0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   ^M
  -0.01 M-A: -0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   ^M
   0.02 M-A:  0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   ^M

첫 번째 열은 루프 시작 부분의 숫자나 음수가 아닌 "nan"인 것 같습니다. 이를 확인하고 프로세스가 보이면 종료할 수 있습니다. 다음 bash 스크립트는 이를 보여줍니다.

#!/bin/bash
sound=somefile.wav
touch flagfile
(sleep 4; rm -f flagfile) &
ffplay -nodisp -stats -loop 0 "$sound" 2>&1 |
while read -d $'\r' time rest
do  case $time in
    nan|-*|0.00) [ ! -f flagfile ] && exit ;;
    esac
done

flagfile루프를 중지하기 위해 삭제해야 하는 파일을 생성합니다 . 이 데모에서는 4초 안에 완료됩니다. ffplay옵션을 사용하여 실행합니다 -stats. 통계는 stderr에 기록되므로 stdout으로 리디렉션합니다 2>&1. 통계는 read구분 기호 캐리지 리턴( $'\r')을 사용하여 첫 번째 단어를 변수에 넣고 time나머지 단어를 에 넣는 while 루프로 파이프됩니다 rest.

case첫 번째 단어를 패턴 nan이나 숫자 0으로 시작하는 모든 항목 과 비교하고 -, 플래그 파일이 더 이상 존재하지 않으면 스크립트가 종료됩니다.

통계를 몇 번 더 작성한 후 SIGPIPE 신호에 의해 ffplay가 종료됩니다. 이 짧은 지연이 귀하에게 적합한지 결정해야 합니다. 이는 사운드 파일의 처음 몇 밀리초가 얼마나 시끄러운지에 따라 달라집니다.


SIGPIPE에 응답하지 않으면 ffplay임시 파일에 명령의 프로세스 ID를 기록하여 자체 kill 명령을 실행할 수 있습니다 pidfile. 후자는 서브셸 내에서 변경되지 않으므로 $BASHPID대신 사용하는 데 주의하세요 .$$

#!/bin/bash
sound=somefile.wav
touch flagfile
(sleep 4; rm -f flagfile) &
( echo $BASHPID >pidfile
  exec ffplay -nodisp -stats -loop 0 $sound 2>&1 ) |
while read -d $'\r' time rest
do  case $time in
    nan|-*|0.00) [ ! -f flagfile ] && break ;;
    esac
done
kill -hup $(<pidfile)
rm -f pidfile

관련 정보