আমার কাছে .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আগে / আগে এই কৌশলটি দেখেনি before
pasteএবং bc! awkবলার চেয়ে অনেক ক্লিনার ।
bcঅবাধ স্পষ্টতা কি করতে হবে, এক অপূর্ণতা যে ...| paste -sd+ - | bcপারেন কিছু লাইন সীমাকে পৌঁছবে bcবাস্তবায়নের (উদাহরণস্বরূপ seq 429 | paste -sd+ - | bcOpenSolaris সঙ্গে ব্যর্থ bc) অথবা অন্যদের মধ্যে সব স্মৃতি ব্যবহার করে সম্ভাব্য আছে।
avprobeআর্চ রেপোসে নেই (প্রলি কারণ এটির সাথে দ্বন্দ্ব রয়েছে ffmpeg) তাই এটিএম চেষ্টা করে দেখতে পারবেন না তবে আপনি যদি ফাইলটি চালিয়ে যান তবে এটি আপনাকে সময়কাল দেয়: avprobe -show_format_entry duration myfile.mp4বা avprobe -loglevel quiet -show_format_entry duration myfile.mp4? আমি মনে করি এই কমান্ডগুলির মধ্যে একটি আপনাকে ফাইলের সময়কাল সহ একক আউটপুট দেয় give যদিও নিশ্চিত না।
এটি 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" এ শেষ হওয়া প্রতিটি ফাইলকে পুনরাবৃত্তি করে
ffmpeg -i "$f" 2>&1 স্ট্যান্ডারে আউটপুট পুনঃনির্দেশ করে
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একটি সাধারণ লিনাক্স ক্যালকুলেটরে পাইপ দেয়
Streamlining @ 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
জামস্যাচের মতো, আমি 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 সাল থেকে সেকেন্ডের সংখ্যা হিসাবে ব্যবহার করি The ফলাফল "তারিখ" বছরের বছর, সময় এবং ন্যানোসেকেন্ড হিসাবে ফর্ম্যাট হয়। বছরের সেই দিন থেকে আমরা একটিকে বিয়োগ করি, যেহেতু শূন্য সেকেন্ডের একটি ইনপুট ইতিমধ্যে ১৯ 1970০ সালের প্রথম দিনকে নিয়ে যায় I আমি মনে করি না যে শূন্য থেকে শুরু করে বছরের দিনটি পাওয়ার কোনও উপায় আছে।
ফাইনালটি 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 আপনার সমস্ত ফাইলের সময়কাল ২৪ ঘন্টা (অর্থাৎ ৮6464০০ সেকেন্ড) থাকলে এই পদ্ধতিতে ব্যবহার করা কেবলমাত্র কাজ করবে। আপনার যদি এমন কিছু প্রয়োজন হয় যা বড় সময়সীমা পরিচালনা করতে পারে তবে আপনি বিকল্প হিসাবে এটি ব্যবহার করতে পারেন:
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-)
গৃহীত উত্তরটি বন্ধ করে দেওয়া এবং ক্লাসিক ইউনিক্স রিভার্স-পলিশ সরঞ্জামটি ব্যবহার করে:
{ find . -maxdepth 2 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 \
-show_entries format=duration {} \; ; printf '+\n60\n*\np'; } | dc
783.493000
উদাহরণস্বরূপ: সংযোজন +এবং 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'
আপনি এমপি্লেয়ার ইনস্টল করেছেন তা নিশ্চিত হয়ে নিন ।
যেমন ffmpeg এর পরিবর্তে উবুন্টু শিপ লিবাভ:
#!/bin/sh
for f in *.mp4; do
avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc
ভারী এমভিজি ধারণাগুলির উপর ভিত্তি করে
ঠিক আছে, এই সমস্ত সমাধানটির জন্য কিছুটা কাজ করা দরকার, আমি যা করেছি তা খুব সহজ, 1)
পছন্দসই ফোল্ডারে যান এবং ডান ক্লিক করুন -> অন্যান্য অ্যাপ্লিকেশন সহ খুলুন
তারপরে ভিএলসি মিডিয়া প্লেয়ার নির্বাচন করুন,
এখানে উদাহরণ
আপনি কেবল সরঞ্জামদণ্ডের নীচে দেখতে পাচ্ছেন, প্লেলিস্টটি [10:35:51] লিখিত আছে, সুতরাং ফোল্ডারে 10 ঘন্টা 35 মিনিট এবং মোট ভিডিওর 51 সেকেন্ড সময়কাল থাকে