I am wanting to write a bash script on a MacOS platform that will perform different operations to m4a files with ALAC encoding, depending on whether they are stereo or mono. How can I go about the stereo/mono detection? Are there any tools/libraries that I can utilise? Thank you.
Got it using https://ffmpeg.org/ffprobe.html
if ffprobe -i the-audio-file.mp4 |& grep stereo; then
echo stereo
else
echo mono
fi
Works as ffprobe will output a result like this:
ffprobe version 3.4.2 Copyright (c) 2007-2018 the FFmpeg developers
built with Apple LLVM version 9.0.0 (clang-900.0.39.2)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.4.2 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --disable-jack --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma --enable-nonfree
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'the-audio-file.mp4':
Metadata:
major_brand : M4A
minor_version : 0
compatible_brands: M4A mp42isom
creation_time : 2018-01-27T18:53:31.000000Z
track : 0
disc : 0
Duration: 04:59:13.02, start: 0.000000, bitrate: 381 kb/s
Stream #0:0(eng): Audio: alac (alac / 0x63616C61), 44100 Hz, stereo, s16p, 381 kb/s (default)
Metadata:
creation_time : 2018-01-27T18:53:31.000000Z
0 0 0
Note, this does not work for he-aac, due to this bug in ffprobe
Related
I would really appreciate some help with this...
I have a .ts file I've downloaded from the internet, when I play in Quicktime the video progressively falls behind the audio. It becomes noticeable after a couple of minutes and is a few seconds out after about ten minutes. It plays fine in VLC, but I want to be able to play on my AppleTV which does the same as Quicktime.
I've tried everything I can think of to resolve...
Convert with VLC, which does work, but every few seconds the audio skips.
Convert with Handbrake, which again works, but every few seconds the audio skips like with VLC.
Convert with FFMpeg using -async, but I get the same result again with the audio skips.
Extracted the audio and video to two separate files and recreated a new file with FFMpeg, this makes no difference and is the same as playing the original file.
Tried "stretching" the audio with FFMpeg using "aresample=async=1000", which synchronises but the audio is distorted.
I think the audio skips I'm getting from the -async option are caused because the audio is being trimmed to sync with the video. What I want to do is adjust the video to fit with the audio and leave the audio unchanged.
I've tried to do this with -vsync, but the the results are the same as the original file. The FFMpeg user guide says the following:
With -map you can select from which stream the timestamps should be taken. You can leave either video or audio unchanged and sync the remaining stream(s) to the unchanged one.
But I cannot figure out the syntax. This is what I'm trying but the output is the same as the original...
ffmpeg -vsync 1 -I test.ts -map 0:1 -map 0:0 -y test.mp4
I've tried the above using vsync with 0, 1 and 2, but the result is still the same.
Could anyone please help me with the syntax to sync the video stream to the audio stream and leave the audio unchanged? Or suggest an alternative method I could use?
Any help would be really, really appreciated. Thanks.
Here is the ffprobe for test.ts...
ffprobe version 4.4 Copyright (c) 2007-2021 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4_1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mpegts, from 'TEst.ts':
Duration: 02:13:05.51, start: 1.406000, bitrate: 4579 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1920x1080, 23.98 tbr, 90k tbn, 1411200000.00 tbc
Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 195 kb/s
I am trying to concat multiple clips using FFMPEG
My input videos have the following details:
input1.mp4
ffprobe version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:05:11.75, start: 0.000000, bitrate: 1338 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1204 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : ISO Media file produced by Google Inc. Created on: 11/09/2018.
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
handler_name : ISO Media file produced by Google Inc. Created on: 11/09/2018.
input2.mp4
ffprobe version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input2.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:00:05.62, start: 0.000000, bitrate: 2479 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1260x720 [SAR 1:1 DAR 7:4], 2376 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
I have tried 2 approaches but none seemed to work properly.
Approach #1: Using ffmpeg concat filter
Steps:
ffmpeg -i input1.mp4 -qscale:v 1 intermediate1.mpg
ffmpeg -i input2.mp4 -qscale:v 1 intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.mp4
Approach #2: Using ffmpeg concat demuxer along with timebase handling
Steps:
ffmpeg -i input1.mp4 -s hd720 -r 30000/1001 -video_track_timescale 30k -c:a copy input1-converted.mp4
ffmpeg -i input2.mp4 -s hd720 -r 30000/1001 -video_track_timescale 30k -c:a copy input2-converted.mp4
ffmpeg -f concat -safe 0 -i vidlist.txt -c copy output.mp4
References:
https://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
How to concatenate two MP4 files using FFmpeg?
After merge videos, the duration is too long - ffmpeg
How to concatenate two MP4 files using FFmpeg?
Expectations:
One resultant clip with both inputs merged one after another with proper length(sum of inputs) and no video freeze/audio loss.
Results:
One resultant clip with both inputs merged one after another with lengthy duration(more than the sum of inputs) and video freeze and sometimes audio loss as well.
Your inputs must have the same parameters, but yours vary in width, frame rate, timescale, audio sample rate, and audio channel layout. Since input1.mp4 is the main feature you can re-encode input2.mp4 to match the properties of input1.mp4:
ffmpeg -i input2.mp4 -filter_complex "[0:v]pad=1280:720:-1:-1,fps=30000/1001[v];[0:a]aformat=sample_rates=44100:channel_layouts=stereo[a]" -map "[v]" -map "[a]" input2b.mp4
Then use the concat demuxer to concatenate them. Create input.txt:
file 'input1.mp4'
file 'input2b.mp4'
Concatenate:
ffmpeg -f concat -i input.txt -c copy output.mp4
This leaves input1.mp4 untouched: the process is faster, and preserves the quality of input1.mp4.
Even better is to re-create a new input2.mp4 from the original source while setting the proper parameters. This will avoid generation loss from re-encoding a new file from it.
try this
ffmpeg -i input1-converted.mp4 -i input2-converted.mp4 -filter_complex "concat=n=2:v=1:a=1" output.mp4
n=2 (inputs).
v=1: 1 video stream from each video.
a=1 1 audio stream from each video.
I have a video file and its properties are as the following when I check via the ffprobe command;
My purpose is to take the audio file only and its size should not be >100mb.
Is there any proper way of doing it in an NPM project?
ffprobe 2.webm
ffprobe version N-86175-g64ea4d1 Copyright (c) 2007-2017 the FFmpeg
developers built with gcc 6.3.0 (GCC) configuration: --enable-gpl --
nable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2
--
nable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-
ontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --
nable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --
nable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-
ibmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-
ibopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-
ibsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-
ibtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --
nable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-
ibx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --
nable-zlib libavutil 55. 63.100 / 55. 63.100 libavcodec 57.
96.101
7. 96.101
libavformat 57. 72.101 / 57. 72.101
libavdevice 57. 7.100 / 57. 7.100
libavfilter 6. 90.100 / 6. 90.100
libswscale 4. 7.101 / 4. 7.101
libswresample 2. 8.100 / 2. 8.100
libpostproc 54. 6.100 / 54. 6.100
Input #0, matroska,webm, from '2.webm':
Metadata:
encoder : libwebm-0.2.1.0
creation_time : 2017-05-04T14:59:01.639000Z
Duration: 00:02:35.16, start: 0.000000, bitrate: 32 kb/s
Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default)
Stream #0:1(eng): Video: vp8, yuv420p(progressive), 640x480, SAR 1:1 DAR
4:3, 14.99 tbr, 1k tbn, 1k tbc (default)
Using fluent-ffmpeg's API
You could use the noVideo() method which tells ffmpeg to produce output with "no video".
ffmpeg('/path/to/file.avi').noVideo();
Using ffmpeg's CLI API
I'm not sure of fluent-ffmpeg, but using ffmpeg, you would use the -map option to dictate what streams you want from you inputs in your output. So for your example, the command to get an MP3 file that contains only the first audio stream from your input would be:
ffmpeg -i 2.webm -map 0:a:0 out.mp3
Alternatively, you could tell ffmpeg to not include video streams using the -vn option; but I like to be explicit. Your command would then be:
ffmpeg -i 2.webm -vn out.mp3
You can also use the -acodec option to dictate what encoder you want to use such as AAC or whatever. ffmpeg will use the best guess by looking at the extension you gave your output if you don't give it enough options.
As to limiting filesize, I'm not sure of a clean way to do that, but this question on the Video Production StackExchange may help: How to limit file size with ffmpeg?. It suggests playing with your bitrate until you get the size you want. I would assume you could calculate correct bitrate ahead of time.
I have tried to transcode a radio stream with ffmpeg to g722.
I get the stream to work and im able to listen to the stream.
The problem is that the output stream have faster speed than the input stream.
so the result is not good. I have tried to slow down the speed with atempo without any luck.
like:
size= 241kB time=00:00:28.67 bitrate= 68.8kbits/s speed= 1.4x
this varies from 1.x to 15.x
Console output:
c:\ffmpeg\bin>ffmpeg -i http://lyd.nrk.no/nrk_radio_mp3_mp3_l -ac 1 -acodec g722 -f rtp -ab 64k -ar 16k rtp://192.168.0.99:555
ffmpeg version N-85750-ga75ef15 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.3.0 (GCC)
configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-zlib
libavutil 55. 61.100 / 55. 61.100
libavcodec 57. 93.100 / 57. 93.100
libavformat 57. 72.101 / 57. 72.101
libavdevice 57. 7.100 / 57. 7.100
libavfilter 6. 88.100 / 6. 88.100
libswscale 4. 7.101 / 4. 7.101
libswresample 2. 8.100 / 2. 8.100
libpostproc 54. 6.100 / 54. 6.100
Input #0, mp3, from 'http://lyd.nrk.no/nrk_radio_mp3_mp3_l':
Metadata:
icy-name : NRK mP3
icy-pub : 1
Duration: N/A, start: 0.000000, bitrate: 96 kb/s
Stream #0:0: Audio: mp3, 48000 Hz, stereo, s16p, 96 kb/s
[udp # 000000000244bec0] 'circular_buffer_size' option was set but it is not supported on this build (pthread support is required)
[udp # 00000000024781a0] 'circular_buffer_size' option was set but it is not supported on this build (pthread support is required)
Stream mapping:
Stream #0:0 -> #0:0 (mp3 (native) -> adpcm_g722 (g722))
Press [q] to stop, [?] for help
Output #0, rtp, to 'rtp://192.168.0.99:555':
Metadata:
icy-name : NRK mP3
icy-pub : 1
encoder : Lavf57.72.101
Stream #0:0: Audio: adpcm_g722 (g722), 16000 Hz, mono, s16, 64 kb/s
Metadata:
encoder : Lavc57.93.100 g722
SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 192.168.0.99
t=0 0
a=tool:libavformat 57.72.101
m=audio 555 RTP/AVP 9
b=AS:64
size= 413kB time=00:00:49.17 bitrate= 68.8kbits/s speed=1.43x
Does anyone know what im doing wrong?
Thanks
The problem is that the output stream have faster speed than the input stream
Are you sure about this? If so, the issue comes down to sample rate. The playback side (after FFmpeg) is playing back at a higher sample rate than what you're outputting from FFmpeg.
I suspect this isn't really happening though based on this comment:
this varies from 1.x to 15.x
When you connect to an internet radio stream, a large buffer is going to be flushed to you as fast as possible. This enables fast starts for players. For your FFmpeg command, it means that when you first connect, FFmpeg is also going to process this data as fast as possible and send it over. This is generally fine, provided that the end playback device is buffering data. If it isn't, you'll have to force FFmpeg to buffer data.
You can do that by specifying the -re parameter before the input. This will force the input to run in real time against a software-defined clock.
I have a 3.2GHz Quad Core Xeon E3-1230 CPU, Passmark CPU mark Score of 8,200, 32GB ram - and I can't do more than 4 ffmpeg commands/sessions without being overloaded. When I execute a ffmpeg session, it's telling me that it's not using muliple cores, only one. Why is that? How can I get ffmpeg to fully use all the cpu cores I have?
Thank you in advance for any kind of suggestions.
ffmpeg version:
ffmpeg version N-42487-gfedefe4-syslint Copyright (c) 2000-2012 the FFmpeg developers
built on Jul 13 2012 23:18:33 with gcc 4.1.2 20080704 (Red Hat 4.1.2-52)
configuration: --prefix=/usr/local/cpffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --enable-libopencore-amrnb --enable-decoder=liba52 --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --extra-cflags=-I/usr/local/cpffmpeg/include/ --extra-ldflags=-L/usr/local/cpffmpeg/lib --enable-version3 --extra-version=syslint
libavutil 51. 64.100 / 51. 64.100
libavcodec 54. 37.100 / 54. 37.100
libavformat 54. 16.104 / 54. 16.104
libavdevice 54. 1.100 / 54. 1.100
libavfilter 3. 2.100 / 3. 2.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 15.100 / 0. 15.100
libpostproc 52. 0.100 / 52. 0.100
Hyper fast Audio and Video encoder