I have lots of files with multiple audio and subtitle languages, however the track numbers aren't consistent (the English audio stream isn't always the first) so using a command such as:
ffmpeg -i "input.mkv" -map 0 -map -0:a:1 -c:v copy -c:a copy "output.mkv"
doesn't yield expected results. After searching around I discovered it was possible to map streams based on language with this command:
ffmpeg -i "input.mkv" -map 0 -map -0:m:language:eng -c:v copy -c:a copy "output.mkv"
However -map -0:m:language:eng will remove all tracks with the English language flag. To keep the subtitle tracks you can use -map 0:s this is a good solution however, I want to know if it's possible to only map audio streams based on language. I.e.,
I want to remove English audio while retaining all other streams without using stream IDs.
-0:m:language:eng will remove english audio tracks and keep all others.
to keep only english audio tracks and remove all others, remove the dash at the beginning: 0:m:language:eng
the dash at the beginning creates a negative mapping, which tells ffmpeg "remove this and only things that match this"
i know this is 8 months later, but i thought it would be helpful for those who end up here off of google searches like i did.
Edit: Ignore initial reply. Not possible at present. Use workaround on top.
ffmpeg -i "in.mkv" -map 0:a -map -0:m:language:eng -map 0:v -map 0:s -map 0:d? -map 0:t? -c copy "out.mkv"
This achieves the desired result because ffmpeg implements the map options in given order.
You need to suffix the metadata selectors to the stream type selector i.e.
ffmpeg.exe -i "%f" -map 0 -map -0:a:m:language:eng -c:v copy -c:a copy "../%f"
Updated As far as I can tell this is the best way to remove English audio while retaining all other streams without using stream IDs which I find to be more inconsistent then language flags. Generally people use correct language flags however audio languages are less likely to keep the same ID.
ffmpeg -i "in.mkv" -map a -map -m:language:eng -map v -map s -map d? -map t -c:v copy -c:a copy "out.mkv"
The command will map every audio stream then remove audio with the English language flag. It will then map all video, subtitle and attachment streams. You can add -disposition:a:0 default to give the first audio stream the [default] flag if needed. Note: Only use when you are removing audio that has the default flag already. Change -disposition:a:0 to -disposition:a:1 and so on if you want to set a different audio track to default.
The following will copy the video and English only audio stream.
ffmpeg -i "G:\VIDEO_TS\VTS_01_1.VOB" -map i:0x1e0 -map i:0x80 "THE STRANGERS 1.mp4"
Related
I have an FFMPEG question for you!
Problem:
I have 2 files(x265)
01.mkv with multiple audio steams and multiple subtitles (with exactly named layers)
02.mkv with multiple audio steams and multiple subtitles (with exactly named layers)
I would like to add specific audio layer(GER) and specific subtitle(GER)
from 02.mkv to 01 mkv at the same time if it is possible.
(The metadata positions almost always random in file 02.mkv so I can't say it is "-map 0:s:2 for ger subtitle"...)
I have already searched and tried multiple solutions ...
This kind of worked with multiple steps but loses audio and subtitle metadata(Title) during process.
German audio layer extract from 02.mkv to aac
ffmpeg -i 02.mkv -map 0:a:m:language:ger 02.aac
German subtitle layer extract from 02.mkv to srt
ffmpeg -i 02.mkv -map 0:s:m:language:ger 02.srt
Adding extracted audio to 01.mkv
ffmpeg -i 01.mkv -i 02.aac -map 0 -map 1 -codec copy outputfinall_1.mkv
Adding extracted srt to 01.mkv none of this works
1.)
ffmpeg -i 01.mkv -i 02.srt -c copy -c:s mov_text outputfinall_2a.mkv
BUG: Subtitle encoding currently only possible from text to text or bitmap to bitmap
2.)
ffmpeg -i 01.mkv -i 02.srt -map 0 -map 1 -codec copy outputfinall_2b.mkv
works but does not show subtitles while playing only that is there.
Please if you can help I would like a less jumbled mess code for this problem.
With keeping the metadata (titles) of the moved audio stream and subtitle.
Thank you for your time!
Try this:
ffmpeg -i 01.mkv -i 02.mkv \
-map 0 -map 1:a:m:language:ger -map 1:s:m:language:ger \
-c copy outputfinall.mkv
I'm not sure what you mean by "metadata (titles)", posting the log of the above command with clarification will help understanding your situation.
I have the following problem.
In the folder there is video.mp4 file (contain 1 audio stream). There are also 3 different files audio1.wav, audio2.wav, audio3.wav. These files I need to 'attach' as multi stream to the video file - so the user can choose the audio language in VLC player or similar. Result must be one audio at the time - no mixing it all together.
Now, I've done it via Premiere Pro with multitrack (quicktime export to mov), and then I run a script to change audio stream names to correspond with the audio language (iso 639-2 ) and output the mp4 file. All works well, but I wonder if there is simple way to do everything via ffmpeg ( .bat script ). I have a working script for replacing audio in the video, but I need to add few additional .wav to the video file as separate audio tracks.
Any help will be appreciated!
To add a new audio track into an existing video with audio, use
the -i parameter to specify all the input files (original video and additional audios)
the -map option to manually select the tracks of each input (https://trac.ffmpeg.org/wiki/Map)
in your case,
-map 0 to copy all streams from the input #0 (video)
-map 1:a to include all audio streams from input#1 file (audio1)
-map 2:a to include all audio streams from input#2 file (audio2)
and so on
and
-shortest to crop the output to the shortest input
and additionally you may want to use
-c:v copy to copy the video stream without reencoding.
so, try this (line split for readability)
ffmpeg -i video.mp4 -i input1.mp3 -i input2.mp3
-map 0 -map 1:a -map 2:a
-c:v copy -shortest
output.mp4
and (addording to your comment) adding metadata for the audio tracks
ffmpeg -i video.mp4 -i input1.mp3 -i input2.mp3
map 0 -map 1:a -map 2:a
-metadata:s:a:0 language=eng
-metadata:s:a:1 language=ger
-metadata:s:a:2 language=fra
-disposition:a:0 default
-c:v copy -shortest
output.mp4
What I want to achieve
I have two input videos which I do want to concatenate using ffmpeg.
Issue
The input videos contain two stereo audio channels:
after concatenation, the second audio stream is lost:
steps to reproduce
The Command I used is
ffmpeg -f concat -i list.txt -c:a copy -c:v copy demuxed.mp4
Additional Information
The Console Output shows the second audio stream in input properly:
The Output settings also show that there is only one audio output stream. But I want to have the exact same settings in to out, just concatenated:
Assuming that all input videos have matching audio streams, add mapping.
ffmpeg -f concat -i list.txt -map 0:v -map 0:a -c:a copy -c:v copy demuxed.mp4
See http://ffmpeg.org/ffmpeg.html#Stream-selection, especially the section on automatic stream selection for details on how ffmpeg selects streams.
I am working on a mp4 file (36017P.mp4) in which I want to extract Track 2 -[English] using ffmpeg.
I tried with the following command on terminal but it seems to extract Track 1 - [English]:
ffmpeg -i 36017P.mp4 filename.mp3
Problem Statement:
I am wondering what changes I need to make in the ffmpeg command above so that it extract Track 2 -[English] from mp4 file.
The -map option will do what you want. Below in -map 0:a:1 the 0 refers to the first (and only) input file. a refers to the audio channels and the next number - 1 here - selects a specific audio stream, starting from 0:
ffmpeg -i 36017P.mp4 -map 0:a:0 filename1.mp3
ffmpeg -i 36017P.mp4 -map 0:a:1 filename2.mp3
ffmpeg -i 36017P.mp4 -map 0:a:2 filename3.mp3
ffmpeg -i 36017P.mp4 -map 0:a:3 filename4.mp3
For further details, see section 5.11 Advanced options in the ffmpeg docs.
I want to create, in a single command, a video from 3 sources:
a silent background video;
a smaller video to be overlayed (same length of 1), KEEPING its AUDIO;
a PNG logo to be overlayed
I can create the video but cannot get the audio track. I don't understand if -vf is supposed to work in this case. This is what I've tried to do :
ffmpeg.exe -y -i MASTER_SILENT_VIDEO.mp4 -vf "movie=SMALLER_VIDEO_WITH_AUDIO.flv, scale=320:-1[inner];movie=MY_LOGO.png[inner2]; [in][inner] overlay=800:480,amerge [step1]; [step1][inner2] overlay=30:30 [out]" completed.mp4
The "amerge" filter should do the audio merging job, but of course it doesn't work. I've found similar questions involving -map or filtergraph but they refer to mixing a video source and an audio source; I tried several filtergraph examples without success. Any idea?
overlay one video over other using audio from one input
Use -filter_complex, eliminate the movie source filters, and explicitly define output streams with -map:
ffmpeg -y -i main.mp4 -i overlay_with_audio.flv -i logo.png -filter_complex
"[1:v]scale=320:-1[scaled];
[0:v][scaled]overlay=800:480[bg];
[bg][2:v]overlay=30:30,format=yuv420p[video]"
-map "[video]" -map 1:a -movflags +faststart
output.mp4
You may have to provide additional options to the overlay filters depending on the length of the inputs and how you want overlay to react, but because you did not provide the complete console output from your command I had to make a generic, less efficient, and possibly incorrect example.
overlay one video over other merging audio from both inputs
ffmpeg -y -i main.mp4 -i overlay_with_audio.flv -i logo.png -filter_complex
"[1:v]scale=320:-1[scaled];
[0:v][scaled]overlay=800:480[bg];
[bg][2:v]overlay=30:30,format=yuv420p[video];
[0:a][1:a]amerge=inputs=2[audio]"
-map "[video]" -map "[audio]" -ac 2 -movflags +faststart
output.mp4
I'm assuming both inputs are stereo and that you want a stereo output. Also see FFmpeg Wiki: Audio channel Manipulation - 2 × stereo → stereo.