Tuesday 1 January 2019

ffmpeg - How to split video files upon detected change in resolution? (ie. recorded streams containing multiple widths)

I have many video files (flv/mp4) that change resolution mid-stream (720p/1080p/640).


I would like to use something like ffmpeg to automatically detect the change in resolution and split the videos into their individual scenes, keeping their existing encoding quality: segment without re-encoding (Video1-scene1.flv, Video1-scene2.flv, etc).


I have found various methods to split upon silence, upon scene change, upon black scenes, but nothing as simple as a change in resolution width.


These files often cause video editors/trimmers to crash, and manually identifying and removing low resolution scenes is very time consuming if I simply convert the entire video to 1080p.


The algorithm is probably as simple as comparing the current frame to the previous frame, and if they are different resolutions, split the video and start a new segment.


Can anyone help please?


EXAMPLE FILE (temporarily available): Example.flv


Below are a few related answers:


Cut part from video file from start position to end position with FFmpeg


https://stackoverflow.com/questions/36074224/how-to-split-video-or-audio-by-silent-parts


Automatically split large .mov video files into smaller files at black frames (scene changes)?


Split Up a Video Using FFMPEG through Scene Detection


Additional Resources:
Using Lord Neckbeard's solution, I am attaching the (unfortunately very manual) process that I eventually got to work on Windows10. Perhaps it can spawn other ideas around ffmpeg.
(I posted a separate question for anyone who is GURU enough to: Automate this process...)


drag video onto a batch file that contains:



ffprobe -v error -show_entries frame=pkt_pts_time,width,height -select_streams v -of csv=p=0 %1 > allkeyframes.txt



(allkeyframes.txt sample...)


13.652000,640,480
13.755000,640,480
13.597000,480,360
13.652000,480,360

paste this text in POWERSHELL:


$o=""
$n=0
foreach($line in (Get-Content allkeyframes.txt)){
$nline = $line.Split(",")
$nline2=($nline[1]+$nline[2])
if ($nline2 -ne $preventry) {
$n0=$nline[0]
$o="$o,$n0"
$n=$n0
}
$preventry = $nline2
}
if ($o.length -gt 1){
echo $o.Remove(0,1) > resolutionchanges.txt
} else {
Write-Host "No resolution changes found" -ForegroundColor Red
}

(resolutionchanges.txt:)


13.597000,25.618000,33.628000,45.598000

enter the following in the command window, after pasting contents of resolutionchanges.txt and changing "input.flv" to the video name (Win10 refused my attempts at batching this):



ffmpeg -i input.flv -map 0 -c copy -segment_times 13.597000,25.618000,33.628000,45.598000 -reset_timestamps 1 -f segment output_%03d.flv


No comments:

Post a Comment

Where does Skype save my contact's avatars in Linux?

I'm using Skype on Linux. Where can I find images cached by skype of my contact's avatars? Answer I wanted to get those Skype avat...