FFMpeg Concatenation Filters: Stream specifier ':0' in filtergraph matches no streams - audio

I am developing an application that relies heavily on FFMpeg to perform various transformations on audio files. I am currently testing my FFMpeg configuration on the command line.
I am trying to concatenate multiple audio files which are in different formats (Primarily MP3, MP2 & WAV). I have been using the official TRAC documentation (https://trac.ffmpeg.org/wiki/How%20to%20concatenate%20(join%2C%20merge)%20media%20files#differentcodec) to help me with this and have created the following command:
ffmpeg -i OHIn.wav -i OHOut.wav -filter_complex '[0:0] [1:0] concat=n=2:a=1 [a]' -map '[a]' output.wav
However, when I run this on Mac OS X using version 2.0.1 of FFMpeg, I get the following error message:
Stream specifier ':0' in filtergraph description [0:0] [1:0] concat=n=2:a=1 [a] matches no streams.
Here is my full output from the terminal:
~/ffmpeg -i OHIn.wav -i OHOut.wav -filter_complex '[0:0] [1:0] concat=n=2:a=1 [a]' -map '[a]' output.wav
ffmpeg version 2.0.1 Copyright (c) 2000-2013 the FFmpeg developers
built on Aug 15 2013 10:56:46 with llvm-gcc 4.2.1 (LLVM build 2336.11.00)
configuration: --prefix=/Volumes/Ramdisk/sw --enable-gpl --enable-pthreads --enable-version3 --enable-libspeex --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-avfilter --enable-libopencore_amrwb --enable-libopencore_amrnb --enable-filters --enable-libgsm --arch=x86_64 --enable-runtime-cpudetect
libavutil 52. 38.100 / 52. 38.100
libavcodec 55. 18.102 / 55. 18.102
libavformat 55. 12.100 / 55. 12.100
libavdevice 55. 3.100 / 55. 3.100
libavfilter 3. 79.101 / 3. 79.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from 'OHIn.wav':
Duration: 00:00:06.71, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, wav, from 'OHOut.wav':
Duration: 00:00:07.19, bitrate: 1411 kb/s
Stream #1:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream specifier ':0' in filtergraph description [0:0] [1:0] concat=n=2:a=1 [a] matches no streams.
I do not understand why this does not work. FFMpeg shows that the streams 0:0 and 1:0 exist in the source files. The only other similar problems online have surrounded the use of the single quote in Windows, however testing of this confirm it does not apply to my Mac command line.
Any help would be much appreciated.

You need to tell the concat filter the number of output video streams. The default is v=1 for video and a=0 for audio, but you have no video streams. It's best to not rely on the defaults. Manually list the number of input segments (n), output video streams (v), and output audio streams (a).
ffmpeg -i input0.wav -i input1.wav -filter_complex "[0:a][1:a]concat=n=2:v=0:a=1[a]" -map "[a]" output.wav
Notice that I added v=0.
See the concat filter documentation for more info.

In addition to upvoting Lord Neckbeard's response, which, solved my problem btw: I wanted to provide a working example of a Bash Shell script, showing how I concatenate three mp3 files (an intro, middle and outro, each having the same bitrate of 160 kbps, sample rate of 44.1 Khz) into one result mp3. The reason why my filter graph reads:
[0:a] [1:a] [2:a]
instead of something like:
[0:0] [1:0] [2:0]
is because some mp3s had artwork, which, ffmpeg sees as two streams for each input mp3 file, one audio (for the music itself) and one video (for the image artwork file).
The :a portion lets ffmpeg know that you want it to use only the audio stream(s) that it reads for that input file and to pass that along to the concat filter. So any video filters get ignored. The benefit of doing this is that you don't need to know the position of the video stream (so that you don't accidentally pass it) as specified by running a command like:
ffprobe control-intro-recording.mp3.
Anyways, I digress, here's the shell script:
#!/bin/sh
ffmpeg -i ./source-files/control-intro-recording.mp3 \
-i ./source-files/control-middle-1-hour-recording-with-artwork-160-kbps.mp3 \
-i ./source-files/control-outro-recording.mp3 \
-filter_complex '[0:a] [1:a] [2:a] concat=n=3:v=0:a=1 [a]' \
-map '[a]' ./output-files/control-output-with-artwork-160-kbps-improved.mp3

