ffmpeg tee muxer failing with error: Tag avc1 incompatible with output codec id '28' - ffmpeg

I am able to stream with ffmpeg an mp4 file with h264 encoded video and aac encoded audio to flash flv output. The command I used is:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -c copy -f flv rtmp://192.168.3.64:1935/main/stream0
When I am trying to use the tee option to duplicate the output I am failing with an error. This is the command I use:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
However, it fails. What I am missing? The output I have from ffmpeg is:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'bigbuckbunny_HD_60fps.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf54.29.104
Duration: 00:10:34.58, start: 0.000000, bitrate: 4279 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4141 kb/s, 60 fps, 60 tbr, 90k tbn, 120 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
handler_name : SoundHandler
[flv # 0x24607a0] Tag avc1 incompatible with output codec id '28' ([7][0][0][0])
[tee # 0x2365260] Slave '[f=flv]rtmp://192.168.3.64:1935/mainconcept/stream0': error writing header: Invalid data found when processing input
[tee # 0x2365260] Slave muxer #0 failed, aborting.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid data found when processing input
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Last message repeated 1 times

According to ffmpeg -f tee refuses to do anything useful add -tag:v 7 (or -vtag 7, same thing):
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -tag:v 7 -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
If you get error Tag mp4a incompatible with output codec id '86018' add -tag:a 10 / -atag 10:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -tag:v 7 -tag:a 10 -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
Related bug report is #6258: tee muxer fails on stream copy.

Related

tee muxer failing with error: Output file #0 does not contain any stream

I am able to stream with ffmpeg an mp4 file with h264 encoded video and aac encoded audio to flash flv output. The command I used is:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -c copy -f flv rtmp://192.168.3.64:1935/main/stream0
When I am trying to use the tee option to duplicate the output I am failing with an error. This is the command I use:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -c copy -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
However, it fails. What I am missing? The output I have from ffmpeg is:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'bigbuckbunny_HD_60fps.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf54.29.104
Duration: 00:10:34.58, start: 0.000000, bitrate: 4279 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4141 kb/s, 60 fps, 60 tbr, 90k tbn, 120 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
handler_name : SoundHandler
Output #0, tee, to '[f=flv]rtmp://192.168.3.64:1935/mainconcept/obs_stream|[f=flv]rtmp://192.168.3.64:1935/mainconcept/obs_stream1':
Output file #0 does not contain any stream
You have to add the -map option when using the tee muxer. From the tee muxer documentation:
Since the tee muxer does not represent any particular output format,
ffmpeg cannot auto-select output streams. So all streams intended for
output must be specified using -map.
Example to include all streams from the input (-map 0):
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
See FFmpeg Wiki: Map for more info and examples.

FFMPEG - concatenating mp4s from different sources - unable to stop "Non-monotonous DTS in output stream" warning

I need to concatenate mp4 files from different sources, this means some of the variables are out of my control such as timebase, aspect ratio and encoding. So to get around this I re-encode and attempt to standardise the files before concatenating them. Unfortunately, despite this I get Non-monotonous DTS in output stream warnings during the concatenation stage, and the output video seems to always have broken audio/video syncing by the last segment.
I know there are a lot of other questions out there about resolving the warning above, but I've been through them all and reviewed the documentation.. but unfortunately I've been still been unable to solve it..
I think the thing which I don't understand is: if I have mp4s from different sources, what exactly do I need to do to ensure that the files will always neatly concatenate together?
What I've tried so far
The script I'm using to standardise the mp4 files before concantenation is the following (amends resolution, frame rate, timebase, bitrate for audio, bitrate for video, audio encoding and video encoding):
ffmpeg -y -i $1 -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2' -r 30 -video_track_timescale 90000 -b:a 128K -b:v 1200K -c:a aac -c:v libx264 $2
Here's the ffprobe output on two of the files, there are some differences but I'm not sure if they are significant?
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'intro.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:08.98, start: 0.000000, bitrate: 1210 kb/s
Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1069 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 132 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'middle.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:59.72, start: 0.000000, bitrate: 1200 kb/s
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1063 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
They all have normal video and audio at this point.
After that I concatenate them and add a watermark using the following (it sucks that I need to re-encode here):
ffmpeg -y \
-f concat \
-safe 0 \
-i $INFILES \
-c:v libx264 \
-c:a copy \
-preset fast \
-vf drawtext=enable="'between(t, $DRAW_TEXT_DELAY, $DRAW_TEXT_DURATION)': fontfile=$FONT_DIR/$FONT: text='$TEXT': fontcolor=$FONTCOLOR: fontsize=$FONTSIZE: $POSITION" \
$OUTFILE
INFILES is a path to a text file formatted like:
file /usr/src/app/data/test/out/intro.mp4
file /usr/src/app/data/test/out/middle.mp4
file /usr/src/app/data/test/out/outro.mp4
What am I missing here? Is there a way to debug this further?
Your audio streams have distinct sampling rates, and may have distinct channel count as well. Also, compressed MPEG audio streams will introduce slight async upon concat.
Use
ffmpeg -y -i $1 -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p' -r 30 -c:v libx264 -b:v 1200K -ac 2 -ar 48000 -c:a pcm_s16le -video_track_timescale 90000 $2
to standardize, but save to MOV.
Then during concat, change -c:a copy to -c:a aac.
There are three methods to concatenate files in FFmpeg.
Demuxer (You are using this)
This method can be used to concat files with the same paramters, like codecs, size, PAR, etc.
$ ffmpeg -concat -i files.txt [...] output.mp4
Protocol
Same as the first one, but on top of that, this method is useful for files that can be copied together bitwise - it doesn't involves re-encoding (some formats support this, like MpegTS or some lossless formats).
$ ffmpeg -i "concat:FILE_0| ... |FILE_N" [...] output.mp4
Filter
If you have videos with different codecs, you have to use this method:
$ ffmpeg -i <FILE_0> ... -i <FILE_N> [...] -filter_complex "[0:0][0:1]...[<N>:0][<N>:1] concat=n=<N>:v=1:a=1[v_out][a_out]" -map [v_out] -map [a_out] output.mp4
The concat filter decodes the video and reencodes it with the same parameters. It also takes care of the audio streams. I'm not entirely sure what does it do if the resolutions are different, but this should be a good start.

ffmpeg can't find codec to cut 10 seconds movie

I tried to cut 10 seconds from movie and convert to MP4. But sometimes I have a error like below:
Duration: 00:08:52.40, start: 0.000000, bitrate: 1126 kb/s
Stream #0:0: Audio: wmav2 (a[1][0][0] / 0x0161), 44100 Hz, stereo, fltp, 96 kb/s
Stream #0:1: Video: wmv3 (Main) (WMV3 / 0x33564D57), yuv420p, 640x480, 1000 kb/s, SAR 1:1 DAR 4:3, 29.97 tbr, 1k tbn, 1k tbc
[mp4 # 0x5614bbea1300] Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argumentStream mapping:
What does this error mean? Should I install some extra codec?
My exec line looks like:
ffmpeg -i input.wmv -ss 00:00:00 -to 0 -c copy 0:00:10 output.mp4
Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
You're trmiing the file without recompressing, and ffmpeg does not write Windows Media 9 streams into MP4, so either recompress:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 output.mp4
or output to a different container, like Matroska:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 -c copy output.mkv

FFMPEG add text frames to the start of video

I have some videos either in mp4 or webm format, and I'd like to use ffmpeg to add 4 seconds to the start of each video to display some text in the center with no sound.
Some other requirements:
try to avoid re-encoding the video
need to maintain the quality (resolution, bitrate, etc)
(optional) to make the text fade in/out
I am new to ffmpeg and any help will be appreciated.
thanks in advance
Example ffprobe information for mp4 below:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.33.100
Duration: 00:00:03.84, start: 0.042667, bitrate: 1117 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720, 1021 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 140 kb/s (default)
Metadata:
handler_name : SoundHandler
Example webm
Input #0, matroska,webm, from 'input.webm':
Metadata:
encoder : Lavf55.33.100
Duration: 00:00:03.80, start: 0.000000, bitrate: 1060 kb/s
Stream #0:0(eng): Video: vp8, yuv420p, 1280x720, SAR 1:1 DAR 16:9, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Stream #0:1(eng): Audio: vorbis, 48000 Hz, stereo, fltp (default)
Screenshot from joined.mp4
Screenshot for step 3 console
You'll have to generate a 4 second video with dummy audio matching the parameters of the existing video, including timebase, and then use the concat demuxer with streamcopy.
For the sample files shown in Q:
Step 1 Generate text video
ffmpeg -f lavfi -r 30 -i color=black:1280x720 -f lavfi -i anullsrc -vf "drawtext=fontfile='/path/to/font.ttf':fontcolor=FFFFFF:fontsize=50:text='Your text':x='(main_w-text_w)/2':y='(main_h-text_h)/2',fade=t=in:st=0:d=1,fade=t=out:st=3:d=1" -c:v libx264 -b:v 1000k -pix_fmt yuv420p -video_track_timescale 15360 -c:a aac -ar 48000 -ac 2 -sample_fmt fltp -t 4 intro.mp4
For WebM, replace -c:v libx264 with -c:v libvpx, -c:a aac with -c:a libvorbis and intro.mp4 with intro.webm. You may remove the -video_track_timescale 15360 since WebMs tend to use a single timescale, that I've seen.
Step 2 Prepare concat file, say, list.txt
file 'intro.mp4'
file 'input.mp4'
Step 3 Concat
ffmpeg -f concat -i list.txt -c copy -fflags +genpts joined.mp4
The variables important here are video size 1280x720, frame rate -r 30, -pix_fmt yuv420p, sample rate -ar 48000, format -sample_fmt fltp, channel layout -ac 2 and of course, codecs.
Short answer is that you cannot encode new data as mp4 or webm and insert it at the front of the video stream. Those formats simply do not work like that. Both of these encoding formats are lossy, so if you decode and encode them again then additional information will be lost/changed by the second encoding. You could do something else, but what you are trying to do will not work.

Demux audio (AMR_WB) and video(H264) from mp4 file using ffmpeg

I want to demux audio (AMR_WB) and video(H264) from an mp4 file. I need to write a program which does this using ffmpeg libraries.
In demuxing.c file which is there in FFMPEG examples i was able to get only the raw formats as the output.
Can i somehow modify that code to get H264 and AMR_WB in encoded format from the mp4 file?
Run ffmpeg twice , each time specify that just 1 track be copy to output.
Example on diff mp4 will provide most of the idea which u will need to adapt to your specific track types for the respective video/audio in your container...
MP4 example : demux h264 and aac tracks to separate outputs (tout1, tout2 )
Whats in input?
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'phoneCam_20120902_112701.mp4':
Metadata:
major_brand : isom
minor_version : 0
compatible_brands: isom3gp4
creation_time : 2012-09-02 18:27:14
Duration: 00:00:12.65, start: 0.000000, bitrate: 8011 kb/s
Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1280x720, 7707 kb/s, SAR 65536:65536 DAR 16:9, 28.64 fps, 29.83 tbr, 90k tbn, 180k tbc
Metadata:
creation_time : 2012-09-02 18:27:14
handler_name : VideoHandle
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, mono, s16, 96 kb/s
Pass 1, just get the Vid
ffmpeg -i phoneCam_20120902_112701.mp4 -map 0:0 -c copy tout1.mp4
Pass2 just get the aud
ffmpeg -i phoneCam_20120902_112701.mp4 -map 0:1 -c aac -ar 48000 -ab
48000 -strict -2 tout2.3gp
In your program, just run ffmpeg from the CLI or call main() in ffmpeg.c

Resources