I was trying to conver audio formats to ogg ( vorbis ) file using Xuggler.
First, i've attemted the very basic way to do it,
IMediaReader readermp3 = ToolFactory.makeReader(sourcefile);
IMediaWriter writer = ToolFactory.makeWriter(targetfilemp3, readermp3);
readermp3.addListener(writer);
while (readermp3.readPacket() == null)
targetfile ended with .ogg. This actually works, however it encodes to ogg FLAC instead of ogg vorbis.
Then i've tried to do some of its parts manually,
First - Get the original sample rate and channel number, Second - addaudiostream using these sample rate,channel number AND Codec id for vorbis.
IMediaReader readermp3 = ToolFactory.makeReader(sourcefile);
IContainer readercontainer = readermp3.getContainer();
readercontainer.open(sourcefile, IContainer.Type.READ,null);
int numStreams = readercontainer.getNumStreams();
IStream stream = null;
for(int i = 0; i < numStreams; i++) {
stream = readercontainer.getStream(i); }
IStreamCoder mycoder = stream.getStreamCoder();
int sourcechannels,sourcesamplerate;
sourcechannels = mycoder.getChannels();
sourcesamplerate = mycoder.getSampleRate();
/* these were for getting samplerate and channels i don't think they are relevant but im */copying it here just incase
IMediaWriter writer = ToolFactory.makeWriter(targetfilemp3, readermp3);
writer.addAudioStream(0, 0,ICodec.ID.CODEC_ID_VORBIS,sourcechannels, sourcesamplerate);
readermp3.addListener(writer);
while (readermp3.readPacket() == null)
;
When i try to run this, it gives me an error "ERROR org.ffmpeg - [libvorbis @ 0436F300] Specified sample_fmt is not supported." "WARN com.xuggle.xuggler - Error: could not open codec (../../../../../../../csrc/com/xuggle/xuggler/StreamCoder.cpp:831)"
Sidenote = it works with mp3,wav and flac ogg file. Also, i have tried changing my extension to .vorbis instead of .ogg. Still the same error.
Then ofcourse, i googled it. There is only 1 relevant q/a about this issue https://groups.google.com/forum/?fromgroups=#!topic/xuggler-users/18hsI_LGxI4
however, i didn't understand the answer =).
Thanks a lot for the answers.
There's a funky thing going on with Xuggler where it doesn't always allow you to set the sample rate of IAudioSamples
. You'll need to use an IAudioResampler
.
Took me a while to figure this out. This post by Marty helped a lot, though his code is outdated now.
Here's how you fix it.
I'm assuming here that audio input has been properly set up, resulting in an IStreamCoder
called audioCoder
.
After that's done, you are probably initiating an IMediaWriter
and adding an audio stream like so:
final IMediaWriter oggWriter = ToolFactory.makeWriter(oggOutputFile);
// Using stream 1 'cause there is also a video stream.
// For an audio only file you should use stream 0.
oggWriter.addAudioStream(1, 1, ICodec.ID.CODEC_ID_VORBIS,
audioCoder.getChannels(), audioCoder.getSampleRate());
Now create an IAudioResampler
:
IAudioResampler oggResampler = IAudioResampler.make(audioCoder.getChannels(),
audioCoder.getChannels(),
audioCoder.getSampleRate(),
audioCoder.getSampleRate(),
IAudioSamples.Format.FMT_FLT,
audioCoder.getSampleFormat());
And tell your IMediaWriter
to update to its sample format:
// The stream 1 here is consistent with the stream we added earlier.
oggWriter.getContainer().getStream(1).getStreamCoder().
setSampleFormat(IAudioSamples.Format.FMT_FLT);
You are currently probably initiating an IAudioSamples
and filling it with audio data, like so:
IAudioSamples audioSample = IAudioSamples.make(512, audioCoder.getChannels(),
audioCoder.getSampleFormat());
int bytesDecoded = audioCoder.decodeAudio(audioSample, packet, offset);
Now initiate an IAudioSamples for our resampled data:
IAudioSamples vorbisSample = IAudioSamples.make(512, audioCoder.getChannels(),
IAudioSamples.Format.FMT_FLT);
Finally, resample the audio data and write the result:
oggResampler.resample(vorbisSample, audioSample, 0);
oggWriter.encodeAudio(1, vorbisSample);
Just a hint to get your output files to play well: