ffmpeg segment to devide video into small chunks - ffmpeg

hello everyone I want to split my video into small chunks.I am using ffmpeg segment to achieve this and I want to split the video in same video lenght chunks.I am using ffmpeg segment to split the video.I have written the command
**ffmpeg -i first.mp4 -codec copy -map 0 -f segment -segment_time 10 -segment_list out.list SplitVideo/out%04d.mp4**
When I am executing this command it splits the video in to small chunks but it is not accurate.The chunks are not of same length

From personal experience I realized the following:
Depending on the video format, there are usually dependencies between different frames. It means that some frames are depended on some other frames to be decoded. Therefore the splitting MAYBE cannot be done at any time you want because some of these dependencies might get lost their connections and hence cannot be decoded later. So what ffmpeg does is actually to find the nearest point that is independent from previous frames so all dependencies are satisfied. This will cause different lengths.

Related

Prepending generated audio silence when merging audio w/ non-zero starting PTS and video with zero-based PTS for equal duration, aligned streams

When extracting segments from a media file with video and audio streams without re-encoding (-c copy), it is likely that the requested seek & end time specified will not land precisely on a keyframe in the source.
In this case, ffmpeg will grab the nearest keyframe of each track and position them with differing starting PTS values so that they remain in sync.
Video keyframes tend to be a lot more spaced apart, so you can often end up with something like this:
Viewing the clip in VLC, the audio will start at 5 seconds in.
However, in other video players or video editors I've noticed this can lead to some playback issues or a/v desync.
A solution would be to re-encode both streams when extracting the clip, allowing ffmpeg to precisely seek to the specified seek time and generating equal length & synced audio and video tracks.
However, in my case I do not want to re-encode the video, it is costly and produces lower quality video and/or greater file sizes. I would prefer to only re-encode the audio, filling the initial gap with generated silence.
This should be simple, but everything I've tried has failed to generate silence before the audio stream begins.
I've tried apad, aresample=sync=1, and using amerge to combine the audio with anullsrc. None of it works.
All I can think to possibly get around this is to use ffprobe on the misaligned source to retrieve the first audio PTS, and in a second ffmpeg process apply this value as a negative -itoffset, then concatting the audio track with generated silence lasting the duration of silence... But surely there's a better way, with just one instance of ffmpeg?
Any ideas?
I just stumbled across the solution by trying some more things.
I take the misaligned source media and process it with another ffmpeg instance with some audio filters:
ffmpeg -fflags +genpts -i input.mkv -c copy -c:a aac -af apad,aresample=async=1:first_pts=0 -ac 2 -shortest -y output.mkv
And it does exactly what I want, pads the beginning (and end) of the audio stream with silence making the audio stream equal length to the video.
The only drawback is that I can't combine this with my original ffmpeg command that extracts the clip, the only way this works is as a 2-step process.

How can I avoid an ffmpeg out of memory error

