मेरे पास .tsफ़ाइलों की एक सूची है :
out1.ts ... out749.ts out8159.ts out8818.ts
मैं इन सभी फाइलों की कुल अवधि (रनिंग टाइम) कैसे प्राप्त कर सकता हूं?
मेरे पास .tsफ़ाइलों की एक सूची है :
out1.ts ... out749.ts out8159.ts out8818.ts
मैं इन सभी फाइलों की कुल अवधि (रनिंग टाइम) कैसे प्राप्त कर सकता हूं?
जवाबों:
मेरे पास .tsयहां नहीं है लेकिन यह काम करता है .mp4। सेकंड में समय पाने के लिए ffprobe(भाग ffmpeg) का उपयोग करें , जैसे:
ffprobe -v quiet -of csv=p=0 -show_entries format=duration Inception.mp4
275.690000
.mp4वर्तमान dir में सभी फ़ाइलों के लिए:
find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \;
149.233333
130.146667
275.690000
तब आउटपुटpaste को पास करने bcऔर सेकंड में कुल समय प्राप्त करने के लिए उपयोग करें :
find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
555.070000
इसलिए, उन .tsफ़ाइलों के लिए जिन्हें आप आज़मा सकते हैं:
find . -maxdepth 1 -iname '*.ts' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc
एक और उपकरण जो मेरे पास मौजूद वीडियो फ़ाइलों के लिए काम करता है exiftool, जैसे:
exiftool -S -n Inception.mp4 | grep ^Duration
Duration: 275.69
exiftool -q -p '$Duration#' Inception.mp4
275.69
.mp4वर्तमान निर्देशिका की सभी फाइलों की कुल लंबाई :
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
आप कुल DD:HH:MM:SSउत्तरों को बदलने के लिए आउटपुट को किसी अन्य कमांड पर भी पाइप कर सकते हैं , यहां उत्तर देखें ।
या उसके लिए exiftoolआंतरिक का उपयोग करें ConvertDuration(आपको हालांकि अपेक्षाकृत हाल के संस्करण की आवश्यकता है):
exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)
}' ./*.mp4| tail -n1
0:09:15
ffprobeसे पहले नहीं देखा था ।
pasteऔर bc! awkचलो कहते हैं की तुलना में बहुत क्लीनर ।
bcमनमानी परिशुद्धता, एक दोष यह है कि ...| paste -sd+ - | bcया तो कुछ bcकार्यान्वयन में लाइन आकार सीमा तक पहुंच जाएगा (उदाहरण के लिए seq 429 | paste -sd+ - | bcओपनसोलारिस के साथ विफल रहता है bc) या दूसरों में सभी मेमोरी का उपयोग करने की क्षमता है।
avprobeआर्क रीपोस में नहीं (संक्षेप में क्योंकि यह संघर्ष करता है ffmpeg) इसलिए इसे एटीएम की कोशिश नहीं कर सकता है लेकिन क्या यह आपको फ़ाइल की अवधि देता है यदि आप इसे इस तरह से चलाते हैं: avprobe -show_format_entry duration myfile.mp4या avprobe -loglevel quiet -show_format_entry duration myfile.mp4? मुझे लगता है कि इनमें से एक कमांड आपको फ़ाइल की अवधि के साथ आउटपुट की एक पंक्ति देनी चाहिए। हालांकि यकीन नहीं हो रहा है।
यह ffmpegकुल सेकंड में समय का उपयोग करता है और प्रिंट करता है :
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
स्पष्टीकरण:
for f in *.ts; do ".ts" में समाप्त होने वाली प्रत्येक फ़ाइल को iterates
ffmpeg -i "$f" 2>&1 आउटपुट को stderr पर पुनर्निर्देशित करता है
grep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' ' समय अलग करता है
awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }' सेकंड के लिए समय बदलता है
times+=("$_t") एक सरणी में सेकंड जोड़ता है
echo "${times[@]}" | sed 's/ /+/g' | bcप्रत्येक तर्क का विस्तार करता है और रिक्त स्थान की जगह लेता है और इसे bcएक सामान्य लिनक्स कैलकुलेटर पर पाइप करता है
व्यवस्थित बनाने @ jmunsch का जवाब है, और का उपयोग कर pasteमैं बस से सीखा @ SLM का जवाब है, तो आप कुछ इस तरह लग सकती है:
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
जैसे jmunsch ने किया है, मैं ffmpegअवधि को प्रिंट करने के लिए उपयोग कर रहा हूं , एक लापता आउटपुट फ़ाइल के बारे में त्रुटि को अनदेखा कर रहा हूं और इसके बजाय अवधि लाइन के लिए त्रुटि आउटपुट खोज रहा हूं । मैं ffmpegमानक सी लोकेल के लिए मजबूर लोकेल के सभी पहलुओं के साथ आह्वान करता हूं, ताकि मुझे स्थानीय आउटपुट संदेशों के बारे में चिंता न करनी पड़े।
आगे मैं awkउसकी जगह सिंगल का इस्तेमाल कर रहा हूं grep | grep | head | tr | awk। वह awkमंगलाचरण (उम्मीद से अद्वितीय) युक्त लाइन के लिए दिखता है Duration:। एक विभाजक के रूप में बृहदान्त्र का उपयोग करना, वह लेबल फ़ील्ड 1 है, घंटे फ़ील्ड 2 हैं, मिनट 3 दर्ज किए गए हैं और सेकंड फ़ील्ड 4. सेकंड के बाद अनुगामी अल्पविराम मुझे परेशान नहीं करता है awk, लेकिन अगर किसी को वहां समस्या है, तो वह एक शामिल हो सकते हैं tr -d ,के बीच पाइप लाइन में ffmpegऔर awk।
अब एसएलएम से भाग आता है: मैं नए pasteसंकेतों को प्लस चिह्नों के साथ बदलने के लिए उपयोग कर रहा हूं , लेकिन अनुगामी न्यूलाइन को प्रभावित किए बिना ( इस उत्तर के पिछले संस्करणtr \\n + में मेरे विपरीत था )। यह योग की अभिव्यक्ति देता है जिसे खिलाया जा सकता है ।bc
dateसमय के समान प्रारूपों को संभालने के लिए स्लम के विचार से प्रेरित , यहां एक संस्करण है जो इसे परिणामी सेकंडों को दिनों, घंटों, मिनटों और अंशों वाले सेकंड के रूप में प्रारूपित करने के लिए उपयोग करता है:
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]*$//'
अंदर $(…)का हिस्सा पहले की तरह ही है। @एक संकेत के रूप में चरित्र का उपयोग करते हुए, हम इसे 1 जनवरी 1970 से सेकंड की संख्या के रूप में उपयोग करते हैं। परिणामस्वरूप "तिथि" वर्ष, समय और नैनोसेकंड के दिन के रूप में स्वरूपित हो जाती है। वर्ष के उस दिन से हम एक को घटाते हैं, क्योंकि शून्य सेकंड का एक इनपुट पहले से ही उस वर्ष 1970 के दिन 1 हो जाता है। मुझे नहीं लगता कि शून्य पर शुरू होने वाले वर्ष की गणना का दिन प्राप्त करने का एक तरीका है।
फाइनल sedमें अतिरिक्त ट्रेलिंग शून्य से छुटकारा मिलता है। TZसेटिंग उम्मीद है कि, यूटीसी का उपयोग कराने के लिए इतना है कि डेलाइट बचत समय साथ हस्तक्षेप नहीं करेगा चाहिए वास्तव में बड़े वीडियो संग्रह। यदि आपके पास एक वर्ष से अधिक का वीडियो है, तो यह दृष्टिकोण अभी भी काम नहीं करेगा, हालांकि।
मैं .tsविस्तार से परिचित नहीं हूं , लेकिन यह मानते हुए कि वे किसी प्रकार की वीडियो फ़ाइल हैं ffmpegजिसका उपयोग आप किसी फ़ाइल की अवधि की पहचान करने के लिए कर सकते हैं :
$ ffmpeg -i some.mp4 2>&1 | grep Dura
Duration: 00:23:17.01, start: 0.000000, bitrate: 504 kb/s
हम इस उत्पादन को विभाजित कर सकते हैं, केवल अवधि के समय का चयन करते हुए।
$ ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
00:23:17.01
तो अब हमें अपनी फ़ाइलों के माध्यम से पुनरावृति करने और इन अवधि मानों को इकट्ठा करने की आवश्यकता है।
$ 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
नोट: यहाँ मेरी उदाहरण के लिए मैं बस अपना नमूना फ़ाइल की नकल की some.mp4है और इसे नाम दिया है 1.mp4, 2.mp4और 3.mp4।
निम्नलिखित स्निपेट ऊपर से अवधि लेते हैं और उन्हें सेकंड में परिवर्तित करते हैं।
$ 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
यह हमारी अवधि लेता है और $durफ़ाइलों के माध्यम से लूप के रूप में उन्हें एक चर में डालता है । इसके dateबाद यूनिक्स एपोक (1970/01/01) साइन सेकंड की संख्या की गणना करने के लिए कमांड का उपयोग किया जाता है। यहाँ ऊपर दिए गए dateआदेश को तोड़ दिया गया है, इसलिए यह देखना आसान है:
$ date -ud "1970/01/01 00:23:17.01" +%s
1397
नोट:date इस तरीके का उपयोग केवल तभी काम करेगा जब आपकी सभी फाइलों की अवधि <24 घंटे (86400 सेकंड) हो। यदि आपको कुछ ऐसी चीज़ों की ज़रूरत है जो एक बड़ी अवधि को संभाल सकें तो आप इसे विकल्प के रूप में उपयोग कर सकते हैं:
sed 's/^/((/; s/:/)*60+/g' | bc
उदाहरण
$ echo 44:29:36.01 | sed 's/^/((/; s/:/)*60+/g' | bc
160176.01
फिर हम अपने forलूप का आउटपुट ले सकते हैं और इसे एक pasteकमांड में चला सकते हैं +, जो प्रत्येक संख्या के बीच में संकेतों को शामिल करेगा , जैसे:
$ 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
अंत में हम कमांड लाइन कैलकुलेटर में bcउन्हें चलाने के लिए इसे चलाते हैं :
$ 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
सभी फ़ाइलों की कुल अवधि में परिणाम, सेकंड में। यदि आवश्यक हो तो यह निश्चित रूप से किसी अन्य प्रारूप में परिवर्तित किया जा सकता है।
dateअगर ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"कुछ ऐसा है, तो वह चोक हो सकता है 26:33:21.68(यानी, अवधि, 24 घंटे / 86400 सेकंड)
pasteमेरी पसंदीदा आदेश 8-) है
स्वीकार किए गए उत्तर को बंद करके क्लासिक UNIX रिवर्स-पॉलिश टूल का उपयोग करें:
{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
-show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc
783.493000
Ie: लागू करना +और pफिर उस में पाइप करना dcऔर आप अपनी राशि प्राप्त करेंगे।
$ 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 स्थापित है।
खैर, इन सभी समाधानों को थोड़ा काम करने की ज़रूरत है, जो मैंने किया वह बहुत सरल था, 1)
वांछित फ़ोल्डर में गया और राइट क्लिक -> अन्य एप्लिकेशन के साथ खुला
फिर VLC मीडिया प्लेयर चुनें,
यहाँ उदाहरण है
आप बस टूलबार के नीचे देख सकते हैं, वहां Playlist [10:35:51] लिखा है, इसलिए फ़ोल्डर में 10 घंटे 35 मिनट और कुल वीडियो की 51 सेकंड अवधि है