本文介绍了如何获得音频使用Xuggler编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写录制屏幕和音频的应用。虽然屏幕录制完美的作品,我有在获得使用JDK库的原始音频困难。这里的code:

  {尝试
            //现在,我们要循环
            长STARTTIME = System.nanoTime();            的System.out.println(编码的图像......);
            而(!Thread.currentThread()。isInterrupted()){
                //取截屏
                屏幕的BufferedImage = robot.createScreenCapture(screenBounds);
                //转换为正确的图像类型
                BufferedImage的bgrScreen = convertToType(屏幕,
                        BufferedImage.TYPE_3BYTE_BGR);                // EN code图像
                writer.en codeVideo(0,bgrScreen,System.nanoTime()
                         - startTime时,TimeUnit.NANOSECONDS);                / *需要使用xuggler获得音频这里,然后带code。就像是                    WaveData WD =新WaveData();                    TargetDataLine的线;
                    AUS的AudioInputStream =新的AudioInputStream(线);                    短[] =样品getSourceSamples();
                       writer.en codeAudio(0,样本); * /
                如果(timeCreation小于10){
                    timeCreation = getGMTTime();
                }
                //睡眠帧率毫秒
                尝试{
                    视频下载((长)(1000 / FRAME_RATE.getDouble()));
                }赶上(例外前){
                    通信System.err.println(停止......);
                    打破;
                }            }
            //最后,我们告诉笔者,关闭和写入如果拖车
            //需要
        } {最后
            writer.close();
        }

这有一些伪code像

 而(haveMoreAudio())
 {
   短[] =样品getSourceSamples();
   writer.en codeAudio(0,样本);
 }

但究竟应该怎么为 getSourceSamples()

另外,奖金的问题 - 是否有可能从多个麦克风可以选择这种方法。

另请参阅:
<一href=\"http://stackoverflow.com/questions/13839850/xuggler-encoding-and-muxing/13934751?noredirect=1#comment32570748_13934751\">Xuggler编码和多路复用


解决方案

试试这个:

  //选择一个格式。需要16比特,其余部分可被设置为任何
//这是更好地枚举系统支持的格式,因为函数getline()可以与任何特定的格式错误了
AudioFormat的AudioFormat的=新AudioFormat的(44100.0F,16,2,真,假);//获取默认的TargetDataLine的与该格式
DataLine.Info dataLineInfo =新DataLine.Info(TargetDataLine.class,AudioFormat的);
TargetDataLine的行=(TargetDataLine的)AudioSystem.getLine(dataLineInfo);//打开并开始捕捉音频
line.open(AudioFormat的,line.getBufferSize());
line.start();而(真){
    //读取为原始字节
    字节[] = audioBytes新的字节[line.getBufferSize()/ 2]; //最好的大小?
    INT numBytesRead = 0;
    numBytesRead = line.read(audioBytes,0,audioBytes.length);    //转换为签订短裤重新presenting样本
    INT numSamplesRead = numBytesRead / 2;
    短[] = audioSamples新的短[numSamplesRead]
    如果(format.isBigEndian()){
        的for(int i = 0; I&LT; numSamplesRead;我++){
            audioSamples [I] =(短)((audioBytes [2 * 1] - ;&下; 8)| audioBytes [2 * I + 1]);
        }
    }
    其他{
        的for(int i = 0; I&LT; numSamplesRead;我++){
            audioSamples [I] =(短)((audioBytes [2 * I + 1];&下; 8)| audioBytes [2 * I]);
        }
    }    //使用audioSamples在Xuggler等
}

要选择一个麦克风,你可能不得不这样做:

  Mixer.Info [] = mixerInfo AudioSystem.getMixerInfo();
//通过看这里选择一个混频器,混频器不同的应该是不同的输入
INT selectedMixerIndex = 0;
调音台调音台= AudioSystem.getMixer(mixerInfo [selectedMixerIndex]);
TargetDataLine的行=(TargetDataLine的)mixer.getLine(dataLineInfo);

我认为这可能是多个麦克风将在一个混频器不同来源的数据线出现。在这种情况下,你必须打开它们,并调用 dataLine.getControl(FloatControl.Type.MASTER_GAIN).setValue(体积); 来打开和关闭它们

