How to check result mp4's integrity? - ffmpeg

There are 4 categories, each Categories has 10 mp4 files.
I used ffmpeg to concatenate 4 categories, such as cat1 | cat2 | cat3 | cat4.
With simple calculation, I get 10000 concatenated mp4 files.
Here is the problem. There are some mp4 files among the 10000 files that are wrongly encoded. So I can't play the files. I found 100 files so far.
Is there any options that I can check the concatenated mp4 is correctly encoded? Or can I verify all of them without playing?
I've searched Stack Overflow and seen ffmpeg's options but I'm not used to ffmpeg and it looks it'd take super long but I got no much time.

I encoded 10000 mp4 files from 40 source mp4 files.
In conclusion,
I used this command.
ffmpeg -v error -i ./result/$num.mp4 -preset ultrafast -f null - 2>> check.log
where $num is from 0000 to 9999.
To check the integrity,
use "-v error" option.

Related

How to merge .ts files from a DLINK security camera losslessly?

I have >1000s of small .ts files from a DLINK camera of a theft that occured. I first tried to merge the ts files into bigger files so that I could look for the audio where the relevant event occurred. Then in Premiere I looked for the highest sustained audio peaks (it was someone using a saw to cut out a catalytic converter). Then, I isolated the relevant 200 files where things happened on the timeline. But now, I want to export the 20 minutes of the incident with the least compression (or no compression). Apparently Adobe Premiere can export the whole timeline containing these clips, but will compress them. I have not edited any of the files, so I don't want any rendering. I just want them strung together in a "well-known" format so I can send the files to the insurance company and authorities.
I used an answer from here but there were audio gaps. Some of the files had no audio, causing the problem when I first merged the files with:
for i in `\ls *.ts | sort -V`; do echo "file '$i'"; done >> mylist.txt;ffmpeg -f concat -i mylist.txt -c copy -bsf:a aac_adtstoasc video.mp4
This worked for me, and I'm sending it along to help the investigation.
xargs cat <mylist.txt >>catout.ts
ffmpeg -i catout.ts -map 0 -c copy catout.mp4
I had >200 .ts files from a DLINK security camera I needed to stitch up losslessly for the authorities (insurance).
After looking around on Stackoverflow, here's what I did.
First create a list of the ts files to combine:
for i in `\ls *.ts | sort -V`; do echo "file '$i'"; done >> mylist.txt;
Merge them into one ts:
ffmpeg -f concat -safe "0" -i mylist.txt -c copy merge.ts
Then convert the ts directly and losslessly to a well known format for the authorities
ffmpeg -i merge.ts -map 0 -c copy output.mp4

Segment video with FFMPEG using custom filenames for output

I'm trying to segment a video and name the cropped files in a specific way. Right now I'm using
ffmpeg -i input.mp3 -f segment -segment_time 59 output_%03d.wav
and looping over created files, parsing their filenames and renaming them accordingly.
I have an array which contains
array=[1650027545, 1650027300, 1650026502, ...]
and want the output files to be in;
output_1650027545.wav
output_1650027300.wav
output_1650026502.wav
format. Since there's no loop, I can't figure out how to implement such a naming scheme. Any help is appreciated!

Remove a section from the middle of a video without concat

How do I cut a section out of a video with ffmpeg?
Imagine I have a 60 second mp4 A.
I want to remove all the stuff from 0:15 to 0:45.
The result should be a 30-second mp4, which is composed of the first 15 seconds of A directly followed by the last 15 seconds of A.
How can I do this without using concat?
I know how I could do it by creating two intermediary files and then using ffmpeg to concat them. I don't want to have to perform so much manual work for this (simple?) operation.
I have also seen the trim filder used for removing multiple parts from a video. All the usages I've found show that it seems to be very verbose, and I haven't found an example for a case as simple as I would like (just a single section removed).
Do I have to use trim for this operation? Or are there other less verbose solutions?
The ideal would of course be something at least simple as -ss 0:15 -to 0:45 which removes the ends of a video (-cut 0:15-0:45 for example).
I started from
https://stackoverflow.com/a/54192662/3499840 (currently the only answer to "FFmpeg remove 2 sec from middle of video and concat the parts. Single line solution").
Working from that example, the following works for me:
# In order to keep <start-15s> and <45s-end>, you need to
# keep all the frames which are "not between 15s and 45s":
ffmpeg -i input.mp4 \
-vf "select='not(between(t,15,45))', setpts=N/FRAME_RATE/TB" \
-af "aselect='not(between(t,15,45))', asetpts=N/SR/TB" \
output.mp4
This is a one-line linux command, but I've used the bash line-continuation character ('\') so that I can vertically align the equals-signs as this helps me to understand what is going on.
I had never seen ffmpeg's not and between operators before, but I found their documentation here.
Regarding the usual ffmpeg "copy vs re-encode" dichotomy, I was hoping to be able to use ffmpeg's "copy" "codec" (yeah, I know that it's not really a codec) so that ffmpeg would not re-encode my video, but if I specify "copy", then ffmpeg starts and stops at the nearest keyframes which are not sufficiently close to my desired start and stop points. (I want to remove a piece of video that is approximately 20 seconds long, but my source video only has one keyframe every 45 seconds!). Hence I am obliged to re-encode. See https://trac.ffmpeg.org/wiki/Seeking#Seekingwhiledoingacodeccopy for more info.
The setpts/asetpts filters set the timestamps on each frame to the correct values so that your media player will play each frame at the correct time.
HTH.
If you want to use the copy "codec", consider the following approach:
ffmpeg -i input.mp4 -t "$start_cut_section" -c copy part1.mp4&
ffmpeg -i input.mp4 -ss "$end_cut_section" -c copy part2.mp4&
echo "file 'part1.mp4'" > filelist;
echo "file 'part2.mp4'" >> filelist;
wait;
ffmpeg -f concat -i filelist -c copy output.mp4;
rm filelist;
This creates two files from before and after the cut, then combines them into a new trimmed final video. Obviously, this can be used to create as many cuts as you like. It may seem like a longer approach than the accepted answer, but it likely will execute much faster because of the use of the copy codec.

