Audio convirtiendo con Xuggler

Estoy tratando de convertir archivos de audio aac / wav / wma a mp3 con Xuggler en Java.

Desafortunadamente, tengo una gran pérdida de calidad. El tamaño del archivo de entrada es de aproximadamente 7 MB y el tamaño del archivo de salida es de solo 1,5 MB.

La frecuencia de muestreo se establece en 44100 Hz, ¿hay otros parámetros para establecer?

Gracias por sus respuestas

  if (args.length <= 1)
        throw new IllegalArgumentException("must pass an input filename and output filename as argument");

    IMediaWriter writer = ToolFactory.makeWriter(args[1]);

    String filename = args[0];

    // Create a Xuggler container object
    IContainer container = IContainer.make();

    // Open up the container
    if (container.open(filename, IContainer.Type.READ, null) < 0)
        throw new IllegalArgumentException("could not open file: " + filename);

    // query how many streams the call to open found
    int numStreams = container.getNumStreams();

    // and iterate through the streams to find the first audio stream
    int audioStreamId = -1;
    IStreamCoder audioCoder = null;
    for(int i = 0; i < numStreams; i++)
    {
        // Find the stream object
        IStream stream = container.getStream(i);
        // Get the pre-configured decoder that can decode this stream;
        IStreamCoder coder = stream.getStreamCoder();

        if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
        {
            audioStreamId = i;
            audioCoder = coder;
            audioCoder.setBitRate(container.getBitRate());

            break;
        }
    }

    if (audioStreamId == -1)
        throw new RuntimeException("could not find audio stream in container: "+filename);

    /* We read only AAC file for the moment */
    if(audioCoder.getCodecID() != ICodec.ID.CODEC_ID_AAC 
        && audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WAVPACK 
        && audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAV1
        && audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAV2
        && audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAPRO
        && audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAVOICE)
    {
        System.out.println("Read only AAC, WAV or WMA files");
        System.exit(1);
    }

    audioCoder.setSampleFormat(IAudioSamples.Format.FMT_S16);
    /*
     * Now we have found the audio stream in this file.  Let's open up our decoder so it can
     * do work.
     */
    if (audioCoder.open() < 0)
        throw new RuntimeException("could not open audio decoder for container: "+filename);

    int streamIndex = writer.addAudioStream(0, 0, audioCoder.getChannels(), audioCoder.getSampleRate());


    System.out.println("audio Frame size : "+audioCoder.getAudioFrameSize());


    /*
     * Now, we start walking through the container looking at each packet.
     */
    IPacket packet = IPacket.make();

    while(container.readNextPacket(packet) >= 0)
    {
        /*
         * Now we have a packet, let's see if it belongs to our audio stream
         */
        if (packet.getStreamIndex() == audioStreamId)
        {
            /*
             * We allocate a set of samples with the same number of channels as the
             * coder tells us is in this buffer.
             * 
             * We also pass in a buffer size (1024 in our example), although Xuggler
             * will probably allocate more space than just the 1024 (it's not important why).
             */

            IAudioSamples samples = IAudioSamples.make(512, audioCoder.getChannels(),IAudioSamples.Format.FMT_S16 );

            /*
             * A packet can actually contain multiple sets of samples (or frames of samples
             * in audio-decoding speak).  So, we may need to call decode audio multiple
             * times at different offsets in the packet's data.  We capture that here.
             */
            int offset = 0;

            /*
             * Keep going until we've processed all data
             */         

            while(offset < packet.getSize())
            {
                int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset);
                if (bytesDecoded < 0)
                    throw new RuntimeException("got error decoding audio in: " + filename);

                offset += bytesDecoded;

                /*
                 * Some decoder will consume data in a packet, but will not be able to construct
                 * a full set of samples yet.  Therefore you should always check if you
                 * got a complete set of samples from the decoder
                 */                                     
                if (samples.isComplete())
                {
                    writer.encodeAudio(streamIndex, samples);   
                }
            }
        }
        else
        {
            /*
             * This packet isn't part of our audio stream, so we just silently drop it.
             */
            do {} while(false);
        }
    }

Respuestas a la pregunta(3)

Su respuesta a la pregunta