请参阅:
<一href=\"http://$c$c.google.com/p/speech-recognition-java-hidden-markov-model-vq-mfcc/source/browse/trunk/SpeechRecognitionHMM/src/org/ioe/tprsa/audio/WaveData.java\"相对=nofollow> WaveData.java

从TargetDataLine的

声波

如何设置

I'm writing an application that records the screen and audio. While the screen recording works perfectly, I'm having difficulty in getting the raw audio using the JDK libraries. Here's the code:

try {
            // Now, we're going to loop
            long startTime = System.nanoTime();

            System.out.println("Encoding Image.....");
            while (!Thread.currentThread().isInterrupted()) {
                // take the screen shot
                BufferedImage screen = robot.createScreenCapture(screenBounds);


                // convert to the right image type
                BufferedImage bgrScreen = convertToType(screen,
                        BufferedImage.TYPE_3BYTE_BGR);

                // encode the image
                writer.encodeVideo(0, bgrScreen, System.nanoTime()
                        - startTime, TimeUnit.NANOSECONDS);

                /* Need to get audio here and then encode using xuggler. Something like

                    WaveData wd = new WaveData();

                    TargetDataLine line;
                    AudioInputStream aus = new AudioInputStream(line);

                    short[] samples = getSourceSamples();
                       writer.encodeAudio(0, samples); */


                if (timeCreation < 10) {
                    timeCreation = getGMTTime();
                }
                // sleep for framerate milliseconds
                try {
                    Thread.sleep((long) (1000 / FRAME_RATE.getDouble()));
                } catch (Exception ex) {
                    System.err.println("stopping....");
                    break;
                }

            }
            // Finally we tell the writer to close and write the trailer if
            // needed
        } finally {
            writer.close();
        }

This page has some pseudo code like

while(haveMoreAudio())
 {
   short[] samples = getSourceSamples();
   writer.encodeAudio(0, samples);
 }

but what exactly should I do for getSourceSamples()?

Also, a bonus question - is it possible to choose from multiple microphones in this approach?

See also:Xuggler encoding and muxing

解决方案

Try this:

// Pick a format. Need 16 bits, the rest can be set to anything
// It is better to enumerate the formats that the system supports, because getLine() can error out with any particular format
AudioFormat audioFormat = new AudioFormat(44100.0F, 16, 2, true, false);

// Get default TargetDataLine with that format
DataLine.Info dataLineInfo = new DataLine.Info( TargetDataLine.class, audioFormat );
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(dataLineInfo);

// Open and start capturing audio
line.open(audioFormat, line.getBufferSize());
line.start();

while (true) {
    // read as raw bytes
    byte[] audioBytes = new byte[ line.getBufferSize() / 2 ]; // best size?
    int numBytesRead = 0;
    numBytesRead =  line.read(audioBytes, 0, audioBytes.length);

    // convert to signed shorts representing samples
    int numSamplesRead = numBytesRead / 2;
    short[] audioSamples = new short[ numSamplesRead ];
    if (format.isBigEndian()) {
        for (int i = 0; i < numSamplesRead; i++) {
            audioSamples[i] = (short)((audioBytes[2*i] << 8) | audioBytes[2*i + 1]);
        }
    }
    else {
        for (int i = 0; i < numSamplesRead; i++) {
            audioSamples[i] = (short)((audioBytes[2*i + 1] << 8) | audioBytes[2*i]);
        }
    }

    // use audioSamples in Xuggler etc
}

To pick a microphone, you'd probably have to do this:

Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
// Look through and select a mixer here, different mixers should be different inputs
int selectedMixerIndex = 0;
Mixer mixer = AudioSystem.getMixer(mixerInfo[ selectedMixerIndex ]);
TargetDataLine line = (TargetDataLine) mixer.getLine(dataLineInfo);

I think it's possible that multiple microphones will show up in one mixer as different source data lines. In that case you'd have to open them and call dataLine.getControl(FloatControl.Type.MASTER_GAIN).setValue( volume ); to turn them on and off.

See:WaveData.java

Sound wave from TargetDataLine

How to set volume of a SourceDataLine in Java

这篇关于如何获得音频使用Xuggler编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 02:43
查看更多