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