LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   ffmpeg chopping up a movie into chunks (https://www.linuxquestions.org/questions/linux-software-2/ffmpeg-chopping-up-a-movie-into-chunks-4175656930/)

GPGAgent 07-05-2019 01:11 PM

ffmpeg chopping up a movie into chunks
 
I have a great little script that makes a new movie file from chopped up chunks of a list of movies, (thanks to help from this forum) except for two problems.

The problem is the first chopped portion always has a delay before playing, can be anything from 0.5 seconds to 4 or 5 seconds. I think this has something to do with key frames?

The second problem is although I select, say a 10 second length of each chopped out portion of movie, this can vary from chunk to chunk so they could be 4 seconds long or even 20 seconds long.

Here's the command line:
Code:

ffmpeg -ss 100 -t 60 -y -i movie.mp4 -c copy -map 0 -segment_time 10 -f segment -reset_timestamps 1 output%03d.mp4
So I'm getting output for 60 seconds 100seconds into the movie and this is the output:
Code:

-rwxrwxrwx 1 charlie charlie 3.8M Jul  5 18:55 output000.mp4
-rwxrwxrwx 1 charlie charlie 827K Jul  5 18:55 output001.mp4
-rwxrwxrwx 1 charlie charlie 1.4M Jul  5 18:55 output002.mp4
-rwxrwxrwx 1 charlie charlie 1.4M Jul  5 18:55 output003.mp4
-rwxrwxrwx 1 charlie charlie 642K Jul  5 18:55 output004.mp4
-rwxrwxrwx 1 charlie charlie 904K Jul  5 18:55 output005.mp4

All looks good but you can see that the first cut is really large, the fifth cut is even small. And the first file is frozen for 3 seconds before playing.

I think I'm missing a parameter but cannot figure out what it is.

Help please?

GPGAgent 07-06-2019 11:51 AM

As I suspected this was due to not setting key frame, and after a lot of testing, trial and error and help from google I've come up with an ffmpeg command that can do this all in one.
It cuts, letterboxes, sets a key frame and then chops the cut part up into chunks of equal size and no freezing of the first chunk.

Here's the command:
Code:

ffmpeg -ss $STARTAT -y -i $FF -vcodec libx264 -r 25 -filter:v "scale=(iw*sar)*min(640/(iw*sar)\,360/ih):ih*min(640/(iw*sar)\,360/ih), pad=640:360:(640-iw*min(640/iw\,360/ih))/2:(360-ih*min(640/iw\,360/ih))/2" -b:v 500k -acodec aac -strict experimental -ss $CHOPLENGTH -t $DURATION  -g $CHOPLENGTH -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*$CHOPLENGTH)"  -map 0 -segment_time $CHOPLENGTH -f segment -reset_timestamps 1 CHOPPED-%03d.mp4
Explanation, I hace a script that prompts for a:
$STARTAT starting point eg 200 seconds
$FF a movie eg XXX.mp4
$CHOPLENGTH eg 15 seconds
$DURATION length of movie to chop into chunks eg 60 seconds
So this would result in 4 chunks of 15 seconds each from 200 seconds into the movie
pretty coll huh!

X-LFS-2010 07-06-2019 07:06 PM

#1 that's still an improperly chopped and stringed mpeg. what you have now is a damaged mpeg movie. it's not a solution it's a hack.

mark it as solved then?

this forum is not for presenting code "you figured out" that others have not asked for

it is for asking others

syg00 07-06-2019 07:24 PM

Quote:

Originally Posted by X-LFS-2010 (Post 6012645)
this forum is not for presenting code "you figured out" that others have not asked for

it is for asking others

Rubbish - I for one appreciate seeing resolutions to issues, even if just for interest.
Who made you judge and jury ?.

GPGAgent 07-07-2019 12:30 PM

Quote:

Originally Posted by X-LFS-2010 (Post 6012645)
#1 that's still an improperly chopped and stringed mpeg. what you have now is a damaged mpeg movie. it's not a solution it's a hack.

mark it as solved then?

this forum is not for presenting code "you figured out" that others have not asked for

it is for asking others

