I am trying to use ffmpeg to combine 1 audio file (ADPCM) and 1 video file (h264) into single mp4. Video by file conversion works fine but ffmpeg chokes on guessing audio input. I can't figure out how to tell ffmpeg which params to use to decode raw audio file.
Currently I first run sox to convert raw audio to wav:
sox -t ima -r 8000 audio.raw audio.wav
... then feed audio.wav from sox as ffmpeg input
ffmpeg -i video.raw -i audio.wav movie.mp4
I am trying to avoid sox step and use audio.raw in ffmpeg.
Thank you
Since you have headless audio, you should tell ffmpeg about the sample format and (optionally) sample rate, audio channels, e.g.:
ffmpeg -i video.raw -f s16le -ar 22050 -ac 1 -i audio.raw movie.mp4
To check supported PCM formats you may use this command:
ffmpeg -formats 2>&1 | grep -i pcm
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 have a webcam and a separate mic. I want to record what is happening.
It almost works, however the audio seems to play quickly and parts missing while playing over the video.
This is the command I am currently using to get it partially working
ffmpeg -thread_queue_size 1024 -f alsa -ac 1 -i plughw:1,0 -f video4linux2 -thread_queue_size 1024 -re -s 1280x720 -i /dev/video0 -r 25 -f avi -q:a 2 -acodec libmp3lame -ab 96k out.mp4
I have tried other arguments, but unsure if it has to do with the formats I am using or incorrect parameter settings.
Also, the next part would be how to stream it. Everytime I try going through rtp it complains about multiple streams. I tried doing html as well, but didn't like the format. html html://localhost:50000/live_feed or rts rts://localhost:5000
edit:
I am running this on a rpi 3.
I have multiple audio tracks and subtitles to extract in a single .mkv file. I'm new to ffmpeg commands, this is what I've tried (audio):
ffmpeg -i VIDEO.mkv -vn -acodec copy AUDIO.aac
It just extract 1 audio. What I want is tell ffmpeg to extract every single audio files and subtitle files to a destination, and keep the original name of each files and extensions. (Because I don't know which extension does the audio files are, sometimes maybe .flac or .aac).
I'm not sure about the solutions I'd found online, because it's quite complicated, and I need explanations to know how it's works, so that I can manipulate the command in the future. By the way, I planned to run the code from Windows CMD. Thanks.
There is no option yet in ffmpeg to automatically extract all streams into an appropriate container, but it is certainly possible to do manually.
You only need to know the appropriate containers for the formats you want to extract.
Default stream selection only chooses one stream per stream type, so you have to manually map each stream with the -map option.
1. Get input info
Using ffmpeg or ffprobe you can get the info in each individual stream, and there is a wide variety of formats (xml, json, cvs, etc) available to fit your needs.
ffmpeg example
ffmpeg -i input.mkv
The resulting output (I cut out some extra stuff, the stream numbers and format info are what is important):
Input #0, matroska,webm, from 'input.mkv':
Metadata:
Duration: 00:00:05.00, start: 0.000000, bitrate: 106 kb/s
Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
Stream #0:1: Audio: vorbis, 44100 Hz, mono, fltp (default)
Stream #0:2: Audio: aac, 44100 Hz, mono, fltp (default)
Stream #0:3: Audio: flac, 44100 Hz, mono, fltp (default)
Stream #0:4: Subtitle: ass (default)
ffprobe example
ffprobe -v error -show_entries stream=index,codec_name,codec_type input.mkv
The resulting output:
[STREAM]
index=0
codec_name=h264
codec_type=video
[/STREAM]
[STREAM]
index=1
codec_name=vorbis
codec_type=audio
[/STREAM]
[STREAM]
index=2
codec_name=aac
codec_type=audio
[/STREAM]
[STREAM]
index=3
codec_name=flac
codec_type=audio
[/STREAM]
[STREAM]
index=4
codec_name=ass
codec_type=subtitle
[/STREAM]
2. Extract the streams
Using the info from one of the commands above:
ffmpeg -i input.mkv \
-map 0:v -c copy video_h264.mkv \
-map 0:a:0 -c copy audio0_vorbis.oga \
-map 0:a:1 -c copy audio1_aac.m4a \
-map 0:a:2 -c copy audio2.flac \
-map 0:s -c copy subtitles.ass
In this case, the example above is the same as:
ffmpeg -i input.mkv \
-map 0:0 -c copy video_h264.mkv \
-map 0:1 -c copy audio0_vorbis.oga \
-map 0:2 -c copy audio1_aac.m4a \
-map 0:3 -c copy audio2.flac \
-map 0:4 -c copy subtitles.ass
I prefer the first example because the input file index:stream specifier:stream index is more flexible and efficient; it is also less prone to incorrect mapping.
See documentation on stream specifiers and the -map option to fully understand the syntax. Additional info is in the answer to FFmpeg mux video and audio (from another video) - mapping issue.
These examples will stream copy (re-mux) so no re-encoding will occur.
Container formats
A partial list to match the stream with the output extension for some common formats:
Video Format
Extensions
H.264
.mp4, .m4v, .mov, .h264, .264
H.265/HEVC
.mp4, .h265, .265
VP8/VP9
.webm
AV1
.mp4
MPEG-4
.mp4, .avi
MPEG-2
.mpg, .vob, .ts
DV
.dv, .avi, .mov
Theora
.ogv/.ogg
FFV1
.mkv
Almost anything
.mkv, .nut
Audio Format
Extensions
AAC
.m4a, .aac
MP3
.mp3
PCM
.wav
Vorbis
.oga/.ogg
Opus
.opus, .oga/.ogg, .mp4
FLAC
.flac, .oga/.ogg
Almost anything
.mka, .nut
Subtitle Format
Extensions
Subrip/SRT
.srt
SubStation Alpha/ASS
.ass
You would first list all the audio streams:
ffmpeg -i VIDEO.mkv
and then based on the output you can compile the command to extract the audio tracks individually.
Using some shell script you can then potentially automate this in a script file so that you can do it generically for any mkv file.
Subtitles are pretty much the same. The subtitles will be printed in the info and then you can extract them, similar to:
ffmpeg -threads 4 -i VIDEO.mkv -vn -an -codec:s:0.2 srt myLangSubtitle.srt
0.2 is the identifier that you have to read from the info.
I solved it like this:
ffprobe -show_entries stream=index,codec_type:stream_tags=language -of compact $video1 2>&1 | { while read line; do if $(echo "$line" | grep -q -i "stream #"); then echo "$line"; fi; done; while read -d $'\x0D' line; do if $(echo "$line" | grep -q "time="); then echo "$line" | awk '{ printf "%s\r", $8 }'; fi; done; }
Output:
Only set $video1 var before command.
Enjoy it!.
If someone steps in this question with a modern version of ffmpeg, it looks like they added the option there.
I needed to convert a file by maintaining all tracks:
ffmpeg -i "${input_file}" -vcodec hevc -crf 28 -map 0 "${output_file}"
To achieve what the original question asked, probably this could be used:
mappings="`ffmpeg -i \"${filein}\" |& awk 'BEGIN { i = 1 }; /Stream.*Audio/ {gsub(/^ *Stream #/, \"-map \"); gsub(/\(.*$/, \" -acodec mp3 audio\"i\".mp3\"); print; i +=1}'`"
ffmpeg -i "${input_file}" ${mappings}
The 1st line (mappings=...) extracts the existing audio streams and converts them in "-map X:Y -acodec mp3 FILENAME", while the 2nd one executes the extraction
The following script extracts all audio streams from files in current directory
ls |parallel "ffmpeg -i {} 2>&1 |\
sed -n 's/.*Stream \#\(.\+\)\:\(.\+\)\: Audio\: \([a-zA-Z0-9]\+\).*$/-map \1:\2 -c copy \"{.}.\1\2.\3\"/p' |\
xargs -n5 ffmpeg -i {} "
I have a problem using ffmpeg:
when i trying to record video+audio from my webcam in result i got only video stream, wthout audio at all.
I have tried different codecs and nothing..
Maybe, someone can give me advice?
ffmpeg -f dshow -i video="Logitech HD Webcam C270" -r 25 -s 800x600 -acodec libmp3lame -vcodec mpeg4 -b 3000k -f avi D:\1.avi
Btw: virtualdub grabs both well.
Thanks.
Assuming that you have installed the driver and codecs, use something like:
ffmpeg -f dshow -i video="Logitech HD Webcam C270" [path]out.mp4
A short explanation is given in capture a webcam input. For using DirectShow you have this examples.