काले दृश्यों द्वारा लंबे वीडियो को छोटे अध्यायों में विभाजित करने के लिए दो पॉवरशेल स्क्रिप्ट हैं।
उन्हें Detect_black.ps1 और Cut_black.ps1 के रूप में सहेजें। विंडोज के लिए ffmpeg डाउनलोड करें और विकल्प अनुभाग के तहत स्क्रिप्ट को अपने ffmpeg.exe और अपने वीडियो फ़ोल्डर का पथ बताएं।
दोनों स्क्रिप्ट मौजूदा वीडियो फ़ाइलों को स्पर्श नहीं करेंगे, वे अछूते नहीं रहेंगे।
हालाँकि, आपको कुछ नई फाइलें उसी स्थान पर मिलेंगी जहाँ आपके इनपुट वीडियो हैं
- उपयोग किए गए ffmpeg कमांड के लिए कंसोल आउटपुट के साथ प्रति वीडियो लॉगफ़ाइल
- मैन्युअल ठीक ट्यूनिंग के लिए काले दृश्यों के सभी टाइमस्टैम्प के साथ एक सीएसवी फ़ाइल प्रति वीडियो
- नए वीडियो के एक जोड़े पर निर्भर करता है कि पहले कितने काले दृश्य हैं
चलाने के लिए पहली स्क्रिप्ट: Detect_black.ps1
### Options __________________________________________________________________________________________________________
$ffmpeg = ".\ffmpeg.exe" # Set path to your ffmpeg.exe; Build Version: git-45581ed (2014-02-16)
$folder = ".\Videos\*" # Set path to your video folder; '\*' must be appended
$filter = @("*.mov","*.mp4") # Set which file extensions should be processed
$dur = 4 # Set the minimum detected black duration (in seconds)
$pic = 0.98 # Set the threshold for considering a picture as "black" (in percent)
$pix = 0.15 # Set the threshold for considering a pixel "black" (in luminance)
### Main Program ______________________________________________________________________________________________________
foreach ($video in dir $folder -include $filter -exclude "*_???.*" -r){
### Set path to logfile
$logfile = "$($video.FullName)_ffmpeg.log"
### analyse each video with ffmpeg and search for black scenes
& $ffmpeg -i $video -vf blackdetect=d=`"$dur`":pic_th=`"$pic`":pix_th=`"$pix`" -an -f null - 2> $logfile
### Use regex to extract timings from logfile
$report = @()
Select-String 'black_start:.*black_end:' $logfile | % {
$black = "" | Select start, end, cut
# extract start time of black scene
$start_s = $_.line -match '(?<=black_start:)\S*(?= black_end:)' | % {$matches[0]}
$start_ts = [timespan]::fromseconds($start_s)
$black.start = "{0:HH:mm:ss.fff}" -f ([datetime]$start_ts.Ticks)
# extract duration of black scene
$end_s = $_.line -match '(?<=black_end:)\S*(?= black_duration:)' | % {$matches[0]}
$end_ts = [timespan]::fromseconds($end_s)
$black.end = "{0:HH:mm:ss.fff}" -f ([datetime]$end_ts.Ticks)
# calculate cut point: black start time + black duration / 2
$cut_s = ([double]$start_s + [double]$end_s) / 2
$cut_ts = [timespan]::fromseconds($cut_s)
$black.cut = "{0:HH:mm:ss.fff}" -f ([datetime]$cut_ts.Ticks)
$report += $black
}
### Write start time, duration and the cut point for each black scene to a seperate CSV
$report | Export-Csv -path "$($video.FullName)_cutpoints.csv" –NoTypeInformation
}
यह कैसे काम करता है
पहली स्क्रिप्ट सभी वीडियो फ़ाइलों के माध्यम से पुनरावृत्ति करती है जो एक निर्दिष्ट विस्तार से मेल खाती है और पैटर्न *_???.*
से मेल नहीं खाती है , क्योंकि नए वीडियो अध्याय का नाम दिया गया था <filename>_###.<ext>
और हम उन्हें बाहर करना चाहते हैं।
यह सभी काले दृश्यों को खोजता है और नाम के एक नए CSV फ़ाइल में प्रारंभ टाइमस्टैम्प और ब्लैक सीन अवधि लिखता है <video_name>_cutpoints.txt
यह भी कटौती अंक दिखाया गया है गणना करता है: cutpoint = black_start + black_duration / 2
। बाद में, वीडियो इन टाइमस्टैम्प पर खंडित हो जाता है।
आपके नमूना वीडियो के लिए cutpoint.txt फ़ाइल दिखाई देगी:
start end cut
00:03:56.908 00:04:02.247 00:03:59.578
00:08:02.525 00:08:10.233 00:08:06.379
एक रन के बाद, आप चाहें तो कट पॉइंट्स को मैन्युअल रूप से जोड़ सकते हैं। यदि आप स्क्रिप्ट को फिर से चलाते हैं, तो सभी पुरानी सामग्री अधिलेखित हो जाती है। मैन्युअल रूप से संपादन करते समय सावधान रहें और अपना काम कहीं और बचाएं।
नमूना वीडियो के लिए काले दृश्यों का पता लगाने के लिए ffmpeg कमांड है
$ffmpeg -i "Tape_10_3b.mp4" -vf blackdetect=d=4:pic_th=0.98:pix_th=0.15 -an -f null
3 महत्वपूर्ण संख्याएं हैं जो स्क्रिप्ट के विकल्प अनुभाग में संपादन योग्य हैं
d=4
मतलब केवल 4 सेकंड से अधिक लंबे काले दृश्यों का पता लगाया जाता है
pic_th=0.98
"काले" के रूप में एक तस्वीर पर विचार करने के लिए सीमा है (प्रतिशत में)
pix=0.15
पिक्सेल को "ब्लैक" (ल्यूमिनेन्स में) के रूप में मानने के लिए सीमा निर्धारित करता है। चूंकि आपके पास पुराने वीएचएस वीडियो हैं, इसलिए आपके वीडियो में पूरी तरह से काले दृश्य नहीं हैं। डिफ़ॉल्ट मान 10 काम नहीं करेगा और मुझे सीमा को थोड़ा बढ़ाना पड़ा
यदि कुछ भी गलत होता है, तो उस लॉगफ़ाइल नामक जाँच करें <video_name>__ffmpeg.log
। यदि निम्नलिखित पंक्तियाँ गायब हैं, तो उपरोक्त संख्याएँ तब तक बढ़ाएँ जब तक आप सभी काले दृश्यों का पता नहीं लगा लेते:
[blackdetect @ 0286ec80]
black_start:236.908 black_end:242.247 black_duration:5.33877
चलाने के लिए दूसरी स्क्रिप्ट: cut_black.ps1
### Options __________________________________________________________________________________________________________
$ffmpeg = ".\ffmpeg.exe" # Set path to your ffmpeg.exe; Build Version: git-45581ed (2014-02-16)
$folder = ".\Videos\*" # Set path to your video folder; '\*' must be appended
$filter = @("*.mov","*.mp4") # Set which file extensions should be processed
### Main Program ______________________________________________________________________________________________________
foreach ($video in dir $folder -include $filter -exclude "*_???.*" -r){
### Set path to logfile
$logfile = "$($video.FullName)_ffmpeg.log"
### Read in all cutpoints from *_cutpoints.csv; concat to string e.g "00:03:23.014,00:06:32.289,..."
$cuts = ( Import-Csv "$($video.FullName)_cutpoints.csv" | % {$_.cut} ) -join ","
### put together the correct new name, "%03d" is a generic number placeholder for ffmpeg
$output = $video.directory.Fullname + "\" + $video.basename + "_%03d" + $video.extension
### use ffmpeg to split current video in parts according to their cut points
& $ffmpeg -i $video -f segment -segment_times $cuts -c copy -map 0 $output 2> $logfile
}
यह कैसे काम करता है
दूसरी स्क्रिप्ट उसी तरह से सभी वीडियो फ़ाइलों पर निर्भर करती है जिस तरह से पहली स्क्रिप्ट ने की है। यह वीडियो की संगत से केवल कट टाइमस्टैम्प में पढ़ता है cutpoints.txt
।
अगला, यह अध्याय फ़ाइलों के लिए एक उपयुक्त फ़ाइल नाम रखता है और वीडियो को खंडित करने के लिए ffmpeg को बताता है। वर्तमान में वीडियो फिर से एन्कोडिंग (सुपरफास्ट और दोषरहित) के बिना कटा हुआ है। इसके कारण, कट प्वाइंट टाइमस्टैम्प के साथ 1-2s की अशुद्धि हो सकती है क्योंकि ffmpeg केवल key_frames पर कट कर सकता है। चूंकि हम सिर्फ कॉपी करते हैं और फिर से एनकोड नहीं करते हैं, इसलिए हम अपने दम पर key_frames नहीं डाल सकते हैं।
नमूना वीडियो के लिए आदेश होगा
$ffmpeg -i "Tape_10_3b.mp4" -f segment -segment_times "00:03:59.578,00:08:06.379" -c copy -map 0 "Tape_10_3b_(%03d).mp4"
कुछ भी गलत होने पर संबंधित ffmpeg.log पर एक नज़र डालें
संदर्भ
करने के लिए
ओपी से पूछें कि क्या सीएसवी प्रारूप कट फ़ाइल के रूप में पाठ फ़ाइल से बेहतर है, इसलिए आप उन्हें एक्सेल के साथ थोड़ा आसान संपादित कर सकते हैं
»लागू किया गया
टाइमस्टैम्प को [hh] के रूप में प्रारूपित करने का तरीका लागू करें: [mm]: [ss], [मिलीसेकंड] केवल सेकंड के बजाय
»कार्यान्वित
प्रत्येक अध्याय के लिए मोज़ेक png फ़ाइलों को बनाने के लिए एक ffmpeg कमांड को
लागू करें »कार्यान्वित किया गया
यदि -c copy
ओपी के परिदृश्य के लिए पर्याप्त है या हमें पूरी तरह से फिर से एनकोड करने की आवश्यकता है, तो विस्तृत करें ।
लगता है कि रयान पहले से ही इस पर है ।