5

I'm thinking of using ffmpeg to automate a simple video task. I have lots of action videos that go like this, quiet/boring -> loud/exciting -> quiet/boring. Allowing for a few seconds at the start and end of the exciting part I'd like to cut the quiet/boring bits. Can anyone give me some help on the filter/filters I might use?

5

I'm not well-versed with Unix shell scripting, and also only have basic proficiency in Windows scripting, so I can only offer a pseudocode flow of the script:

1) Break up your full video into N-second segments of only audio (into a temporary folder)

ffmpeg -i GoProFull.mp4 -vn -c:a copy -segment_time n -f segment GP%03d.mp4

Obviously, this will generate a sequence of MP4s where GPx.mp4 represents the n second audio starting at n*x seconds. You can get the exact value by running

ffprobe -i GPx.mp4

and parsing for Start: XX.YYYYYY

2) Run ffmpeg with the volumedetect filter on each of the files

ffmpeg -i GPx.mp4 -af volumedetect -f null - 2> GPx.log

This will produce an output with the final lines looking like this.

[Parsed_volumedetect_0 @ 0000000002584880] n_samples: 575488
[Parsed_volumedetect_0 @ 0000000002584880] mean_volume: -6.6 dB
[Parsed_volumedetect_0 @ 0000000002584880] max_volume: 0.0 dB
[Parsed_volumedetect_0 @ 0000000002584880] histogram_0db: 54799

There may be multiple histogram lines depending on your audio, but the mean and max are on the 2nd and 3rd lines.

3) Now your script should parse those last lines of each log

Check the detected mean and max volumes of each segment. Depending on how long your exciting parts are, and how much of a quiet interval there may be within an exciting segment, decide on whether to use the mean or max (or some evaluating expression involving both) and record the qualifying segment names in a formatted text file. Probably remove the prefix and keep only the unpadded numbers for the next part.

4) Prepare cut list

In the text file containing the numbers of the qualifying segments, collect consecutive segments together, so if your list is 3,4,7,11,13,14,15,18 then you want to treat it as 3+4, 7, 11, 13+14+15, and 18

5) Run ffmpeg to generate the cuts

Now for each cut, use the trim and atrim filter to make the cut. For a cut consisting of multiple segments starting with GPx and ending with GPy, the time codes for the cut is n*x - top seconds to n*(y+1) + tail seconds. You can use ffprobe to get the precise numbers.

ffmpeg -i GoProFull.mp4 -vf "trim=n*x-top:n*(y+1)+tail,setpts=PTS-STARTPTS" -af "atrim=n*x-top:n*(y+1)+tail,asetpts=PTS-STARTPTS" -{video and audio encoding parameters} GPcut-X.mp4

where X is the index of each generated segment.

Output each generated filename, one on each line, into a text file of the form

file 'GPcut-X.mp4'

6) Make into one video.

Run

ffmpeg -f concat -i cutlist.txt -c copy GoPro-Highlights.mp4

where cutlist.txt is the text file created in step 5.

| improve this answer | |
  • @Mulvya, I split the video into segments of 1 second, and the mean_volume of all of'em were alike. What could be the problem? Since I'm searching for pauses in speech, I can't go beyond 2 or 3 seconds. – Saeed Neamati Dec 15 '15 at 5:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.