Mam listę .ts
plików:
out1.ts ... out749.ts out8159.ts out8818.ts
Jak mogę uzyskać całkowity czas trwania (czas działania) wszystkich tych plików?
shell-script
video
k961
źródło
źródło
Odpowiedzi:
Nie mam
.ts
tutaj, ale to działa.mp4
. Użyjffprobe
(częśćffmpeg
), aby uzyskać czas w sekundach, np .:więc dla wszystkich
.mp4
plików w bieżącym katalogu:następnie użyć
paste
aby przekazać wyjście dobc
i uzyskać całkowity czas w sekundach:W przypadku
.ts
plików możesz spróbować:Innym narzędziem, które działa dla plików wideo, które tu mam, jest
exiftool
np .:Całkowita długość wszystkich
.mp4
plików w bieżącym katalogu:Możesz również przesłać dane wyjściowe do innego polecenia, aby przekonwertować sumę
DD:HH:MM:SS
, zobacz odpowiedzi tutaj .Lub użyj do tego
exiftool
wewnętrznegoConvertDuration
(potrzebujesz jednak stosunkowo nowej wersji):źródło
ffprobe
wcześniej.paste
ibc
! znacznie czystsze niżawk
powiedzmy.bc
będzie to miało dowolną precyzję, jedną wadą jest to, że...| paste -sd+ - | bc
albo osiągnie limit rozmiaru linii w niektórychbc
implementacjach (na przykładseq 429 | paste -sd+ - | bc
zawiedzie w OpenSolarisabc
), albo może potencjalnie wykorzystać całą pamięć w innych.avprobe
w repozytoriach Arch (prolly, ponieważ powoduje konfliktffmpeg
), więc nie można wypróbować bankomatu, ale czy daje on czas trwania pliku, jeśli uruchomisz go w ten sposób:avprobe -show_format_entry duration myfile.mp4
lubavprobe -loglevel quiet -show_format_entry duration myfile.mp4
? Myślę, że jedno z tych poleceń powinno dać ci jeden wiersz wyniku z czasem trwania pliku. Nie jestem pewien.Spowoduje to użycie
ffmpeg
i wydrukowanie limitu czasu w całkowitych sekundach:Wyjaśnienie:
for f in *.ts; do
iteruje każdy z plików, który kończy się na „.ts”ffmpeg -i "$f" 2>&1
przekierowuje wyjście do stderrgrep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
izoluje czasawk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Konwertuje czas na sekundytimes+=("$_t")
dodaje sekundy do tablicyecho "${times[@]}" | sed 's/ /+/g' | bc
rozwija każdy z argumentów i zastępuje spacje i potokuje je dobc
wspólnego kalkulatora linuxźródło
Usprawniając odpowiedź @ jmunsch i korzystając z odpowiedzi ,
paste
którą właśnie nauczyłem się z @ slm , możesz otrzymać coś takiego:Podobnie jak jmunsch, używam
ffmpeg
do drukowania czasu trwania, ignorując błąd dotyczący brakującego pliku wyjściowego i zamiast tego szukam w wierszu czasu trwania błędu. Inwokujęffmpeg
ze wszystkimi aspektami ustawień narodowych wymuszonymi na standardowe ustawienia regionalne C, aby nie musiałem się martwić o zlokalizowane komunikaty wyjściowe.Następnie używam singla
awk
zamiast jegogrep | grep | head | tr | awk
. Toawk
wywołanie szuka wiersza zawierającego (miejmy nadzieję unikatowego)Duration:
. Używając dwukropka jako separatora, etykieta jest polem 1, godziny są polem 2, minutami zapisanymi 3 i polem sekund 4. Przecinek końcowy po sekundach nie przeszkadza miawk
, ale jeśli ktoś ma problemy, on może zawieraćtr -d ,
w potoku międzyffmpeg
iawk
.Teraz zaczyna się od SLM: Używam
paste
zastąpić newlines z znaki plus, ale bez wpływu na nowej linii spływu (w przeciwieństwie dotr \\n +
miałem w poprzedniej wersji tej odpowiedzi). To daje sumę wyrażenia, którą można podaćbc
.Zainspirowana pomysłem SLM dotyczącym
date
obsługi formatów podobnych do czasu, oto wersja, która używa go do formatowania wynikowych sekund jako dni, godzin, minut i sekund z częścią ułamkową:Część wewnątrz
$(…)
jest dokładnie taka jak poprzednio. Używając tego@
znaku jako wskaźnika, używamy go jako liczby sekund od 1 stycznia 1970 roku. Powstała „data” jest formatowana jako dzień roku, godzina i nanosekundy. Od tego dnia roku odejmujemy jeden, ponieważ wprowadzanie wartości zero sekund prowadzi już do dnia 1 tego roku 1970. Nie sądzę, że istnieje sposób, aby liczenie dnia roku zaczynało się od zera.Finał
sed
pozbywa się dodatkowych zer końcowych.TZ
Ustawienie powinno nadzieją wymusić użycie UTC, tak że czas letni nie będzie kolidować z naprawdę dużych zbiorów wideo. Jeśli masz wideo dłuższe niż rok, to podejście nadal nie zadziała.źródło
Nie znam
.ts
rozszerzenia, ale zakładając, że jest to jakiś plik wideo, którego można użyćffmpeg
do określenia czasu trwania pliku:Następnie możemy podzielić ten wynik, wybierając tylko czas trwania.
Teraz potrzebujemy tylko sposobu na iterację naszych plików i zebranie tych wartości czasu trwania.
UWAGA: Tutaj dla mojego przykładu po prostu skopiowałem mój przykładowy plik
some.mp4
i nadałem mu nazwę1.mp4
,2.mp4
i3.mp4
.Przeliczanie czasów na sekundy
Poniższy fragment zabierze czas trwania z góry i zamieni go na sekundy.
To zajmuje nasze czasy trwania i umieszcza je w zmiennej,
$dur
gdy przeglądamy pliki.date
Polecenia te są następnie wykorzystywane do obliczenia liczby sekund sinusoidalnych epoki owych (1970/01/01). Oto powyższedate
polecenie, dzięki czemu łatwiej zobaczyć:UWAGA: Używanie
Przykładdate
w ten sposób będzie działać tylko wtedy, gdy wszystkie twoje pliki mają czas trwania <24 godziny (tj. 86400 sekund). Jeśli potrzebujesz czegoś, co poradzi sobie z dłuższym czasem trwania, możesz użyć tego jako alternatywy:Sumując czasy
Następnie możemy pobrać dane wyjściowe z naszej
for
pętli i uruchomić je wpaste
poleceniu, które będzie zawierało+
znaki między każdą liczbą, w następujący sposób:Na koniec uruchamiamy to w kalkulatorze wiersza poleceń,
bc
aby je podsumować:Łączny czas trwania wszystkich plików, w sekundach. W razie potrzeby można to oczywiście przekonwertować na inny format.
źródło
date
może się udusić, jeśliffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
zwróci coś podobnego26:33:21.68
(to znaczy czas trwania ≥ 24 godziny / 86400 sekund)paste
zwróciło moją uwagę. Myślę, że przyda mijava -classpath $(find -name \*.jar | paste -sd:)
się bardzo , biorąc pod uwagę włamania, których użyłem w przeszłości.paste
to moje ulubione polecenie 8-)Wyjście z zaakceptowanej odpowiedzi i użycie klasycznego narzędzia do polerowania w systemie UNIX:
Tj .: dodawanie,
+
ap
następnie wpuszczanie tego do,dc
a otrzymasz swoją sumę.źródło
bc
dostaje o wiele za dużo miłości. Wszyscy stawiacie+
znaki między każdą linią (łączenie się+
), podczas gdy przy polerowaniu wstecznym można po prostu rzucić a+
na końcu ip
zrzucić to;)Upewnij się, że masz zainstalowany MPlayer .
źródło
Jako Ubuntu wysyłamy libav zamiast ffmpeg:
Mocno oparty na pomysłach MvG
źródło
Cóż, te wszystkie rozwiązania wymagają trochę pracy, to co zrobiłem było bardzo proste, 1)
poszedł do żądanego folderu i kliknij prawym przyciskiem myszy -> otwórz za pomocą innej aplikacji
Następnie wybierz odtwarzacz multimedialny VLC,
oto przykład
1.
2)
3)
Możesz zobaczyć tuż pod paskiem narzędzi, napisana jest lista odtwarzania [10:35:51] , więc folder zawiera 10 godzin 35 minut i 51 sekund czasu trwania wszystkich filmów
źródło
Miałem podkatalogi w bieżącym folderze, więc musiałem rekurencyjnie obliczać czas trwania:
find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1
źródło