FFMpeg Convert to AAC with a multiple stream input file - ffmpeg

I am trying to add a AAC Audio Stream (Stereo) to a MKV file.
To do this I am first creating a Temp.mkv file which I then combine with the original MKV file. This works fine in most cases but when I am trying to create the Temp.mkv where the original file have multiple audio stream it's not working.
I am doing this (in this example I am going for the 3rd Audio stream to be converted)
-loglevel error -i "Input.mkv" -map 0:a:2 -c:a:2 aac -ac:a:2 2 Temp.mkv
The goal is to have a single AAC audio stream (Stereo) in the Temp.mkv file.
Also the reason I am doing the "Temp.mkv" and not "Temp.aac" is to keep the audio stream metadata.
For some reason I end up with the wrong audio stream (I know this because the language is wrong) and for some reason it's in Vorbis and not AAC.
UPDATE:
If do the 3rd stream it's like this:
Stream #0:3 -> #0:0 (ac3 (native) -> vorbis (libvorbis))
If I do the 1st stream it's like this:
Stream #0:1 -> #0:0 (truehd (native) -> aac (native))

Related

-use_wallclock_as_timestamps adds delay in live stream

We have a livestream (MPEG-TS with RTP), which we currently, for testing purposes, replay with tcpreplay.
Our mpeg-ts stream consists of 4 streams (codec details omitted for brevity).
Stream #0:2: Video: h264
Stream #0:1: Audio: mp2
Stream #0:4: Data: bin_data ([6][0][0][0] / 0x0006)
Strean #0:3: Data: bin_data (FBID / 0x4494246)
Stream #0:0: Data: klv (KLVA / 0x41564C4B)
Sometimes the stream indexes are different (like audio stream being stream 0 and so on, I don't know if thats normal behavior)
What we currently try is just to get the stream and copy it with ffmpeg, like
ffmpeg -nostdin -hide_banner -i rtp://239.0.0.2:3000 -map 0 -codec copy -f rtp_mpegts rtp://239.0.0.1:2000`
This leads to the error Application provided invalid, non monotonically incereasing dts to muxer in stream 0: [NUMBER] >= 0
It always says stream 0 no matter what stream 0 contains.
if I add use_wallclock_as_timestamps it works but adds a delay (compared to a video directly streamed from 239.0.0.2:3000 of ~10seconds which are never caught up.
If I set the output format to mpegts instead of rpt_mpegts it works as expected, the same I if don't map the KLVA and FBID stream.
Is this behavior expected (because of wallclock) or what can I do to either use_wallclock_as_timestamps without delay or get rid of the error above?

Converting MKV to MP4

So I am trying to convert a really long video from MKV to MP4.
I tried this command first which is supposed to be the fastest way to convert mkv to mp4
ffmpeg -i "vid.mkv" -codec copy -map 0 "MP4/vid.mp4"
however I am getting this error everytime I run it
[mp4 # 0x7fffe98ae500] track 1: codec frame size is not set
[mp4 # 0x7fffe98ae500] opus in MP4 support is experimental, add '-strict -2' if you want to use it.
Could not write header for output file #0 (incorrect codec parameters ?): Experimental feature
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Last message repeated 1 times
What am I doing wrong?
The issue and solution is mentioned in the 2nd line of the excerpt you pasted.
You're using an older version of ffmpeg. Since recently, Opus audio in MP4 is no longer treated as experimental. Upgrade to ffmpeg 4.3 or add -strict -2 as mentioned in log.
For compatibility sake, you'll usually want to transcode audio to AAC.
ffmpeg -i "vid.mkv" -map 0 -c copy -c:a aac "MP4/vid.mp4"

Could not find tag for codec subrip in stream, codec not currently supported in container

I'm trying to convert a video to lower quality using the following comand :
ffmpeg -i in.mkv -c:a copy -map 0:5 -map 0:6 -map 0:7 -c:s copy -map 0:9 -c:v h264_nvenc -rc constqp -qp 23 -map 0:0 out.mp4
With stream 0:9 being a subtitle. I get
Stream mapping:
Stream #0:5 -> #0:0 (copy)
Stream #0:6 -> #0:1 (copy)
Stream #0:7 -> #0:2 (copy)
Stream #0:9 -> #0:3 (copy)
Stream #0:0 -> #0:4 (h264 (native) -> h264 (h264_nvenc))
Press [q] to stop, [?] for help
[mp4 # 0x55c6edd3a640] track 0: codec frame size is not set
[mp4 # 0x55c6edd3a640] track 1: codec frame size is not set
[mp4 # 0x55c6edd3a640] track 2: codec frame size is not set
[mp4 # 0x55c6edd3a640] Could not find tag for codec subrip in stream #3, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:4 --
If I change -c:s copy with -c:s mov_text, the error is gone, but then the subtitle doesn't work. Everything else seems to be fine.
You are outputting MP4, but it only supports mov_text (a generic name for streaming text format [14496-17]) softsubs. However, player support is not universal.
Use a better player (VLC, mpv, Pot Player), use a different output container format (such as MKV), or use hardsubs (see subtitles filer).

Which codecs were used in transcoding of a video using ffmpeg

During a transcoding of a video how can I figure out which codecs were used by ffmpeg to decode and transcode the video.
For eg. when I do ffmpeg -i input.mp4 output.avi
How can I know which codecs where used to decode the input file and encode to the output?
#Koby Douek's answer is not applicable here.
Mediainfo and ffprobe will indicate the bitstream syntax but to answer the OP's Q: "How can I know which codecs where used to decode the input file and encode to the output?", one can run
ffmpeg -i input.mp4 output.avi 2>&1 | sed -n "/Stream mapping/,/Press/p"
whose output will be like
Stream #0:1 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:0 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
This informs us that the first output stream mapped was the 2nd input stream, of type H.264 and decoded using ffmpeg's native H.264 decoder. This stream was encoded to H.264 using the libx264 encoder.
The given command actually performs the conversion, but the mapping info is displayed just before processing starts, so either abort the command or redirect the log to file by adding -report and parse that file for the info.
If you have mediainfo:
mediainfo --Inform="Video;%Codec%" output.avi
If not, use ffprobe (comes with ffmpeg installation):
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name \ -of default=noprint_wrappers=1:nokey=1 output.avi

FFMPEG attach file as metadata

I have a set of images which I want to convert to a video using ffmpeg. The following command works perfectly fine:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 testout.mkv
I have some meta data in a binary file which I want to attach with the video. I tried doing the following, but it gives me an error:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 -attach mybinaryfile -metadata:s:2 mimetype=application/octet-stream testout.mkv
This is the error:
[matroska # 0x656460] Codec for stream 1 does not use global headers but container format requires global headers
[matroska # 0x656460] Attachment stream 1 has no mimetype tag and it cannot be deduced from the codec id.
Output #0, matroska, to 'testout.mkv':
Metadata:
encoder : Lavf56.33.101
Stream #0:0: Video: huffyuv (HFYU / 0x55594648), rgb24, 640x640, q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc56.39.100 huffyuv
Stream #0:1: Attachment: none
Metadata:
filename : 2ceb-1916-56bb-3e10
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> huffyuv (native))
File 2ceb-1916-56bb-3e10 -> Stream #0:1
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
It would be wonderful if somebody can explain to me what am I doing wrong :)
You need to specify your stream properly
Example:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 -attach mybinaryfile \
-metadata:s:t mimetype=application/octet-stream testout.mkv
This command will set the metadata for all attachment (t) streams (s). If you have more than one attachment, and the metadata are different, then you will have to be more specific, such as:
-metadata:s:t:0 mimetype=text/plain \
-metadata:s:t:1 mimetype=application/gzip
This will set the metadata for the first attachment as mimetype=text/plain, and the second as mimetype=application/gzip. Remember that the stream index starts at 0, so the first steam is labeled 0.
What was wrong with your command
Using -metadata:s:2 (which appears to have been copied verbatim from the documentation) sets the metadata for the third stream, regardless of stream type (because no specifier is present), but your output only contained two streams.
Attachment: None
You may see something like this:
Output #0, matroska, to 'output.mkv':
...
Stream #0:1: Attachment: none
Metadata:
filename : 2ceb-1916-56bb-3e10
mimetype : application/octet-stream
Attachment: none does not mean that there is no attachment, but that there is no format associated with it, so it can be ignored.
Also see
Stream specifiers and the ffmpeg documentation on -attach, -metadata, and -map_metadata for more details.

Resources