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

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

Related

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.

How to check result mp4's integrity?

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.

ffmpeg convert images with name pattern into video [duplicate]

I am trying to make an FFMPEG script that relied on a glob input pattern from Linux to Windows. Unfortunately that is not supported so I am looking for an alternative. I do not want to have to rename or copy the files every time I run the script because the files are used elsewhere and I cannot rename them and I would like to avoid duplication or unnecessary temporary files.
Are globs numerically sequential named images my only option here? Ideally I would like to input a list of image paths to FFMPEG as a substitute for ffmpeg -i *.jpg
The workarounds are to prepare a text file with the names and use the concat demuxer.
Or you can use image2pipe
cat *.jpg | ffmpeg -f image2pipe -framerate 25 -i - out.mp4
The best solution I could find (that's Windows compatible) was to generate a line separated list of files in a text file and pass that through to FFMPEG. For example, to generate a stabilized MP4 from a bunch of JPEGs:
ffmpeg -f concat -safe 0 -i ./files.txt -vf deshake=rx=64:ry=64 ./stabilized.mp4
Where files.txt is a list of the files in the following format. The safe option toggles the ability to have absolute/relative file paths.
# this is a comment
file 'C:/path/to/file1.jpg'
file 'C:/path/to/file2.jpg'
file 'C:/path/to/file3.jpg'

Input parameters to FFMPEG

I am trying to make an FFMPEG script that relied on a glob input pattern from Linux to Windows. Unfortunately that is not supported so I am looking for an alternative. I do not want to have to rename or copy the files every time I run the script because the files are used elsewhere and I cannot rename them and I would like to avoid duplication or unnecessary temporary files.
Are globs numerically sequential named images my only option here? Ideally I would like to input a list of image paths to FFMPEG as a substitute for ffmpeg -i *.jpg
The workarounds are to prepare a text file with the names and use the concat demuxer.
Or you can use image2pipe
cat *.jpg | ffmpeg -f image2pipe -framerate 25 -i - out.mp4
The best solution I could find (that's Windows compatible) was to generate a line separated list of files in a text file and pass that through to FFMPEG. For example, to generate a stabilized MP4 from a bunch of JPEGs:
ffmpeg -f concat -safe 0 -i ./files.txt -vf deshake=rx=64:ry=64 ./stabilized.mp4
Where files.txt is a list of the files in the following format. The safe option toggles the ability to have absolute/relative file paths.
# this is a comment
file 'C:/path/to/file1.jpg'
file 'C:/path/to/file2.jpg'
file 'C:/path/to/file3.jpg'

Converting MP4 from input folder, moving them to new output, resizing with FFMPEG

I would like to know how to do the following :
There are 2 folders on my desktop. One is called input, the other output.
1 : Input folder contains a number of MP4 video files.
2 : I execute a .SH script (OSX) and all MP4 video files in the
folder will be resized to 2 other sizes for HLS.
3 : The original video in the folder, the highest version, will be
also moved to the output folder after the other 2 versions were
rescaled and created by FFMPEG in the output folder.
After this, we will use the Apple segmentation tool to segment all 3 versions, and automatically deleting the 3 MP4 video's left in the output folder.
I am not experienced with programming, hence I can use some help on this.
As far as I came with some code :
#!/bin/bash
Cd ~/username/Desktop/input
for name in *.mp4; do
ffmpeg -i "$name" -vf scale=854:480 "../output/${name%.*}_middle.mp4"
ffmpeg -i "$name" -vf scale=426:240 "../output/${name%.*}_low.mp4"
mv "$name" "../output/${name%.*}_high.mp4"
Thanks heaps in advance,
John

Resources