Hi Thanks for that, I've marked this as UNSOLVED now because of your comment, so if anyone can solve it please feel free, hacks aren't allowed on this forum :-(

GPGAgent 07-07-2019 12:58 PM

Anyway, besides X-LFS-2010 comment, I found my "hack" still creates a movie that freezes, not to start with but some point through the video.

So a bit more research I reread https://trac.ffmpeg.org/wiki/Concatenate

and added a bit to my script to convert my chopped up files to an intermediate .ts format with this command:
Code:

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
and once all my chopped up files have been converted I joined them with this command:
Code:

ffmpeg -f mpegts -i "concat:temp1|temp2" -c copy -bsf:a aac_adtstoasc output.mp4

So far this seems to work, just a bit more testing with a load more movie files.

Then I'm going to see if I can convert the original movies to ts after cutting, letterboxing and adding some time flags.

It's an amazing tool ffmpeg and I feel I'm just scratching the surface.

GPGAgent 07-08-2019 05:08 PM

Quote:

Originally Posted by X-LFS-2010 (Post 6012645)
#1 that's still an improperly chopped and stringed mpeg. what you have now is a damaged mpeg movie. it's not a solution it's a hack.

mark it as solved then?

this forum is not for presenting code "you figured out" that others have not asked for

it is for asking others

Just for you X-LFS-2010, I've been doing more hacking and come up with a slightly modified version, this is all in a bash script that prompts for the input parameters, file names to process, like *.mp4, or *.*, the startpoint and duration in seconds, the chop size, the video bit rate and the letterbox size (note running in a letterbox means it can handle any aspect ratio of original, but ourputs a constant size video so they can be joined.

So step 1 is to cut, letter box, and flag the input files to .mp4 container
Code:

ffmpeg -ss 100 -y -i test.mp4 -t 120 -ss 13 -vcodec libx264 -r 25 -filter:v "scale=(iw*sar)*min(640/(iw*sar)\,360/ih):ih*min(640/(iw*sar)\,360/ih), pad=640:360:(640-iw*min(640/iw\,360/ih))/2:(360-ih*min(640/iw\,360/ih))/2" -b:v 500k -acodec aac -strict experimental -g 13 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*13)" CLB.mp4
Step 2 is to chop it up into stream style .ts files
Code:

ffmpeg  -y -i CLB.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts  -map 0 -segment_time 13 -f segment -reset_timestamps 1 CHOPPED-test-%03d.ts
Step 3 is to randomise the .ts files
Code:

for movies in CHOPPED-*.ts
 do mv -f "$movies" CHOPPED-$(shuf -i 100000-999999 -n 1).ts
done

Step 4 is to join the .ts files and re-encode to .mp4 containers
Code:

for i in {0..9}
 do
 ls CHOPPED-$i*.ts; ls CHOPPED-$i*.ts | perl -ne 'print "file $_"' | ffmpeg -y -f concat -i - -c copy -bsf:a aac_adtstoasc JOINED-$i.mp4
 done



Seems to work, files playback correctly, but I need to do more extensive testing, so it's not solved yet!

GPGAgent 07-10-2019 12:42 PM

Quote:

Originally Posted by GPGAgent (Post 6013217)
Seems to work, files playback correctly, but I need to do more extensive testing, so it's not solved yet!

As I suspected my hack is still not 100% perfect, running 200 movie files through this process causes a few to have a really long duration when it hasn't. Not sure which file causes and why so I'm going to keep the .ts files and find the rogue ones and either delete them of analyse the original movie to see why its wrong and either fix or skip it.

Shadow_7 07-11-2019 07:04 PM

keyframes and groups of pictures. You would probably need to re-encode the whole video with iframes (everyframe is a keyframe), then chunk that out. Or other such trickery. In either case, to break it up mid group-of-pictures will require re-encoding the video. Which is an imperfect copy with compression and artifacts. The file sizes differ because the movement differs, as lots of movement does not compress well.

GPGAgent 07-14-2019 08:28 AM

Quote:

Originally Posted by Shadow_7 (Post 6014234)
keyframes and groups of pictures. You would probably need to re-encode the whole video with iframes (everyframe is a keyframe), then chunk that out. Or other such trickery. In either case, to break it up mid group-of-pictures will require re-encoding the video. Which is an imperfect copy with compression and artifacts. The file sizes differ because the movement differs, as lots of movement does not compress well.

Absolutely correct, I've finally figured how to put it all together to letterbox, add keyframes, and set the audio, video and frame rates, cut a segment from the main video and then cop it up into equal length chunks, all in one neat ffmpeg command line and this is it (note all parameters are prompted for and are self explanatory):

ffmpeg -ss $ss -y -i $FF -r 29.97 -vcodec libx264 -r 29.97 -filter:v "$LETTERBOX_PARM" -b:v ${VideoBitRate} -acodec aac -strict experimental -ss $CHOPLENGTH -t $t -g $CHOPLENGTH -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*$CHOPLENGTH)" -map 0 -segment_time $CHOPLENGTH -f segment -reset_timestamps 1 CHOPPED-$CHOPLENGTH-${FF::-4}-%03d.mp4

and

LETTERBOX_PARM="scale=(iw*sar)*min($width/(iw*sar)\,$height/ih):ih*min($width/(iw*sar)\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2"

This is done in a loop through many videos, where FF is the video name eg zxc.mp4, or zxc.wmv and so on

Then the script renames the videos to a six digit random number so that when joined up again it's a new movie of chunks in random order, like the shuffle effect on a cd-player.

Here is where I just could not get an "ffmpeg concat" script to work, so I resorted to mmcat.sh which can be found here: https://trac.ffmpeg.org/wiki/mmcat

Usage is
Code:

mmcat.sh file1.mp4 file2.mp4 file3.mp4 outputfile.mp4
The input list can have a wild card like this: mmcat.sh $i*.mp4 mmcat-out.mp4[/CODE]

So that's it for now, post solved


All times are GMT -5. The time now is 07:41 PM.