Bash: sort find results using part of a filename [duplicate]

This question already has answers here:
Bash and sort files in order
(8 answers)
Closed 7 years ago.
I have 3 webcams set up in a building, uploading still images to a webserver. I'm using ffmpeg to encode the jpgs to mp4 video.
The directories are set up like this:
Cam1/201504
Cam1/201505
Cam2/201504
Cam2/201505
Cam3/201504
Cam3/201505
I'm using the following bash loop/ffmpeg parameters to make one video per camera, per year. This works well so far (well... except that my SSD is rapidly degrading in performance - too many simultaneous read/write operations?):
find Cam2/2013* -name "*.jpg" -print0 | xargs -0 cat | ffmpeg -f image2pipe -framerate 30 -vcodec mjpeg -i - -vcodec libx264 -profile:v baseline -level 3.0 -movflags +faststart -crf 19 -pix_fmt yuv420p -r 30 "Cam2-2013-30fps-19crf.mp4"
The individual files are named like this (confusing ffmpeg's built-in file sequencer):
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413032601.jpg
Cam2_2015052413544901.jpg
I now need to create one video for an entire year across all 3 cameras, ordered by timestamp. To accomplish this, I need to sort the find results by the segment of the filename after the underscore.
What do I pipe the find output to to accomplish this? For example, the files above would be ordered like this:
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
Any help is very much appreciated!
sort
sort -t '_' -nk2
-t '_' # specifices that the field seperator should be an underscore
-nk2 # start sorting from the second field (after the underscore)..n sort according to numerical value/timestamp
output
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
pipe sort to find command like
sort -t '_' -nk2 --files0-from=-
Use sort with the --key option. See your man page of sort for details of the key format. Generally (for both coreutils and BSD sort) it should be F[.C][OPTS][,F[.C][OPTS]], where F is for field and C is for character position. Here you want to sort from the 5th character of the first field, so --key=1.5 will do:
> echo -e 'Cam1_2015052413543201.jpg\nCam1_2015052413544601.jpg\nCam2_2015052413032601.jpg\nCam2_2015052413544901.jpg' | sort --key=1.5
Cam2_2015052413032601.jpg
Cam1_2015052413543201.jpg
Cam1_2015052413544601.jpg
Cam2_2015052413544901.jpg
Here you seem to have not only basenames in the output of find, but relative paths with path segments like Cam1/201505/ prepended, but you can still count the number of characters and hence write the appropriate keydef. For instance, say the paths for the images in the example above are
Cam1/201505/Cam1_2015052413543201.jpg
Cam1/201505/Cam1_2015052413544601.jpg
Cam2/201505/Cam2_2015052413032601.jpg
Cam2/201505/Cam2_2015052413544901.jpg
Then
sort --key=1.17
will give you the correct order
Cam2/201505/Cam2_2015052413032601.jpg
Cam1/201505/Cam1_2015052413543201.jpg
Cam1/201505/Cam1_2015052413544601.jpg
Cam2/201505/Cam2_2015052413544901.jpg

Convert series of images to video

I have series of images with sorted names, like 0000000354 ... 0000008591
I have tried using ffmpeg or MEncoder to convert theme. In ffmpeg the problem is this that it will operate while the names are like 0000000001 ... 00000000009 with %010d syntax.I don't know what syntax i should use for my images names.in mencoder it will cover all images But when i play the output video it doesn't show images,I want to show every image in 5 seconds or somthing like this, any one can help?
ffmpeg can't read in arbitrarily named images. You'll have to rename them or do something clever with symlinks to get ffmpeg to take them as input.
From the man page:
If the pattern contains "%d" or "%0Nd", the first filename of the file
list specified by the pattern must contain a number inclusively
contained between 0 and 4, all the following numbers must be
sequential. This limitation may be hopefully fixed.
Let's say you have:
img000001.jpg
....
img000140.jpg
....
img010040.jpg
....
To encode it into a movie using ffmpeg just use the filename pattern:
ffmpeg -i "img%06d.png" -vcodec libx264 -vpre ipod640 output.mp4

Resources