I use ffmpeg with complex filtering. Input are different sets of FULLHD surveilance camera videos each 10 to 15 seconds long. Set size (number of videos per set) varies. To remove unchanged frames I apply mpdecimate. To avoid being triggered by moving bushes but still keep objects I want to remain, I apply a complex filter:
split the video (the original and a dummy to detect motion/stills)
scale the dummy down (so the 8x8-block-metric of mpdecimate matches the size of moving objects I want to keep)
add white boxes to dummy to mask unintendedly moving objects
apply mpdecimate to dummy to remove non-changing frames
scale dummy back to original size
overlay the remaining frames of dummy with matching frames of original
All this works fine if the number of input videos is small (less than 100). The memory consupmtion of the ffmpeg process varies somewhere between 2GiB and 5GiB.
If the number of input files gets larger (say 200), the memory consumption suddenly jumps to insane numbers until memory (32GiB plus 33GiB swap) runs out and ffmpeg gets killed. I can not predict if and why this happens. I have one example, where a set of 340 videos worked using 6GiB. Any other set above 100 videos I tried eats all RAM in under two minutes and dies.
There is no particular error message from ffmpeg.
dmesg says:
Out of memory: Kill process 29173 (ffmpeg)
Killed process 29173 (ffmpeg) total-vm:66707800kB
My ffmpeg command:
ffmpeg -f concat -safe 0 -i vidlist -vf 'split=2[full][masked];[masked]scale=w=iw/4:h=ih/4,drawbox=w=51:h=153:x=101:y=0:t=fill:c=white,drawbox=w=74:h=67:x=86:y=49:t=fill:c=white,drawbox=w=51:h=149:x=258:y=0:t=fill:c=white,drawbox=w=13:h=20:x=214:y=103:t=fill:c=white,drawbox=w=29:h=54:x=429:y=40:t=fill:c=white,drawbox=w=35:h=49:x=360:y=111:t=fill:c=white,drawbox=w=26:h=54:x=304:y=92:t=fill:c=white,drawbox=w=48:h=27:x=356:y=105:t=fill:c=white,drawbox=w=30:h=27:x=188:y=124:t=fill:c=white,drawbox=w=50:h=54:x=371:y=7:t=fill:c=white,drawbox=w=18:h=38:x=248:y=107:t=fill:c=white,drawbox=w=21:h=51:x=242:y=33:t=fill:c=white,mpdecimate=hi=64*80:lo=64*40:frac=0.001,scale=w=iw*4:h=ih*4[deduped];[deduped][full]overlay=shortest=1,setpts=N/(15*TB),mpdecimate=hi=64*80:lo=64*50:frac=0.001,setpts=N/(15*TB)' -r 15 -c:v libx265 -preset slower -crf 37 -pix_fmt yuv420p -an result.mkv
ffmpeg version 4.1.6
Debian 4.19.171-2
I hope that my filter can be tuned in some way that achieves the same result but doesn't eat RAM that much - but I have no clue how. Within reasonable limits, I wouldn't mind if processing time suffers. Any hints appreciated.
It seems the memory issue can be avoided by removing the split filter. Instead of spliting one input into two streams (that ffmpeg has to store in memory) the same input can be loaded twice.
So instead of using "full" and "dummy" as below
ffmpeg -i source -vf 'split=2[full][dummy];...;[dummy][full]overlay...
one would use "0:v" and "1:v" as in
ffmpeg -i source -i scource -filter_complex '.....;[0:v][1:v]overlay...
I get this to work with input videos, but so far I fail to do this with the concat demuxer as input.
Any hints very welcome.

Merge two mkv videos in one but put theme in separate tracks

I want to make a video player that displays more video streams at the same time using the mkv format.
I build my app so that when it decodes an Mkv video it puts all frames from a cluster in memory, from what I observe when I read a video with only one video stream, every cluster except the last one has equal numbers of frames.
I want to merge tow mkv files in one, but at the same time, I want every cluster from the video to have equal numbers of frames from both tracks.
Is this thing possible using FFmpeg or another tool?
Use -frames:v:
ffmpeg -i input0.mkv -i input1.mkv -map 0 -map 1 -c copy -frames:v 100 output.mkv
To verify see Fetch frame count with ffmpeg.

How can I concatenate two very different mp3 files(diff bitrate, channels, samplerate, bitdeph)?

