Converting MKV to MP4 - ffmpeg

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"

Related

FFMpeg Convert to AAC with a multiple stream input file

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))

FFMPEG Pick First Audio Stream of Specific Language

I am trying to extract a single audio stream of a specific language from a video file (which has around 10 different audio streams).
So I tried to use this command:
ffmpeg -i file.mkv -map 0:a:m:language:eng output.mp3
The problem is that the video contains multiple english language audio streams. So I get the error:
Invalid audio stream. Exactly one MP3 audio stream is required.
Here is the stream mapping:
Stream #0:1 -> #0:0
Stream #0:4 -> #0:1
From those two streams I only want the first one. I tried to with -map 0:a:m:language:eng -map 0:0, but this doesn't help in narrowing it down.
Note: I need the language filter as the stream numbers aren't consistent across multiple files. But the English language stream with the lower number is always the correct one I want to map.
Thanks to #kesh's post I found a solution.
By splitting the command into 2 and piping it in the next it is possible to get the expected behaviour.
Here is the code that worked for me:
ffmpeg -i input.mkv -map 0:a:m:language:eng -acodec copy -f matroska pipe: | ffmpeg -i pipe: -map 0:0 -c:a libmp3lame output.mp3

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 : Check if the aac bitstream is malformed or not

I want to upload few sets of videos on my server and later play them in the HTML5 video tag. But some of them are not playing.
I checked the audio stream and video stream of the video, they have AAC and H264 codec respectively.So nothing seems wrong to me.
Then I tried re-encoding it, i got the following message:
malformated aac bitstream, use -absf aac_adtstoasc
av_interleaved_write_frame(): Operation not permitted
However I don't want to encode the videos before upload and just need to check if video has a malformed aac or h264 bitsream.
PS. Users are limited and will be provided with videos h264 and aac
encoded for the upload.
malformated aac bitstream, use -absf aac_adtstoasc doesn't mean the input stream is invalid. It's rather the re-encoding that's invalid. The idea is that you're using an MPEG-2 transport stream as input and the AAC stream in it uses the ADTS format.
If you want to re-encode the file and change the container to FLV or MP4 for example you MUST use the bitstream filter aac_adtstoasc to remove the ADTS header:
-bsf:a aac_adtstoasc
To view the input streams you can use ffprobe. Eg:
ffprobe -v quiet -print_format json -show_streams [input]
Verifying file integrity is another matter.
If the input is MPEG-TS it will not play in HTML5 natively. Check the uploaded format and re-encode to a HTML5 supported format.

Resources