JavaCV 采集摄麦克风音频数据

上一次介绍 JavaCV采集摄像头及桌面视频数据,同样的,采集音频数据也可以使用JavaCV。

其他关于JavaCV的文章,可以通过下面的链接查看:
JavaCV-开发系列文章汇总篇(https://www.cnblogs.com/itqn/p/14696221.html)

引入依赖

引入JavaCV 1.5.5 maven依赖:

<properties>
  <javacpp.version>1.5.5</javacpp.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>${javacpp.version}</version>
  </dependency>
  <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>${javacpp.version}</version>
  </dependency>
</dependencies>

采用FFmpeg采集麦克风数据

跟采集视频一样,麦克风音频数据也可以使用ffmpeg采集,同样使用dshow,这里有点不同的是采集的数据使用AAC编码后存储。

如果想采集PCM数据,可以查看我的另外一篇文章 JavaCV FFmpeg采集麦克风PCM音频数据

public class Sample02 {

  public static void main(String[] args) throws Exception {
    FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("audio=麦克风阵列 (Realtek(R) Audio)");
    grabber.setFormat("dshow");

    FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("Test01.aac"), 2);
    recorder.setAudioOption("crf", "0");
    recorder.setAudioQuality(0);
    recorder.setAudioBitrate(192000);
    recorder.setSampleRate(44100);
    recorder.setAudioChannels(2);
    // AAC
    recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);

    grabber.start();
    recorder.start();

    Frame frame = null;
    int count = 0;
    while ((frame = grabber.grab()) != null) {
      recorder.record(frame);
      if (count++ > 100) {
        break;
      }
    }
    grabber.close();
    recorder.close();
  }
}

直接读取麦克风音频数据

除了使用FFmpeg采集麦克风音频数据外,还是采用直接读取麦克风音频字节数据的方式,采集音频数据,同样进行AAC编码。

public class Sample01 {

  public static void main(String[] args) throws Exception {
    FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("Test01.aac"), 2);
    recorder.setAudioOption("crf", "0");
    recorder.setAudioQuality(0);
    recorder.setAudioBitrate(192000);
    recorder.setSampleRate(44100);
    recorder.setAudioChannels(2);
    // AAC
    recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
    recorder.start();

    AudioFormat format = new AudioFormat(44100.0F, 16, 2, true, false);
    TargetDataLine line = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, format));
    line.open(format);
    line.start();

    int sampleRate = (int) format.getSampleRate();
    int numChannels = format.getChannels();
    byte[] buffer = new byte[sampleRate * numChannels];
    int count = 0;
    while (count++ < 100) {
      int nBytesRead = 0;
      while (nBytesRead == 0) {
        nBytesRead = line.read(buffer, 0, line.available());
      }
      int nSamplesRead = nBytesRead / 2;
      short[] samples = new short[nSamplesRead];
      ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
      ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);
      recorder.recordSamples(sampleRate, numChannels, sBuff);
    }
    recorder.close();
  }
}

效果展示

采集的AAC数据可以直接使用VLC播放:

===========================================================================
HiIT青年
关注公众号,阅读更多关于JavaCV的文章。

posted @ 2021-04-10 13:09  HiIT青年  阅读(1441)  评论(1编辑  收藏  举报