I ran into this Stream specifier ':0' in filtergraph description [0:0] [1:0]... error trying to combine two video files. #LordNeckbeard's answer helped me diagnose the issue. I mention it as a separate answer in case a future querent like myself encounters this situation with video files.
It turned out that one of my videos didn't have an audio track. Adding an audio track with
ffmpeg -f lavfi -i aevalsrc=0 -i title-slide.mp4 -shortest -c:v copy \
-c:a mp3 -strict experimental title.mp4
got me going.

Related

ffmpeg complex filtering: how to get around

Alright, I have my own compiled ffmpeg with --enable-lv2. This allows for 3rd-party plugins to work. The plugin I use is: https://github.com/lucianodato/speech-denoiser it's a plugin that wraps around this RNN noise reduction library: https://github.com/GregorR/rnnoise-models
The following commands work:
(1) ffmpeg -i input.mov -filter_complex '[0:a]lv2=plugin=https\\://github.com/lucianodato/speech-denoiser[audio]' -map "[audio]" output.wav
(2) ffmpeg -i input.mov -filter_complex '[0:v]copy[video]' -map "[video]" output.mov
But when I do the combination, that doesn't work.
ffmpeg -i input.mov -filter_complex '[0:a]lv2=plugin=https\\://github.com/lucianodato/speech-denoiser[audio];[0:v]copy[video]' -map "[audio]" -map "[video]" output.mov
I think the error is essentially this:
Channel layout change is not supported
Error while filtering: Not yet implemented in FFmpeg, patches welcome
Failed to inject frame into filter network: Not yet implemented in FFmpeg, patches welcome
Error while processing the decoded data for stream #0:0
My guess: this 3rd-party filter is not configure to work with any other output stream other than audio.
My question: can I somehow trick this 3rd-party plugin that it is outputting to an audio file, while still outputting everything to a video file?
Note: I know, I can simply split this up in 2 commands and be done with it, so I'm wondering if I can accomplish this via one ffmpeg command. How I would split it up in 2 commands is as follows:
ffmpeg -i out_cropped.mov -af 'lv2=plugin=https\\://github.com/lucianodato/speech-denoiser' -vcodec copy out_cropped_denoised.wav
&&
ffmpeg -i out_cropped.mov -i out_cropped_denoised.wav -c:v copy -map 0:v:0 -map 1:a:0 out_cropped_denoised.mov
But I want to be able to put it all in one complex filter (ideally) or at least in one ffmpeg command.
Appendix: here is the full interaction
ffmpeg -i input.mov -filter_complex '[0:a]lv2=plugin=https\\://github.com/lucianodato/speech-denoiser[audio];[0:v]copy[video]' -map "[audio]" -map "[video]" output.mov
ffmpeg version N-95577-g68f623d644 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.8)
configuration: --prefix=/usr/local --enable-gpl --enable-nonfree --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libopus --enable-libxvid --enable-lv2 --samples=fate-suite/
libavutil 56. 35.101 / 56. 35.101
libavcodec 58. 60.100 / 58. 60.100
libavformat 58. 33.100 / 58. 33.100
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 65.100 / 7. 65.100
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mov':
Metadata:
major_brand : qt
minor_version : 512
compatible_brands: qt
encoder : Lavf58.29.100
Duration: 00:16:19.11, start: 0.000000, bitrate: 1341 kb/s
Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1080x960, 1262 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : Core Media Video
encoder : Lavc58.54.100 libx264
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 69 kb/s (default)
Metadata:
handler_name : Core Media Audio
File 'output.mov' already exists. Overwrite? [y/N] y
#ote: I typed yes and then this came.
Stream mapping:
Stream #0:0 (h264) -> copy
Stream #0:1 (aac) -> lv2
lv2 -> Stream #0:0 (aac)
copy -> Stream #0:1 (libx264)
Press [q] to stop, [?] for help
[out_0_0 # 0x7fa6811066c0] Channel layout change is not supported
Error while filtering: Not yet implemented in FFmpeg, patches welcome
Failed to inject frame into filter network: Not yet implemented in FFmpeg, patches welcome
Error while processing the decoded data for stream #0:0
I forgot to post an answer here, but I recompiled the ffmpeg project.
And then I could use this command ffmpeg -i out_cropped.mov -af 'lv2=plugin=https\\://github.com/lucianodato/speech-denoiser' -vcodec copy out_cropped_denoised.wav
I remember that I wrote a compilation guide to myself as compiling it seemed a scary thing to do. And it was (just a little), but ultimately it was perfectly doable.
Here's the guide.
How to compile ffmpeg, lv2 and speech-denoiser for mac and denoise your audio files (and put it into videos) on a Mac!
Helpful guide for compiling ffmpeg on MacOS:
CompilationGuide/macOS – FFmpeg
Install depencencies
brew install automake fdk-aac git lame libass libtool libvorbis libvpx \
opus sdl shtool texi2html theora wget x264 x265 xvid nasm
Install lilv (dependency for lv2)
brew install lilv #because of ERROR: lilv-0 not found using pkg-config when doing ./configure right away
Configure ffmpeg
./configure --prefix=/usr/local --enable-gpl --enable-nonfree --enable-libass \
--enable-libfdk-aac --enable-libfreetype --enable-libmp3lame \
--enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libopus --enable-libxvid --enable-lv2 \
--samples=fate-suite/
Make & Install
make
sudo make install
Install speech denoiser dependencies + the project itself
brew update
brew cask uninstall oclint
brew install lv2 meson ninja pkg-config autoconf m4 libtool automake
#Download and install speech denoiser
git clone https://github.com/lucianodato/speech-denoiser.git
cd speech-denoiser
chmod +x install.sh && ./install.sh
Check fo see if install exists
lv2ls #You got this command from installing lilv
Output: https://github.com/lucianodato/speech-denoiser
(yep a URL)
Use your command!
#audio to denoised audio
ffmpeg -i out_cropped.mov -af 'lv2=plugin=https\\://github.com/lucianodato/speech-denoiser' -vcodec copy out_cropped_denoised.wav
#for if you want to put it with a video
&&
ffmpeg -i out_cropped.mov -i out_cropped_denoised.wav -c:v copy -map 0:v:0 -map 1:a:0 out_cropped_denoised.mov

How can I mux a MKV and MKA file and get it to play in a browser?

I'm using ffmpeg to merge .mkv and .mka files into .mp4 files. My current command looks like this:
ffmpeg -i video.mkv -i audio.mka output_path.mp4
The audio and video files are pre-signed urls from Amazon S3. Even on a server with sufficient resources, this process is going very slowly. I've researched situations where you can tell ffmpeg to skip re-encoding each frame, but I think that in my situation it actually does need to re-encode each frame.
I've downloaded 2 sample files to my macbook pro and have installed ffmpeg locally via homebrew. When I run the command
ffmpeg -i video.mkv -i audio.mka -c copy output.mp4
I get the following output:
ffmpeg version 3.3.2 Copyright (c) 2000-2017 the FFmpeg developers
built with Apple LLVM version 8.1.0 (clang-802.0.42)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
libavutil 55. 58.100 / 55. 58.100
libavcodec 57. 89.100 / 57. 89.100
libavformat 57. 71.100 / 57. 71.100
libavdevice 57. 6.100 / 57. 6.100
libavfilter 6. 82.100 / 6. 82.100
libavresample 3. 5. 0 / 3. 5. 0
libswscale 4. 6.100 / 4. 6.100
libswresample 2. 7.100 / 2. 7.100
libpostproc 54. 5.100 / 54. 5.100
Input #0, matroska,webm, from '319_audio_1498590673766.mka':
Metadata:
encoder : GStreamer matroskamux version 1.8.1.1
creation_time : 2017-06-27T19:10:58.000000Z
Duration: 00:00:03.53, start: 2.831000, bitrate: 50 kb/s
Stream #0:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
title : Audio
Input #1, matroska,webm, from '319_video_1498590673766.mkv':
Metadata:
encoder : GStreamer matroskamux version 1.8.1.1
creation_time : 2017-06-27T19:10:58.000000Z
Duration: 00:00:03.97, start: 2.851000, bitrate: 224 kb/s
Stream #1:0(eng): Video: vp8, yuv420p(progressive), 640x480, SAR 1:1 DAR 4:3, 30 tbr, 1k tbn, 1k tbc (default)
Metadata:
title : Video
[mp4 # 0x7fa4f0806800] Could not find tag for codec vp8 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
Stream #1:0 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
Last message repeated 1 times
So it appears that the specific encodings I'm working with are vp8 videos and opus audio files, which I believe are incompatible with the .mp4 output container. I would appreciate answers that cover ways of optimally merging vp8 and opus into .mp4 output or answers that point me in the direction of output media formats that are both compatible with vp8 & opus and are playable on web and mobile devices so that I can bypass the re-encoding step altogether.
EDIT:
Just wanted to provide a benchmark after following LordNeckbeard's advice:
4 min 41 second video transcoded locally on my mac
LordNeckbeard’s approach : 15 mins 55 seconds (955 seconds)
Current approach : 18 mins 49 seconds (1129 seconds)
18% speed increase
You can use ffmpeg to mux and/or re-encode MKV and MKA into web browser compatible formats such as Webm or MP4.
Webm mux: If the input formats are VP8/VP9 video with Vorbis or Opus audio
You can just mux into Webm if your inputs are VP8 or VP9 video and Vorbis or Opus audio, such as the inputs in your question. This should be fast because it will not re-encode:
ffmpeg -i video.mkv -i audio.mka -c copy output.webm
Default stream selection behavior is to select one stream per stream type, so with -map you can tell it which streams to choose to prevent mistakes. For example, if both inputs contain multiple streams, but you only want to first video stream from video.mkv and the first audio stream from audio.mka:
ffmpeg -i video.mkv -i audio.mka -map 0:v:0 -map 1:a:0 -c copy -movflags +faststart output.webm
MP4 mux: If the input formats are H.264/H.265 video and AAC audio
ffmpeg -i video.mkv -i audio.mka -c copy -movflags +faststart output.mp4
-movflags +faststart was added because you mentioned web playback. This will allow the video to begin playback before it is completely downloaded by the client.
Webm Re-encode: If the input formats are not compatible with Webm
You'll need to re-encode:
ffmpeg -i video.mkv -i audio.mka -c:v libvpx-vp9 -crf 33 -b:v 0 -c:a libopus output.webm
VP9 is really slow. If you want VP8 instead use -c:v libvpx. For more info see FFmpeg Wiki: VP8 and FFmpeg Wiki: VP9.
If you don't have libopus support use libvorbis instead.
MP4 Re-encode: If the input formats are not compatible with MP4
ffmpeg -i video.mkv -i audio.mka -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart output.mp4
For video, control quality with -crf and encoding speed with -preset. See FFmpeg Wiki: H.264 and FFmpeg Wiki: AAC for more info.
If your target devices are limited in the H.264 profiles they support you can add -profile:v main or -profile:v baseline.
ffprobe for scripting
You can make a script to automate this. ffprobe can be used to determine the formats:
$ ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 video.mkv
h264
$ ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 audio.mka
aac
The ffprobe outputs can be used as variables in an if/then statement.

Concat multiple (self-generated) videos using ffmpeg on raspbian linux

I am a very talented sleep talker, so I decided to write a solution that records the things I talk at night to make funny videos with subtitles of it. The project is nearly done, but I got a big problem with concating videos I generated before.
The video parts are generated from single png frames using this command:
ffmpeg -y -framerate 15 -i "${images_file_path}" -c:v libx264 -r 30 -pix_fmt yuv420p "${video_file_path}"
Then the sound is added using this command (got this from #9049970 and #11779490):
ffmpeg -y -i "${video_file_path}" -i "${mp3_file_path}" -map 0:v -map 1:a -vcodec copy -acodec copy -shortest "${final_video_file_path}"
All this is causing no problems so far, but I think it may be relevant to know how the videos are generated. I can watch all this and get valid video and sound - the full source code of this first part can be found here.
Now I added a feature that is able to generate "full videos" containing a title and a various number of previously generated "video parts" using this command:
ffmpeg -f concat -i "${video_list_path}" -filter_complex "${filter_string} concat=n=${input_file_counter}:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" "${full_video_path}"
But something is wrong with it and I get this error:
Invalid file index 1 in filtergraph description [0:v:0] [1:v:0] [2:v:0] [2:a:0] [3:v:0] [4:v:0] [4:a:0] [5:v:0] [6:v:0] [6:a:0] [7:v:0] concat=n=8:v=1:a=1 [v] [a].
The full output is:
ffmpeg version N-77213-g7c1c453 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.2 (Raspbian 4.9.2-10)
configuration: --enable-shared --enable-gpl --prefix=/usr --enable-nonfree --enable-libmp3lame --enable-libfaac --enable-libx264 --enable-version3 --disable-mmx
libavutil 55. 10.100 / 55. 10.100
libavcodec 57. 17.100 / 57. 17.100
libavformat 57. 20.100 / 57. 20.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 20.100 / 6. 20.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
[mov,mp4,m4a,3gp,3g2,mj2 # 0xc2e900] Auto-inserting h264_mp4toannexb bitstream filter
Input #0, concat, from '/usr/sleeptalk/records-rendered/3enguzpuu2gw0ogk8wkko/videos.txt':
Duration: N/A, start: 0.000000, bitrate: 61 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 58 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s
Metadata:
handler_name : SoundHandler
Invalid file index 1 in filtergraph description [0:v:0] [1:v:0] [2:v:0] [2:a:0] [3:v:0] [4:v:0] [4:a:0] [5:v:0] [6:v:0] [6:a:0] [7:v:0] concat=n=8:v=1:a=1 [v] [a].
I also wrote a test case so you can reproduce this on your local machine. Download the files from my dropbox. Also, the full script that renders the "final move" can be found here.
Would be great to get an Idea, got struggle to fix this the last two days.
You're using both the concat demuxer as well as the concat filter. Skip the latter, because
a) it's unnecessary and
b) I don't believe the demuxer is inducting all input files as separate inputs so the indices beyond 0 don't make sense. Also, the concat filter needs equal number of streams per input file, and their input assignment has to be pair-wise i.e. [0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0]....
Instead, use
ffmpeg -f concat -i "${video_list_textfile}" -c copy "${full_video_path}"
where ${video_list_textfile} is a text file of the form
file 'file1.mp4'
file 'file2.mp4'
file 'file3.mp4'
...

FFmpeg inaccurate outputs [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
ffmpeg: videos before and after conversion aren't the same length
Recently, I've been trying to use FFmpeg for an application which requires a VERY accurate manipulation when it comes to the time parameter (milliseconds resolution). Unfortunately, I was surprised to find out that FFmpeg's manipulation functionalities return some inaccurate results.
Here is the output of 'ffmpeg':
ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers
built on Jul 25 2012 19:55:05 with gcc 4.2.1 (Apple Inc. build 5664)
configuration: --enable-gpl --enable-shared --enable-pthreads --enable-libx264 --enable-libmp3lame
libavutil 51. 54.100 / 51. 54.100
libavcodec 54. 23.100 / 54. 23.100
libavformat 54. 6.100 / 54. 6.100
libavdevice 54. 0.100 / 54. 0.100
libavfilter 2. 77.100 / 2. 77.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 15.100 / 0. 15.100
libpostproc 52. 0.100 / 52. 0.100
Now, let's assume I want to rip the audio track of 'foo.mov'. Here is the relevant output of 'ffmpeg -i foo.mov':
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.mov':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2012-07-24 23:16:08
Duration: 00:00:40.38, start: 0.000000, bitrate: 805 kb/s
Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 480x360, 733 kb/s, 24.46 fps, 29.97 tbr, 600 tbn, 1200 tbc
Metadata:
rotate : 90
creation_time : 2012-07-24 23:16:08
handler_name : Core Media Data Handler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, s16, 63 kb/s
Metadata:
creation_time : 2012-07-24 23:16:08
handler_name : Core Media Data Handler
As you probably noticed, the video file duration is 00:00:40.38. Using the following command, I ripped it's audio track:
'ffmpeg -i foo.mov foo.wav'
Output:
Output #0, wav, to 'foo.wav':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2012-07-24 23:16:08
encoder : Lavf54.6.100
Stream #0:0(und): Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Metadata:
creation_time : 2012-07-24 23:16:08
handler_name : Core Media Data Handler
Stream mapping:
Stream #0:1 -> #0:0 (aac -> pcm_s16le)
Press [q] to stop, [?] for help
size=3482kB time=00:00:40.42 bitrate= 705.6kbits/s
video:0kB audio:3482kB global headers:0kB muxing overhead 0.001290%
As you can see, the output file is longer than the file in the input.
Another example is audio (and video) file trimming:
Let's assume I would like to use ffmpeg for audio file trimming. I used the next command:
'ffmpeg -t 00:00:10.000 -i foo.wav trimmed_foo.wav -ss 00:00:25.000'
Output:
[wav # 0x10180e800] max_analyze_duration 5000000 reached at 5015510
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, wav, from 'foo.wav':
Duration: 00:00:40.42, bitrate: 705 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Output #0, wav, to 'trimmed_foo.wav':
Metadata:
encoder : Lavf54.6.100
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le)
Press [q] to stop, [?] for help
size=864kB time=00:00:10.03 bitrate= 705.6kbits/s
video:0kB audio:864kB global headers:0kB muxing overhead 0.005199%
Again, the output file is 30 milliseconds longer than I expected.
I tried, for a long time, to research the issue without any success. When I use audacity for the same functionality, it does it very accurately!
Does anyone have any idea how to solve this problem?
TL; DR: FFmpeg and your iOS device are the wrong tools for your needs.
There are a host of problems to cover, so in no particular order:
Neither FFmpeg or the underlying codecs that you're working with are designed for the sort of time resolution you want. 40ms is 1 frame at 25fps, which just isn't much in the context of most video and audio files. Hyperaccurate timing isn't a design feature of common audio codecs, like your source AAC data, and FFmpeg follows suit.
Don't do any transcoding! If you want to change the data as little as possible... don't change it. You can use ffmpeg -i in.mov -c:a copy out.m4a to extract the audio stream exactly instead of transcoding it to wav format.
Use FFprobe instead of FFmpeg to get file information. FFmpeg just gives some cursory information about input and output files because its default logging is overly verbose. FFprobe is usually bundled with FFmpeg and is specifically designed to extract information in a convenient form. Use ffprobe -show_streams -show_format in.mov to get information.
Increase your -analyzeduration! You might've noticed the note about max_analyze_duration reached in your output. From the docs that's how many microseconds are going to actually be read of the file before FFmpeg estimates the total length. Again, for most purposes knowing the length of the file to microsecond accuracy isn't feasible or desirable and it is expensive. If you want hyperaccuracy, make sure that that parameter is set much higher, probably longer than your actual input.
Be a bit more careful with your option placement. This is fairly minor, but I thought that I should bring it up in case you're unaware. Many of FFmpeg's options behave differently depending on the order they're given with respect to input and output. Notably -ss that you're using. You have it after the input, which is where you want it, but you also have the output-only option -t at the beginning which is... weird. The more natural way to order that command would be:
ffmpeg -i foo.wav -ss 00:00:25.000 -t 00:00:10.000 trimmed_foo.wav
All the timing commands accept input in seconds (including fractional seconds), so you don't have to prepend everything with 00:00:.
Distinguish container length and actual stream length. I don't use Audacity, but I wouldn't be surprised if it showed extreme accuracy because it was lying to you about what it was doing. Actually trimming audio or video data with millisecond accuracy would require not merely choosing which frames from the input are included in the output (which is accurate to 40ms at 25fps!) but changing frame data to insert silence at the end. Far easier would be to just trim based on frame inclusion, then put the hyper-accurate length in the container file metadata. Some playback software might actually cut off based on that number, but again, most AV software just isn't designed for that level of accuracy. I would be curious to see what FFmpeg shows as the length of a file trimmed by Audacity.
That's all that springs to mind now, but I'm happy to give more feedback once you've had a chance to incorporate some of the above. My guess would be that this sort of accuracy is required for research pruposes, in which case, happy researching!

ffmpeg segments only the first part of my audio file

I'm implementing a http live streaming server to send audio file to iOS devices.
No problem with Apple's tools, mediafilesegmenter, my files are valid and it works fine.
I'm trying now to segment the same file using ffmpeg. I've downloaded the last stable version which is the 0.10.2 for now.
Here is how I try to segment my mp3 file:
./ffmpeg -re -i input.mp3 -f segment -segment_time 10 -segment_list outputList.m3u8 -acodec libmp3lame -map 0 output%03d.mp3
It starts the mapping like expected but finish with only one .mp3 file.
Did I miss something in the process?
Thanks in advance.
edit
Ok here is my latest command line:
ffmpeg -i input.mp3 -c:a libmp3lame -b:a 128k -map 0:0 -f segment -segment_time 10 -segment_list outputlist.m3u8 -segment_format mp3 'output%03d.mp3'
It still gives me only one file but the file is the hole song, not only one part.
Here is the output of ffmpeg:
ffmpeg version 0.10.2 Copyright (c) 2000-2012 the FFmpeg developers
built on Apr 20 2012 07:08:29 with gcc 4.5.2
configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libmp3lame
libavutil 51. 35.100 / 51. 35.100
libavcodec 53. 61.100 / 53. 61.100
libavformat 53. 32.100 /
53. 32.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 61.100 / 2. 61.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
[mp3 # 0x8e4f120] max_analyze_duration 5000000 reached at 5015510
Input #0, mp3, from 'BeachHouse-Myth.mp3':
Metadata:
title : Myth
artist : Beach House
track : /
album : Bloom
disc : /
genre : Alternative
TSRC : USSUB1296501
Duration: 00:04:18.69, start: 0.000000, bitrate: 320 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 320 kb/s Output #0, segment, to 'stream%03d.mp3': Metadata:
title : Myth
artist : Beach House
track : /
album : Bloom
disc : /
genre : Alternative
TSRC : USSUB1296501
encoder : Lavf53.32.100
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (mp3 -> libmp3lame)
Press [q] to stop, [?] for help
Truncating packet of size 1024 to 105ate= 0.0kbits/s
Truncating packet of size 1024 to 1
size= 0kB time=00:04:18.71 bitrate= 0.0kbits/s video:0kB audio:4042kB global headers:0kB muxing overhead -100.000000%
Audio only might be a bug. I contacted the FFMPEG player bug list, and a bug is filed: http://ffmpeg.org/trac/ffmpeg/ticket/1290

Resources