微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的音频文件在 Xuggle 中编码样本数组后如此断断续续? 总结问题

如何解决为什么我的音频文件在 Xuggle 中编码样本数组后如此断断续续? 总结问题

public class captureAudio{

    IMediaWriter writeraudio=null;
    long currentAudioTime;



    void startAudio() throws Exception {
        TargetDataLine line;

        //gets a TargetDataLine in which gets data from the Microphone
        line= getMic();

        //creates an array that is half the data buffer so that we don't have to worry about sample discards
        final byte[] audioBytes=new byte[line.getBufferSize()/2];

        final String outputFilename = "c:/Users/NICK/Desktop/SaveJPEG/"+"saved"+".aac";
        //creates a writer in which it's output is to outputFilename
        writeraudio = ToolFactory.makeWriter(outputFilename);

        //starts I/O process in which starts capturing  
        line.start();

        //gets current system time in nanoseconds
        currentAudioTime = System.nanoTime();


        //sets audioRunning to true 
        setstopper(true);

        writeraudio.addAudioStream(0,ICodec.ID.AV_CODEC_ID_AAC,1,44100);
        //create new thread in which audio will be captured and encoded
        Thread thread = new Thread() {
            @Override
            public void run() {
                while(audioRunning()) {
                    short[] audioSamples;
                    int numSamplesRead=0;
                    int numBytesRead=0;

                    //get the number of bytes read
                    numBytesRead=line.read(audioBytes,audioBytes.length);
                    numSamplesRead=numBytesRead/2;
                    //create an array with a size of numSamplesRead. It is smaller than numBytesRead since we
                    //have 16 bit of data in each index of this array
                    audioSamples = new short[numSamplesRead];

                    /*Since the IMediaWriter.encodeAudio method takes in a short array,We need to convert byte array to a short*/

                    //checks to see if the format is bigEndian or littleEndian which is indeed littleEndian by the format       
                    if(line.getFormat().isBigEndian()) {
                        for (int i = 0; i < numSamplesRead; i++) {

                            audioSamples[i] = (short)((audioBytes[2*i] << 8) | audioBytes[2*i + 1]);
                        }
                    }
                    else {

                        /*cast to short,get 2nd element create 8 zeros to the right(making it 16 bit) and include the first element (still 8 bit)*/ 
                        for (int i = 0; i < numSamplesRead; i++) {
                            audioSamples[i] = (short)((audioBytes[2*i + 1] << 8) | audioBytes[2*i]);

                        }
                    }
                    //Stream index is 0,pass in short[] audioSamples,get sample timestamp,units of timestamp
                    writeraudio.encodeAudio(0,audioSamples,System.nanoTime()-currentAudioTime,TimeUnit.NANOSECONDS);
                }



            }

        };
        //starts the thread above
        thread.start();
    }

TargetDataLine getMic() throws Exception {
//Audioformat object that takes a sample rate,bit size per sample,channel,and bool isBigEndian
AudioFormat format = new AudioFormat(44100F,16,true,false);
TargetDataLine line =null;
DataLine.Info info = new DataLine.Info(TargetDataLine.class,format); // format is an AudioFormat object
if (!AudioSystem.isLinesupported(info)) {
    throw new Exception();
    }

void stop() throws Exception {

    TargetDataLine mic = getMic();
    setstopper(false);
    mic.stop();
    mic.close();
    writeraudio.flush();
    writeraudio.close();
  }
}

总结

主要想法是我试图通过 TargetDataLine 从麦克风中检索数据,然后创建一个新线程来运行音频的编码过程以及我的 videoCapture 类用于对视频进行编码的主线程。在新线程内部,我将音频样本数组(最初是一个字节数组)转换为一个短数组,以在上述 IMediaWriter.encodeAudio(...) 方法中使用,作者将在该方法中成功创建一个 .acc 音频文件我的输出文件路径。

问题

当我运行代码时,我确实获得了所需的音频文件,但音频质量很差。当我播放音频时,它真的很不稳定而且断断续续。那么我究竟如何才能使音频质量更好呢?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。