একটি ডিরেক্টরিতে ভিডিও ফাইলের মোট সময়কাল পান


30

আমার কাছে .tsফাইলগুলির একটি তালিকা রয়েছে :

out1.ts ... out749.ts   out8159.ts  out8818.ts

আমি এই সমস্ত ফাইলের মোট সময়কাল (চলমান সময়) কীভাবে পেতে পারি?


আপনি একটি একক ফাইলের সময়কাল কীভাবে পাবেন?
হাউক লেগেইন

আমি এটিও জানি না
k961

@ হউক লিগিং আমি এই প্রোগ্রামটি "মিডিয়েনফো" পেয়েছি
k961

এগুলি হ'ল মিডিয়া ফাইল, সম্ভবত ভিডিও।
slm

1
যে কোনও মিডিয়া ফাইল (যেমন: এমপি 4, এএসএফ & .264 ...) এর পূর্বনির্ধারিত মানক শিরোনামের তথ্য থাকবে, আমরা ফাইলটি রেজোলিউশন, ফ্রেম রেট, ফ্রেমের সংখ্যা (জিওপি) এবং ফাইলের দৈর্ঘ্য এবং সময়কাল এর মতো তথ্য পেতে পারি মিডিয়া ...
কান্টাম নাগেশ

উত্তর:


55

আমার .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
slm

1
সঙ্গে সুন্দর কৌতুক pasteএবং bc! awkবলার চেয়ে অনেক ক্লিনার ।
fduff

@fduff। যদিও bcঅবাধ স্পষ্টতা কি করতে হবে, এক অপূর্ণতা যে ...| paste -sd+ - | bcপারেন কিছু লাইন সীমাকে পৌঁছবে bcবাস্তবায়নের (উদাহরণস্বরূপ seq 429 | paste -sd+ - | bcOpenSolaris সঙ্গে ব্যর্থ bc) অথবা অন্যদের মধ্যে সব স্মৃতি ব্যবহার করে সম্ভাব্য আছে।
স্টাফেন চেজেলাস

আপনি অ্যাভকনভের মতো কিছু দিয়ে এই (ffprobe পদ্ধতি) করতে পারেন? কুবুন্টু 14.04 এর জন্য আমার রেপোগুলিতে আমি ffmpeg খুঁজে পাচ্ছি না - সুতরাং আমার কাছে ffprobe নেই? আমার কাছে অ্যাপ্রপ্রোব রয়েছে তবে এটি যুক্তিগুলি পছন্দ করে না।
জো

@ জো - avprobeআর্চ রেপোসে নেই (প্রলি কারণ এটির সাথে দ্বন্দ্ব রয়েছে ffmpeg) তাই এটিএম চেষ্টা করে দেখতে পারবেন না তবে আপনি যদি ফাইলটি চালিয়ে যান তবে এটি আপনাকে সময়কাল দেয়: avprobe -show_format_entry duration myfile.mp4বা avprobe -loglevel quiet -show_format_entry duration myfile.mp4? আমি মনে করি এই কমান্ডগুলির মধ্যে একটি আপনাকে ফাইলের সময়কাল সহ একক আউটপুট দেয় give যদিও নিশ্চিত না।
don_crissti

6

এটি 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একটি সাধারণ লিনাক্স ক্যালকুলেটরে পাইপ দেয়


1
নিস! এছাড়াও আমার সংস্করণটি দেখুন যা আপনার ধারণাগুলির উপর নির্ভর করে।
এমভিজি

সংক্ষিপ্ত এবং মার্জিত সমাধান
নিও

4

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সেটিং আশা করছি, ইউটিসি ব্যবহার জোর করে ব্যবহার যাতে দিবালোক সংরক্ষণ সময় হস্তক্ষেপ করবে না উচিত সত্যিই বড় ভিডিওটি সংগ্রহ। আপনার যদি এক বছরেরও বেশি মূল্যবান ভিডিও থাকে তবে এখনও এই পদ্ধতির কাজ হবে না।


3

আমি এই .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

সেকেন্ডে সমস্ত ফাইলের মোট সময়কালীন ফলাফল। এটি অবশ্যই প্রয়োজনে অন্য কোনও ফর্ম্যাটে রূপান্তরিত হতে পারে।


@ ডামেনসালভাতোর - কোনও সমস্যা নেই, আশা করি এটি আপনাকে দেখায় যে কীভাবে আপনি বিভিন্ন পদক্ষেপে টাস্কটি ভেঙে ফেলতে পারেন, তাই আপনি এটি প্রয়োজনীয় হিসাবে কাস্টমাইজ করতে পারেন।
slm

