Dla kontekstu próbuję utworzyć skrypt powłoki, który upraszcza wyjście konsoli ffmpeg w czasie rzeczywistym, wyświetlając tylko bieżącą ramkę, która jest kodowana. Moim celem końcowym jest wykorzystanie tych informacji w pewnego rodzaju wskaźniku postępu dla przetwarzania wsadowego.Usuwanie w czasie rzeczywistym powrotu karetki w powłoce
Dla tych, którzy nie są zaznajomieni z wynikami ffmpeg, wyprowadza zakodowane informacje wideo na stdout i informacje konsolowe na stderr. Ponadto, gdy faktycznie wyświetla informacje o kodowaniu, wykorzystuje powrót karetki, aby nie wypełniać ekranu konsoli. Dzięki temu nie można po prostu użyć grep i awk do przechwycenia odpowiednich informacji o linii i ramie.
Pierwszą rzeczą Próbowałem jest zastąpienie powrotu karetki pomocą tr:
$ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'
Działa to tym, że wyświetla obrazy w czasie rzeczywistym do konsoli. Jednakże, jeśli następnie potoku tej informacji do grep lub awk lub cokolwiek innego, dane wyjściowe tr są buforowane i nie jest już w czasie rzeczywistym. Na przykład: $ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'>log.txt
powoduje wyświetlenie pliku, który jest natychmiast wypełniony pewnymi informacjami, a następnie 5-10 sekund później, kolejne wiersze zostają upuszczone do pliku dziennika.
Na początku myślałem, że sed będzie świetny do tego: $ # ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | sed 's/\\r/\\n/'
, ale dotrze do linii z wszystkimi powrotami karetki i czeka, aż przetwarzanie zakończy się, zanim podejmie próbę zrobienia czegokolwiek. Zakładam, że dzieje się tak dlatego, że sed działa na zasadzie line-by-line i wymaga ukończenia całej linii, zanim zrobi cokolwiek innego, i wtedy i tak nie zastąpi powrotu karetki. Próbowałem różnych regex dla powrotu karetki i nowej linii, i jeszcze nie znalazłem rozwiązania, które zastąpiłoby powrót karetki. Używam OSX 10.6.8, więc używam BSD sed, co może to wyjaśniać.
Próbowałem również zapisać informacje w pliku dziennika i użyć tail -f
, aby go odczytać, ale wciąż napotykam problem zastępowania zwrotów karetki w czasie rzeczywistym.
Widziałem, że istnieją rozwiązania dla tego w python i perl, jednak jestem niechętny, aby przejść tę trasę natychmiast. Po pierwsze, nie wiem Pythona lub Perl. Po drugie, mam w pełni funkcjonalną aplikację powłoki przetwarzania wsadowego, którą potrzebowałbym do przeniesienia lub wymyślenia jak zintegrować z pythonem/perlem. Prawdopodobnie nie jest to trudne, ale nie to, co chcę osiągnąć, chyba że absolutnie muszę. Tak więc szukam rozwiązania powłoki, najlepiej bash, ale każda z powłok OSX byłaby w porządku.
A jeśli tego, czego chcę, po prostu nie da się zrobić, to chyba przejdę przez ten most, kiedy tam dotrę.
Dziękuję bardzo! Twoje pierwsze polecenie działa idealnie, chociaż oczywiście użyłem 'awk', ponieważ jestem na OSX. To oszczędza mi tyle bólu głowy! – Seth
Jedną z rzeczy, które należy dodać do tej wspaniałej odpowiedzi: sprawdź, w jaki sposób zainstalowana jest dokumentacja awk/gawk/mawk, aby dowiedzieć się, jak interpretować RS. W moim lokalnym systemie OSX, awk miał niejawne OR dla separatora rekordów (albo powrót karetki, albo znak nowej linii). Na moim serwerze Ubuntu gawk 4.0.1 interpretuje RS jako wyrażenie regularne, jeśli ma więcej niż jeden znak. Musiałem więc użyć 'RS = '\ r | \ n'', aby osiągnąć to samo zachowanie, które widziałem na OSX. – ajmicek