I'm calling ffmpeg from a program I'm writing in order to record audio from an audio interface. The audio interface has six channels and what I'd like to do is only record from the first two audio channels, discarding the rest. I can't work out how to do this or if it is even possible from the documentation.
The command I'm using is as follows:
ffmpeg -f alsa -acodec pcm_s32le -ac 6 -ar 44100 -i hw:CARD=K6,DEV=0 output.wav
Is this something that is possible? If so, how?
Use
ffmpeg -f alsa -acodec pcm_s32le -ac 6 -ar 44100 -i hw:CARD=K6,DEV=0
-af "pan=2c|c0=c0|c1=c1" output.wav
The first argument to the pan filter is the number of output channels. Then come the individual channel mixes. Here it is first out channel is first in channel, and a similar assignment for the second.
Related
We need to detect the 'silence'(s) in the audio channel of a video stream. We have been able to receive a UDP video stream and extract audio from it using the command:
ffmpeg -y -i udp://127.0.0.1:23000 -ab 3000k -ar 44100 -ac 1 test.wav
The audio file was saved only to verify whether audio has been extracted correctly or not.
To detect 'silence'(s) in the audio, we are using the silencedetect filter. We referred to some examples and it seems to work for audio files:
ffmpeg -i audio/file/path -af silencedetect=noise=-50dB:d=0.25 -f null -
We are unable to detect silence(s) in the audio from a video stream. This is the command we came up with:
ffmpeg -y -i udp://127.0.0.1:23000 -ab 3000k -ar 44100 -ac 1 -af silencedetect=noise=-50dB:d=0.25 -f null -
What is it that we are doing wrong? Any help would be appreciated.
Thanks!
I am attempting to use ffmpeg for a number of files.
The actual number of audio streams (there is usually one channel per stream) per file isn't known until I'm using ffmpeg.
The desired outcome is to somehow have ffmpeg get the count of audio channel, use the number in the command line to amerge those into one single audio channel.
The goal is to create a preview version of the original video file for use in a simple HTML5 page.
Is this possible in just one call to ffmpeg?
(Also, apologies as some parts of this problem I'm still learning about)
Edit:
Dumas stackoverflow asker here.
Yes, I've been trying multiple combinations of ffmpeg args.
To answer the other question, we have video files that have multiple streams, usually with single channels.
I'll post some cmdline examples shortly.
This cmdline example kind of does what I want; there are 8 streams, and I'm able to combine all audio into one. THe issue is having to know the number before running ffmpeg:
ffmpeg -i EXAMPLE.MOV -filter_complex "[0:v]scale=-2:720,format=yuv420p[v];[0:a]amerge=inputs=8[a]" -map "[v]" -map "[a]" -c:v libx264 -crf 23 -preset medium -c:a libmp3lame -ar 44100 -ac 2 OUTPUT.mov
You can use ffprobe to find the number of audio streams and use the output as a variable in your ffmpeg command. Bash example using wc to count the audio streams listed by ffprobe:
ffmpeg -i input.mov -filter_complex "[0:v]scale=-2:720,format=yuv420p[v];[0:a]amerge=inputs=$(ffprobe -loglevel error -select_streams a -show_entries stream=codec_type -of csv=p=0 input.mov | wc -l)[a]" -map "[v]" -map "[a]" -c:v libx264 -crf 23 -preset medium -c:a libmp3lame -ar 44100 -ac 2 output.mov
The following command should do the same thing as llogan's answer but doesn't recompress the video track and requires you to identify how many audio tracks should be merged together.
If you want to know how many audio streams are present, try:
ffprobe originalfile.mov 2>&1 | grep 'Stream #'
Once you have identified how many audio streams should be merged, use that number in the amerge=inputs=2 parameter here. This command will merge the streams into one and recompress the audio using aac compression.
ffmpeg -i originalfile.mov -c:v copy -c:a aac -b:a 160k -ac 2 -filter_complex amerge=inputs=2 output.mp4
I capture sound from soundcard, convert it to mp3 and stream to multicast IP.
Command looks like:
ffmpeg -f alsa -i hw:0 -async 1 -vn -acodec libmp3lame -ac 1 -ar 44100 -b:a 128k -flush_packets 0 -f mpegts -pes_payload_size 426 -mpegts_start_pid 0x44 udp://233.21.215.101:1234?pkt_size=1316
But I need to monitor volume level of capturing. If there is no sound (or noise only) I need to switch to another (reserve) channel.
Can I get volume level in ffmpeg output? How I can do it?
P.S: I can get volume level by "volumedetect" filter but it's not in realtime. I need realtime monitoring.
P.P.S: I run ffmpeg programmatically from my application and can't monitor additional windows (like video frame when I use showvolume filter).
Right now, I can suggest using the showvolume filter
ffmpeg -f alsa -i hw:0
-async 1 -vn -acodec libmp3lame -ac 1 -ar 44100 -b:a 128k
-flush_packets 0 -f mpegts
-pes_payload_size 426 -mpegts_start_pid 0x44 udp://233.21.215.101:1234?pkt_size=1316
-filter_complex showvolume[a] -map [a] -f sdl -
A small video window will pop up with a bar graph display of the current volume and also as text labels. You'll need a ffmpeg build with SDL library linked.
You can't close this video window while your streaming is active.
I'm currently writing a small script that coverts an MP4 to Opus audio on the fly and sends it to Discord in golang. Initially my script would pass an MP4 as it was downloading to ffmpeg through stdin and then pass stdout to an Opus encoder, then to Discord (exactly like this). After learning I could build ffmpeg with Opus, I'd like to cut out the opus encoder I previous had and pass ffmpeg's output directly to Discord.
Previous, my ffmpeg command looked like this (with using the second opus encoder)
ffmpeg -i - -f s16le -ar 48000 -ac 2 pipe:1
Now, without the encoder and letting ffmpeg do all the work, this is what I've come up with so far.
ffmpeg -i - -f s16le -ar 48000 -ac 2 -acodec libopus -b:a 192k -vbr on -compression_level 10 pipe:1
With this command however the audio doesn't get accepted by Discord's server, meaning I'm suspecting opus audio isn't coming out the other end. No errors outputted. Have I done something wrong with ffmpeg that could of caused this?
Try
ffmpeg -i - -sample_fmt s16 -ar 48000 -ac 2 -acodec libopus -b:a 192k -vbr on -compression_level 10 -f opus pipe:1
You can't use -f s16le as that specifies an uncompressed output format (of a specific sample type), whereas you need a compressed data stream of a certain codec. Instead, you can use sample_fmt and -f opus
I have some video files that I need to re-encode due to compatibility issues. They are currently mkv files with h.264 video and ac3-a52 audio. I want to keep the h.264 video, convert the container to m4v and create two audio tracks, one with the original ac3-a52 and one copied from that but in aac stereo.
I assume there has to be some sort of audio stream mapping command but I don't know how to map and re-encode at the same time. What command should I enter into ffmpeg to achieve this?
Also, what is the difference between ac3 and ac3-a52? Will an apple TV still be able to pass through ac3-a52 or does that have to be converted to ac3?
this works for me:
ffmpeg -y -i Source.mkv -map 0:v -c:v copy -map 0:a -c:a copy -map 0:a -strict -2 -c:a aac out.mkv
-y – A global option to overwrite the output file if it already exists.
-map 0:v – Designate the video stream(s) from the first input as a source for the output file.
-c:v copy – Stream copy the video. This just muxes the input to the output. No re-encoding occurs.
-map 0:a – Designate the audio stream(s) from the first input as a source for the output file.
-c:a copy – Stream copy the audio. This just muxes the input to the output. No re-encoding occurs.
-strict -2 -c:a aac – Use the native FFmpeg AAC audio encoder. -strict -2 is required as a way that you acknowledge that the encoder is designated as experimental. It is not a great encoder, but it is not too bad at higher bitrates.
According to wikipedia, there is no difference between AC3 and ATSC A/52: the 1st one is the name of the codec, the 2nd is the name of the standard specifying the AC3 codec. Maybe someone have more knowledge about it?
I'm doing the same as the OP, but with an m4v container. I'm using the MacPorts "nonfree" variant of ffmpeg so that I can use libfaac, which gives better audio quality than the built-in AAC encoder and also had the same issue as #dkam. The command line I ended using is like this:
ffmpeg -i input.m4v -map 0:v -c:v copy -map 0:a -c:a:0 copy -map 0:a -c:a:1 libfaac output.m4v
(The videos are for playback on an iPad, which doesn't seem to be able to handle ac3.)
This command will take a video with 1 audio stream, and downmix to stereo and convert the audio stream and add it as a 2nd audio stream. It will be in AAC 384k.
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:0 -c:a:1 aac -b:a 384k -ac 2 OUTPUT.mkv
Explanation of the command
ffmpeg -i INPUT.mkv The application and input file
-strict -2 Enable downmixing support
-map 0 Tell ffmpeg read all Video, Audio, and Subtitle streams for the following arguments
-c copy Copy everything
-map 0:a:0 Tell ffmpeg to read the first audio stream for the following arguments
-c:a:1 aac Output the audio to a 2nd audio channel (0 = first channel) in aac format. Important! You must change the output channel to a higher number if there are multiple audio streams to prevent overwriting them.
-b:a 384k 384k bitrate (I don't know what's good for aac stereo but this is really high since it's for 5.1 aac)
-ac 2 Downmix to stereo
OUTPUT.mkv Output file
More examples
A video with two audio streams. Creating a third audio stream by encoding the first.
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:0 -c:a:2 aac -b:a 384k -ac 2 OUTPUT.mkv
Again a video with two audio streams, but you want to encode the second one
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:1 -c:a:2 aac -b:a 384k -ac 2 OUTPUT.mkv