As input I get one mp3 file(input.mp3), then I need to split it into two separate parts(done that) and insert between those parts another mp3(second.mp3).
The problem:
I tried using every single command for concatenating files, converting them to .ts etc etc.
But I always get only the sound of the first mp3 file and the sound of the second is lost. I guess I have to transform my mp3 file into the exact same format as the input.mp3(bitrates, sample rates number of channels) file before I can concatenate it to it.
I could concatenate the two parts of the input.mp3, but no matter what I do I cannot concatenate with second.mp3.
I am using php with exec and ffmpeg.exe file. Is it possible to code it so no matter the input, I can transform second.mp3 into suitable for concatenating mp3?
How can I concatenate two very different mp3 files(diff bitrate, channels, samplerate, bitdeph)?
Let's start with each component...
bitrate
This one doesn't matter. MP3 streams can (and do!) change bitrate mid-stream. As long as you join on a frame header, you're fine.
bitdepth
The concept of sample bit depth doesn't exist within MP3. You can capture at 24-bit, encode to MP3, and the decoder will decode to 16-bit. (Or, with some command line switches, vice versa!) It's not a problem because bit depth doesn't apply.
sample rates
This is usually a problem. Most players don't assume they're going to change output sample rate mid-stream. Most players don't attempt to resample to stick to the rate they were already outputting at. I'm not surprised that you'd have some trouble with a changing sample rate.
channels
This is similar to the sample rate problem in that it requires changing the configuration of the output device. Even if the player supports it, it isn't going to be seamless. (Unless you were going from stereo to mono, where the mono could be easily upmixed to stereo.)
As input I get one mp3 file(input.mp3), then I need to split it into two separate parts(done that) and insert between those parts another mp3(second.mp3).
This actually presents another problem you haven't asked about... timing. MP3 works in relatively large frames (typically 576 samples), which becomes the resolution at which you can splice. Not good. Also, the starts of tracks often have a frame or two of initialization.
A third issue is the bit reservoir. This is where content from one frame is stored in a different frame that might have extra space.
At the end of the day, you're going to have to decode everything to regular PCM samples, do your splicing, and re-encode to MP3. You'll also have to re-sample everything to a common clock rate, and mix to a particular channel count. Fortunately, once decoded to PCM, this is all trivial and standard. Once your input streams are compatible, you an arbitrarily splice on a PCM frame which is the most granular possible.
If you want to concatenate or merge different bit rate and Mono and Stereo mp3 files into one mp3 file use ffmpeg libmp3lame library.
Command :
ffmpeg -i "concat:'url1.mp3'|'mono_url2.mp3'|'stereo_url3.mp3'" -c:a libmp3lame output_file.mp3
Use the atrim, asetpts, and concat filters:
ffmpeg -i input.mp3 -i second.mp3 -filter_complex "[0:a]atrim=end=10,asetpts=N/SR/TB[begin];[0:a]atrim=start=10,asetpts=N/SR/TB[end];[begin][1:a][end]concat=n=3:v=0:a=1[a]" -map "[a]" output
Note: All corresponding streams must have the same parameters in all segments; the filtering system will automatically select a common sample format, sample rate, and channel layout for audio streams. These common parameters will vary depending on the input parameters, so add the aformat filter (or equivalent) if you want consistent results:
ffmpeg -i input.mp3 -i second.mp3 -filter_complex "[0:a]atrim=end=10,aformat=sample_rates=44100:channel_layouts=stereo,asetpts=N/SR/TB[begin];[1:a]aformat=sample_rates=44100:channel_layouts=stereo[middle];[0:a]atrim=start=10,aformat=sample_rates=44100:channel_layouts=stereo,asetpts=N/SR/TB[end];[begin][middle][end]concat=n=3:v=0:a=1[a]" -map "[a]" output

ffmpeg split into frames

Hey, I want to split a video which is one second long (25fps)into 25 seperate video files. I know I can split it up into jpegs but I need to retain the audio. So when I recompile audio is still there.
This is what I tried to grab the first frame only (with audio):
ffmpeg -i 1.mov -vcodec mjpeg -qscale 1 -an -ss 00:00:00:00 -t 00:00:00:1 frame1.mov
But it doesn't seem to work. Am I wrong in assuming ffmpeg supports time stamps in this format? hh:mm:ss:f?
Thanks
You are wrong in assuming ffmpeg supports timestamps in that format, but that's not the only problem
ffmpeg does not support the time format you're using. Options are either the time in seconds, or hh:mm:ss[.xxx] (two colons and a dot instead of three colons).
Your example code specifically strips the audio. That's what -an does.
Splitting by time when you actually want frames is not a great idea. Though since the audio frames are unlikely to match 1:1 with the video frames, it might be the best option.
Most importantly, most video and audio codecs are lossy and thus do not take well to being broken up into lots of pieces and then put back together. To do this without horribly mangling the quality, you need to first convert both video and audio into raw formats, manipulate those, and then re-transcode to compressed formats once you've done whatever you want to do with the pieces. You'll still lose some quality, but not as much as otherwise.

Resources