@ এসএলএম - আমি ভিডিওর সময়কালকে কয়েক সেকেন্ডে রূপান্তর করতে অন্য উপায় ব্যবহার করব কারণ dateযদি ffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"এমন কিছু ফিরে আসে 26:33:21.68(যেমন, সময়কাল ≥ 24 ঘন্টা / 86400 সেকেন্ড)
ডোন_ক্রিসটি

@ ডন_ক্রিসটি - ধন্যবাদ, এটি পরীক্ষা করার সময় আমি 20 ঘন্টারও বেশি চেষ্টা করে দেখিনি। আমি একটি বিকল্প পদ্ধতি দেখায় একটি নোট যুক্ত করব।
slm

আপনার উত্তরের জন্য ধন্যবাদ! এটি কেবল আমার অনুপ্রেরণাই নয়, এটি pasteআমার নজরে এনেছিল । আমি অনুমান java -classpath $(find -name \*.jar | paste -sd:)হতে যাচ্ছে খুব হ্যাক আমি অতীতে এই জন্য ব্যবহার করা চাই বিবেচনায় আমার কাছে দরকারী।
এমভিজি

@ এমভিজি - pasteআমার প্রিয় কমান্ড 8-)
slm

1

গৃহীত উত্তরটি বন্ধ করে দেওয়া এবং ক্লাসিক ইউনিক্স রিভার্স-পলিশ সরঞ্জামটি ব্যবহার করে:

{ 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আপনি আপনার যোগফল পাবেন।


2
bcউপায় অনেক বেশি ভালবাসা পায়। আপনি সমস্ত দিচ্ছি +প্রতিটি লাইনে মধ্যে লক্ষণ (চালু যোগদান +), যেহেতু বিপরীত পোলিশ সঙ্গে আপনি শুধুমাত্র একটি চাক করতে +প্রান্তে এবং p); এটি ব্যবহার করে দ্রণ
যেমন AT

0
$ 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'

আপনি এমপি্লেয়ার ইনস্টল করেছেন তা নিশ্চিত হয়ে নিন ।


এটি আমাকে কোনও আউটপুট দেয় না
k961

আপনি কি এমপ্লেয়ার এবং পার্ল ইনস্টল করেছেন?
ryanmjacobs

হ্যাঁ আমি এমপ্লেয়ার ইনস্টল করেছি এবং পার্ল ইতিমধ্যে ইনস্টল করা হয়েছিল
k961

1
দুঃখিত, আমি জানি না কেন এটি কাজ করছে না; তবে, আপনার কাছে ইতিমধ্যে যাইহোক ইতিমধ্যে যথেষ্ট শালীন উত্তর রয়েছে। :)
ryanmjacobs

0

যেমন ffmpeg এর পরিবর্তে উবুন্টু শিপ লিবাভ:

#!/bin/sh
for f in *.mp4; do
    avprobe -v quiet -show_format_entry duration "$f"
done | paste -sd+ | bc

ভারী এমভিজি ধারণাগুলির উপর ভিত্তি করে


0

ঠিক আছে, এই সমস্ত সমাধানটির জন্য কিছুটা কাজ করা দরকার, আমি যা করেছি তা খুব সহজ, 1)

  1. পছন্দসই ফোল্ডারে যান এবং ডান ক্লিক করুন -> অন্যান্য অ্যাপ্লিকেশন সহ খুলুন

  2. তারপরে ভিএলসি মিডিয়া প্লেয়ার নির্বাচন করুন,

  3. এটি ভিডিওগুলির মধ্যে একটি খেলতে শুরু করবে তবে তারপরে
  4. সিটিআরএল + এল টিপুন এবং আপনি ভিডিওগুলির প্লেলিস্ট দেখতে পাবেন এবং কোথাও উপরের বাম কোণে আপনি মোট সময়কাল দেখতে পাবেন

এখানে উদাহরণ

1। তালিকাবদ্ধ

2।এখানে চিত্র বর্ণনা লিখুন

3।এখানে চিত্র বর্ণনা লিখুন

আপনি কেবল সরঞ্জামদণ্ডের নীচে দেখতে পাচ্ছেন, প্লেলিস্টটি [10:35:51] লিখিত আছে, সুতরাং ফোল্ডারে 10 ঘন্টা 35 মিনিট এবং মোট ভিডিওর 51 সেকেন্ড সময়কাল থাকে


0

আমার বর্তমান ফোল্ডারে সাব-ডিরেক্টরি ছিল তাই আমাকে সময়কাল পুনরাবৃত্তভাবে গণনা করতে হয়েছিল:

find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.