Bir .tsdosya listem var :
out1.ts ... out749.ts out8159.ts out8818.ts
Tüm bu dosyaların toplam süresini (çalışma süresini) nasıl alabilirim?
Bir .tsdosya listem var :
out1.ts ... out749.ts out8159.ts out8818.ts
Tüm bu dosyaların toplam süresini (çalışma süresini) nasıl alabilirim?
Yanıtlar:
Hiç var .tsburada ama bunun için çalışır .mp4. Kullanım ffprobe(parçası ffmpeg) saniye, örneğin zaman almak için:
ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4
275.690000
.mp4geçerli dizindeki tüm dosyalar için :
find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \;
149.233333
130.146667
275.690000
Daha sonra kullanmak pasteüzere çıktıyı geçmesi için bcve saniye cinsinden toplam zaman olsun:
find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
555.070000
Yani, .tsdeneyebileceğiniz dosyalar için :
find . -maxdepth 1 -iname '*.ts' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
Burada sahip olduğum video dosyaları için çalışan başka bir araç exiftool, örneğin:
exiftool -S -n Inception.mp4 | grep ^Duration
Duration: 275.69
exiftool -q -p '$Duration#' Inception.mp4
275.69
.mp4Geçerli dizindeki tüm dosyaların toplam uzunluğu :
exiftool -S -n ./*.mp4 | awk '/^Duration/ {print $2}' | paste -sd+ -| bc
555.070000000000
exiftool -q -p '$Duration#' ./*.mp4 | awk '{sum += $0}; END{print sum}'
555.070000000000
Ayrıca başka bir komuta çıkış için toplam dönüştürmek olabilir DD:HH:MM:SS, cevapları görmek burada .
Ya kullanımı exiftool'iç s ConvertDuration(gerçi nispeten yeni bir sürümü gerekir) bunun için:
exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
}' ./*.mp4| tail -n1
0:09:15
ffprobe.
pasteve bc! awkDiyelim ki çok daha temiz .
bcİsteğe bağlı bir kesinliği olsa da, bazı dezavantajlar ...| paste -sd+ - | bcbazı bcuygulamalarda (örneğin seq 429 | paste -sd+ - | bcOpenSolaris ile başarısız bc) satır boyut sınırına ulaşması veya diğerlerinde tüm belleği kullanma potansiyeline sahip olmasıdır.
avprobe, Arch depolarında (bununla çakıştığı için ffmpeg) çünkü ATM'yi deneyemezsiniz, ancak eğer böyle çalıştırırsanız dosyanın süresini veriyor mu : avprobe -show_format_entry duration myfile.mp4veya avprobe -loglevel quiet -show_format_entry duration myfile.mp4? Bence bu komutlardan biri size dosyanın süresi boyunca tek bir çıktı satırı vermeli. Emin değilim.
Bu ffmpeg, zaman aşımını toplam saniye olarak kullanır ve yazdırır:
times=()
for f in *.ts; do
_t=$(ffmpeg -i "$f" 2>&1 | grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
times+=("$_t")
done
echo "${times[@]}" | sed 's/ /+/g' | bc
Açıklama:
for f in *.ts; do ".ts" ile biten her bir dosyayı yineler
ffmpeg -i "$f" 2>&1 çıktıyı stderr'ye yönlendirir
grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' zamanı izole eder
awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }' Zamanı saniye'ye çevirir
times+=("$_t") bir diziye saniye ekler
echo "${times[@]}" | sed 's/ /+/g' | bcArgümanların her birini genişletir ve boşlukları değiştirir ve onu bcortak bir linux hesaplayıcısına aktarır
Düzene jmunsch cevabı @ ve kullanma pastesadece öğrenilen I @ slm cevabı , böyle bir şey ile bitebileceğini:
for i in *.ts; do LC_ALL=C ffmpeg -i "$i" 2>&1 | \
awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done | paste -sd+ | bc
Tıpkı jmunsch gibi, ffmpegsüreyi yazdırmak için kullanıyorum , eksik bir çıktı dosyası ile ilgili hatayı görmezden geliyorum ve bunun yerine süre satırı için hata çıktısını araştırıyorum. Ben çağırmak ffmpegben lokalize çıkış mesajları hakkında endişe zorunda kalmazsınız böylece, Standart C yerelinde zorla yerel ayar tüm yönleri ile.
Sonra awkonun yerine bir tane kullanıyorum grep | grep | head | tr | awk. Bu awkçağrı içeren (umarım benzersiz) bir çizgi arar Duration:. Ayırıcı olarak iki nokta üst üste kullanarak, bu etiket alanı 1, saatleri alanı 2, dakika Sondaki virgül gözlerimi rahatsız görünmüyor saniye sonra 3 ve saniye alanını 4. dosyalanmış olan awk, ancak birileri sorunları varsa, o ve tr -d ,arasındaki boru hattına bir içerebilir .ffmpegawk
Şimdi slm'den gelen bölüm geliyor: pasteyeni satırları artı işaretleriyle değiştirmek için kullanıyorum , ancak sondaki yeni satırı etkilemeden kullanıyorum (aksine bu cevabın önceki sürümündetr \\n + bulundum ). Bu, beslenebilecek toplam ifadesini verir .bc
Slm'in datezamana benzer formatları kullanmak için kullanma fikrinden esinlenerek , burada elde edilen saniyeleri kesirli kısımlarla gün, saat, dakika ve saniye olarak formatlamak için kullanan bir versiyon:
TZ=UTC+0 date +'%j %T.%N' --date=@$(for i in *.ts; do LC_ALL=C \
ffmpeg -i "$i" 2>&1 | awk -F: '/Duration:/{print $2*3600+$3*60+$4}'; done \
| paste -sd+ | bc) | awk '{print $1-1 "d",$2}' | sed 's/[.0]*$//'
İçindeki kısım $(…)tam olarak eskisi gibi. @Karakteri bir gösterge olarak kullanarak , bunu 1 Ocak 1970'ten bu yana geçen saniye sayısı olarak kullanırız. Sonuçta ortaya çıkan “tarih”, yılın günü, saati ve nanosaniye olarak biçimlendirilir. Yılın o gününden bir tanesini çıkardık, çünkü sıfır saniyelik bir girdi zaten o yılın 1970'in 1. gününe yol açtı. Sıfırdan başlayarak yılın gününü almanın bir yolu olduğunu sanmıyorum.
Final sed, sondaki sıfırlardan kurtulur. Bu TZayar UTC kullanımını zorlamalıdır, böylece gün ışığından yararlanma saati gerçekten büyük video koleksiyonlarına engel olmaz . Bir yıldan fazla video değeriniz varsa, bu yaklaşım yine de işe yaramaz.
Uzantıya aşina değilim .ts, ancak ffmpegböyle bir dosyanın süresini belirlemek için kullanabileceğiniz bir tür video dosyası olduğunu varsayalım:
$ ffmpeg -i some.mp4 2>&1 | grep Dura
Duration: 00:23:17.01, start: 0.000000, bitrate: 504 kb/s
Daha sonra sadece süreyi seçerek bu çıktıyı bölebiliriz.
$ ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
00:23:17.01
Şimdi sadece dosyalarımızı gözden geçirmek ve bu süre değerlerini toplamak için bir yola ihtiyacımız var.
$ for i in *.mp4; do
ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"; done
00:23:17.01
00:23:17.01
00:23:17.01
NOT: İşte benim mesela ben sadece benim örnek dosyayı kopyalanmış some.mp4ve onu adlandırılmış 1.mp4, 2.mp4ve 3.mp4.
Aşağıdaki kod parçası süreleri yukarıdan alacak ve saniyelere çevirecektir.
$ for i in *.mp4; do
dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
date -ud "1970/01/01 $dur" +%s; done
1397
1397
1397
Bu bizim sürelerimizi alır $durve dosyaları değiştirirken bunları değişkene koyar . dateKomut daha sonra UNIX dönemine (1970/01/01) sinüs saniye sayısını hesaplamak için kullanılır. İşte yukarıdaki datekomut dağıldı, bu yüzden görülmesi daha kolay:
$ date -ud "1970/01/01 00:23:17.01" +%s
1397
NOT:date Bu şekilde kullanmak , tüm dosyalarınızın <24 saat (yani 86400 saniye) süresine sahip olması durumunda işe yarar. Daha büyük sürelerle başa çıkabilecek bir şeye ihtiyacınız olursa, bunu alternatif olarak kullanabilirsiniz:
sed 's/^/((/; s/:/)*60+/g' | bc
Örnek
$ echo 44:29:36.01 | sed 's/^/((/; s/:/)*60+/g' | bc
160176.01
Daha sonra fordöngümüzün çıktısını alabilir ve her sayı arasında işaretleri pasteiçeren bir komuta girebiliriz +, şöyle:
$ for i in *.mp4; do
dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
date -ud "1970/01/01 $dur" +%s; done | paste -s -d+
1397+1397+1397
Sonunda, bcbunları özetlemek için komut satırı hesap makinesine koyarız :
$ for i in *.mp4; do
dur=$(ffmpeg -i "$i" 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)");
date -ud "1970/01/01 $dur" +%s; done | paste -s -d+ | bc
4191
Tüm dosyaların toplam süresi içinde saniye cinsinden sonuç. Elbette gerekirse bu başka bir formata dönüştürülebilir.
datemight 24 saat / 86400 saniyedir)ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"26:33:21.68
pastebenim en sevdiğim komut 8-)
Kabul edilen cevabı iptal etmek ve klasik UNIX ters parlatma aracını kullanmak:
{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
-show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc
783.493000
Yani: Eklemek +ve psonra onu boruya sokmak dc, toplamı elde etmek.
$ find -iname '*.ts' -print0 |\
xargs -0 mplayer -vo dummy -ao dummy -identify 2>/dev/null |\
perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t += $1) && printf "%02d:%02d:%02d:%02d\n",$t/86400,$t/3600%24,$t/60%60,$t%60'
MPlayer'ın kurulu olduğundan emin olun .
Ubuntu olarak ffmpeg yerine libav gemisi:
#!/bin/sh
for f in *.mp4; do
avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc
Ağır MvG fikirlerine dayalı
Eh, tüm bu çözümler biraz işe ihtiyaç duyuyor, yaptığım şey çok basitti, 1)
İstediğiniz klasöre gidip sağ tıklayın -> diğer uygulamalarla açın
Ardından VLC media player'ı seçin.
işte örnek
Araç çubuğunun hemen altında görebilirsiniz, Oynatma Listesi [10:35:51] yazılı, bu nedenle klasörde 10 saat 35 dakika ve 51 saniye toplam video süresi var