ต่อไปนี้เป็นสคริปต์ PowerShell สองตัวเพื่อแยกวิดีโอขนาดยาวเป็นบทย่อย ๆ ด้วยฉากสีดำ
บันทึกเป็น Detect_black.ps1 และ Cut_black.ps1 ดาวน์โหลดffmpeg สำหรับ Windowsและบอกสคริปต์เกี่ยวกับเส้นทางไปยัง ffmpeg.exe และโฟลเดอร์วิดีโอของคุณในส่วนตัวเลือก
สคริปต์ทั้งสองจะไม่แตะไฟล์วิดีโอที่มีอยู่โดยจะไม่มีการแตะต้อง
อย่างไรก็ตามคุณจะได้รับไฟล์ใหม่สองไฟล์ในที่เดียวกับที่คุณใส่วิดีโอ
- ล็อกไฟล์ต่อวิดีโอที่มีเอาต์พุตคอนโซลสำหรับทั้งคำสั่ง ffmpeg ที่ใช้
- ไฟล์ CSV ต่อวิดีโอที่มีการประทับเวลาทั้งหมดของฉากสีดำสำหรับการปรับจูนแบบแมนนวล
- วิดีโอใหม่สองสามรายการขึ้นอยู่กับจำนวนฉากสีดำที่ตรวจพบก่อนหน้านี้
สคริปต์แรกที่เรียกใช้: 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
นอกจากนี้ยังคำนวณจุดตัดดังแสดง: หลังจากนั้นวิดีโอจะแบ่งกลุ่มตามการประทับเวลาเหล่านี้
ไฟล์ cutpoints.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
ตั้งค่าขีด จำกัด สำหรับการพิจารณาพิกเซลเป็น "ดำ" (ในความสว่าง) เนื่องจากคุณมีวิดีโอ VHS เก่าคุณจึงไม่มีฉากสีดำสนิทในวิดีโอของคุณ ค่าเริ่มต้นที่ 10 จะไม่ทำงานและฉันต้องเพิ่มเกณฑ์เล็กน้อย
ถ้ามีอะไรผิดพลาดตรวจสอบ logfile <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-2 วินาทีกับการประทับเวลาของจุดตัดเนื่องจาก 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 ที่เกี่ยวข้อง
อ้างอิง
ทำ
ถาม OP ว่ารูปแบบ CSV นั้นดีกว่าไฟล์ข้อความเป็นไฟล์จุดตัดหรือไม่ดังนั้นคุณสามารถแก้ไขด้วย Excel ได้ง่ายขึ้น
»นำไปใช้
ใช้วิธีการจัดรูปแบบการประทับเวลาเป็น [hh]: [mm]: [ss], [มิลลิวินาที] แทนที่จะใช้เวลาเพียงไม่กี่วินาที
»นำไปใช้
ใช้คำสั่ง ffmpeg เพื่อสร้างไฟล์ mosaik png สำหรับแต่ละบท
»นำมาใช้
อธิบายอย่างละเอียดว่า-c copy
เพียงพอสำหรับสถานการณ์ของ OP หรือเราจำเป็นต้องเข้ารหัสใหม่ทั้งหมด
ดูเหมือนว่าไรอันอยู่ในนั้นแล้ว