如何获得音频使用Xuggler编码 [英] How to get Audio for encoding using Xuggler

查看:373
本文介绍了如何获得音频使用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的

声波

如何设置<一个SourceDataLine的是Java /量一>

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编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