How to split and join without transcoding AVC/MPEG-TS video files in Windows with ffmpeg?
How do I split and join files using ffmpeg
while retaining all audio tracks?
As you have discovered, a bitstream copy will select only one (audio) track, as per the stream specification documentation:
By default,
ffmpeg
includes only one stream of each type (video, audio, subtitle) present in the input files and adds them to each output file. It picks the "best" of each based upon the following criteria: for video, it is the stream with the highest resolution, for audio, it is the stream with the most channels, for subtitles, it is the first subtitle stream. In the case where several streams of the same type rate equally, the stream with the lowest index is chosen.
To select all audio tracks:
ffmpeg -i InputFile.ts-c copy -ss 00:12:34.567 -t 00:34:56.789 -map 0:v -map 0:a FirstFile.ts
To select the third audio track:
ffmpeg -i InputFile.ts -c copy -ss 00:12:34.567 -t 00:34:56.789 -map 0:v -map 0:a:2 FirstFile.ts
You can read more about and see other examples of stream selection in the advanced options section of the ffmpeg
documentation.
I would also combine -vcodec copy -acodec copy
from your original command into -c copy
as above for compactness of expression.
Split:
So, combining those with what you want to achieve in the two files in terms of splitting for later re-joining:
ffmpeg -i InputOne.ts -ss 00:02:00.0 -c copy -map 0:v -map 0:a OutputOne.ts
ffmpeg -i InputTwo.ts -c copy -t 00:03:05.0 -map 0:v -map 0:a OutputTwo.ts
will give you:
OutputOne.ts
, which is everything after the first two minutes of the first input fileOutputTwo.ts
, which is the first 3 minutes and 5 seconds of the second input file
Join:
ffmpeg
supports concatenation of files without re-encoding, described extensively in its concatenation documentation.
Create your listing of files to be joined (eg join.txt
):
file '/path/to/files/OutputOne.ts'
file '/path/to/files/OutputTwo.ts'
Then your ffmpeg
command can use the concat demuxer
:
ffmpeg -f concat -i join.txt -c copy FinalOutput.ts
Since you are working with mpeg
transport streams (.ts
), you should be able to use the concat protocol as well:
ffmpeg -i "concat:OutputOne.ts|OutputTwo.ts" -c copy -bsf:a aac_adtstoasc output.mp4
Per the example on the concat page linked above. I'll leave that up to you to experiment with.
As a simplified answer based on the main one:
To keep data after a start point (up to the end):
ffmpeg -i INPUT -c copy -ss START_TIME -map 0 OUTPUT
To keep data between two time points:
ffmpeg -i INPUT -c copy -ss START_TIME -to END_TIME -map 0 OUTPUT
To keep data of a certain duration after a certain point:
ffmpeg -i INPUT -c copy -ss START_TIME -t DURATION_TIME -map 0 OUTPUT
To keep data of a certain duration after beginning:
ffmpeg -i INPUT -c copy -t DURATION_TIME -map 0 OUTPUT
To keep data from beginning up to a time point:
ffmpeg -i INPUT -c copy -to TIME_POINT -map 0 OUTPUT
TIME may be a number in seconds, or in hh:mm:ss[.xxx]
To join files, create a file called join.txt
with the content
file 'path-to-INPUT1'
file 'path-to-INPUT2'
file...etc
then
ffmpeg -f concat -i join.txt OUTPUT
Or:
To join mpeg files (including transport files)
ffmpeg -i "concat:INPUT-1|INPUT-2" -c copy -bsf:a aac_adtstoasc OUTPUT
As a GUI solution, I have tried Avidemux but with bad results. When searching a Linux solution I have found this comment here pointing to Avidemux nightly:
"You can try Avidemux, but not the stable one. You should try the win32 version (yes, for windows) with "Wine". It supports H.264 and you must use the double arrow to find out the keyframes because you can[not] cut everywhere (due to the "long gop" thing...). But, as every software like this, you can do JUST CUTS otherwise it will render (in case of transitions, effects, ectc.). http://avidemux.org/nightly/win32/"
I have tested that in Linux/Wine but it should work in Windows too.
To join files, use File-Open to add first file, and then File-Append for the rest.
To save: File - Save.