Why is the results of this FFmpeg command a broken MP4 file?

0

0

I have a YouTube video that I would like to add 30 second intros and outtros to. The three files are saved as MP4s. I am using macOS.

Following instructions on this offical FFmpeg page I used these commands to convert the files to ts files and tested them. They all worked.

ffmpeg -i intro.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts in.ts

However when I used the command:

/opt/local/bin/ffmpeg -f mpegts -i "concat:intro.ts|episode1.ts|out.ts" -c copy -bsf:a aac_adtstoasc output.mp4

output.mp4 is broken: The first video appears correctly, but there seems to be no visual information from there (audio is working and output.mp4 is expected length). This approach works when I do it using videos created in the same application, so I suspect that that's the problem: one file was created in iMovie, one with OBS and the other was first created in OBS and then downloaded from youTube.

Note that all .TS files and output.mp4 are here on my website for review.

What I really want is this.

  • I want a command that converts the intro and outro files so that they match the attributes of the episode and thus the concat works.
  • I then want to convert the intro file so it matches the attributes of outro for future recordings.

Joe

Posted 2019-06-08T15:08:20.300

Reputation: 2 942

2All corresponding streams from the input files must match in their attributes. – Gyan – 2019-06-10T04:35:58.780

Answers

4

Your input parameters vary (which is bad)

Input #0, mpegts, from 'intro.ts':
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 960x540 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 180k tbc
    Stream #0:1[0x101](eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 126 kb/s

Input #1, mpegts, from 'episode1.ts':
    Stream #1:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #1:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 123 kb/s

Input #2, mpegts, from 'out.ts':
    Stream #2:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #2:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 160 kb/s
  • intro.ts has 48000 audio sample rate, but the others have 44100.
  • episode1.ts has H.264 High profile, but the others have Main profile.
  • intro.ts is 960x540, but the others are 1280x720.
  • intro.ts frame rate and timebase varies from the others.

For concatenation inputs need to have the same parameters and the same number and type of streams.

Make all inputs the same

Since episode1.mp4 is the longest and most important input you can conform the others to match it. This requires re-encoding of those other two inputs:

ffmpeg -i intro.mp4 -vf "scale=1280:-2,fps=30" -c:v libx264 -profile:v main -c:a aac -ar 44100 intro2.mp4
ffmpeg -i out.mp4 -c:v libx264 -profile:v main -c:a copy out2.mp4

You can avoid re-muxing to TS since you can use the concat demuxer instead. So just use the original MP4 inputs instead.

Concat

Now create a text file for the concat demuxer:

file intro2.mp4
file episode1.mp4
file out2.mp4

Then concatenate using the concat demuxer:

ffmpeg -f concat -i input.txt -c copy output.mp4

You can add the -movflags +faststart output option if it is to be viewed from your server so it can begin playback faster.

llogan

Posted 2019-06-08T15:08:20.300

Reputation: 31 929

This looks like a really good answer, but unfortunately I get the same problem. All files and copy paste of my command line is here: http://joereddington.com/temp/llogan/ :(

– Joe – 2019-06-13T13:33:31.763

@Joe Works for me. Show the complete log from the concat command. Or update your ffmpeg and try again (vai zeranoe, evermeet, or homebrew). Not sure what player you're using. – llogan – 2019-06-13T20:29:07.770

-1

The post Use ffmpeg copy codec to combine *.ts files into a single mp4, contains some suggestions for concatenating .ts files (the mp4 part is not interesting for you). The most surprising method, if the videos have identical properties, does not even use ffmpeg, so you could try it first due to its simplicity:

copy /b segment1_0_av.ts+segment2_0_av.ts+segment3_0_av.ts all.ts

If this doesn't work for you, the post How to concatenate two MP4 files using FFmpeg gives much useful information. I reproduce below the answer by user rogerdpack which most pertains to your question (the bold-italics text is my emphasis):

FFmpeg has three concatenation methods.

1. concat video filter

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
  -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \
  -map "[v]" -map "[a]" output.mkv

Note that this method performs a re-encode.

2. concat demuxer

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -i mylist.txt -c copy output

for Windows:

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. concat protocol

ffmpeg -i "concat:input1|input2" -codec copy output

This method does not work for many formats, including MP4, due to the nature of these formats and the simplistic concatenation performed by this method.

Which one to use

  • concat filter: Use if your inputs do not have the same parameters (width, height, etc), or are not the same formats/codecs, or if you want to perform any filtering. (You could re-encode just the inputs that don't match so they share the same codec and other parameters, then use the concat demuxer to avoid re-encoding the other inputs).

  • concat demuxer: Use when you want to avoid a re-encode and your format does not support file level concatenation (most files used by general users do not support file level concatenation).

  • concat protocol: Use with formats that support file level concatenation (MPEG-1, MPEG-2 PS, DV). Do not use with MP4.

If in doubt try the concat demuxer.

You have chosen the concat protocol solution, which is apparently the most problematic.

I would suggest trying the other two methods. If the videos don't have identical properties, the concat video filter method might be best. Otherwise, try the concat demuxer method.

The ffmpeg article wiki: Concatenate that has disappeared but still exists in the Google Cache gives additional useful information about the three methods. It also stresses the importance of the inputs being similar enough in properties.

(As I'm not a user of ffmpeg, I cannot test the above. In any case, the properties of your videos play a very important role in the feasibility of the process.)

harrymc

Posted 2019-06-08T15:08:20.300

Reputation: 306 093

1The wiki page hasn't disappeared for good, but the server (or perhaps this trac instance) is problematic, so availability has been sporadic. – llogan – 2019-06-12T18:20:23.037