Thursday, March 8, 2012

Using ffmpeg tool to recode audio files...

I'm using ffmpeg library in one simulation project to support VoIP traffic. What bothers me is that on certain input files in mp3 format I constantly received error message about format error and then simulator would segmentation fault. The output codec is g726. So, to determine if this is a bug in my code, or something is really wrong with mp3 file I decided to use ffmpeg command line tool.

It turned out that it is necessary to experiment quite a bit with this command to achieve what you want, and in my case to recode mp3 file into wav file in g726.

First, I tried with the following command:
ffmpeg -i test.mp3 test.g726
That command specifies that ffmpeg should use test.mp3 as the input file and the output should be stored in test.g726 file. But, it stopped with the following error:
[NULL @ 0x2014c60] Unable to find a suitable output format for 'test.g726'
The problem in this case is that ffmpeg tries to deduce which codec to use based on the extension of the output file. In my case this extension didn't mean anything, it was only indicator to me which codec is used. So, I used option acodec to force use of g726:
ffmpeg -i test.mp3 -acodec g726 test.g726
Still no luck, the following error message was reported:
[NULL @ 0x21aec60] Unable to find a suitable output format for 'test.g726'
but, that gave me the clue. The problem is that output file format isn't recognized! I wanted to place g726 output into WAV file, so either changing extension from g726 into wav, or using -f option will do:
ffmpeg -i test.mp3 -acodec g726 test.wav
Now I got another error message. It's good, it means I'm progressing. The error message is:
[g726 @ 0x1dad1e0] Bitrate - Samplerate combination is invalid
This time the problem is that mp3 input file has 44khz sampling rate which is not supported by g726. So, using ar option, I specified sampling rate supported by g726, i.e. 8khz:
ffmpeg -i test.mp3 -acodec g726 -ar 8k test.wav
Then, a new message appeared:
[g726 @ 0x1f511e0] Only mono is supported
Ok, this is easy too, MP3 file is in stereo, while g726 supports only mono. So, I have to choose only one channel (or stream) from input file. Digging a bit through the manual gave the answer, I should use ac option. In other words, default number of output channels is the same as input ones. By using ac options it can be changed to 1, i.e. to mono output:
ffmpeg -i lucky.mp3 -acodec g726 -ar 8k -ac 1 test.wav
This solved the previous error, but now I got a new one:
[g726 @ 0xb6b1e0] Unsupported number of bits 8
Well, this is a confusing error message because it's obvious that it wants to use 8 bits per sample, but the question is where. Also, when you look into diagnostic information you'll notice that everything is 16 bits! But then, I realized that it uses sample frequency and default bit rate to calculate bits per sample, which turns out to be 8 bits. So, by increasing sampling frequency the problem is solved:
ffmpeg -i test.mp3 -acodec g726 -ar 16k -ac 1 test.wav
Finally, I come from where I started, to check if there is an error in input file, and it turns there is not, or, it is suppresed by ffmpeg. So, the problem is in my code obviously.

No comments:

About Me

scientist, consultant, security specialist, networking guy, system administrator, philosopher ;)