2

我浏览了 Java 的声音教程,但不知何故,它对于初学者来说太复杂了。
在这里
我的目标是:

  • 检测所有音频输入和输出设备
  • 让用户选择音频输入设备
  • 捕捉用户所说的
  • 输出到默认的音频输出设备
  • 现在我该怎么做呢?
    有没有更好的教程?
    我试过的:

    import javax.sound.sampled.*;
    public class SoundTrial {
        public static void main(String[] args) {
            Mixer.Info[] info = AudioSystem.getMixerInfo();
            int i =0;
            for(Mixer.Info print : info){
    
                System.out.println("Name: "+ i + " " + print.getName());
                i++;
            }
        }
    }  
    

    输出:

    Name: 0 Primary Sound Driver
    Name: 1 Speakers and Headphones (IDT High Definition Audio CODEC)
    Name: 2 Independent Headphones (IDT High Definition Audio CODEC
    Name: 3 SPDIF (Digital Out via HP Dock) (IDT High Definition Audio CODEC)
    Name: 4 Primary Sound Capture Driver
    Name: 5 Integrated Microphone Array (ID
    Name: 6 Microphone (IDT High Definition
    Name: 7 Stereo Mix (IDT High Definition
    Name: 8 Port Speakers and Headphones (IDT Hi
    Name: 9 Port SPDIF (Digital Out via HP Dock)
    Name: 10 Port Integrated Microphone Array (ID
    Name: 11 Port Microphone (IDT High Definition
    Name: 12 Port Stereo Mix (IDT High Definition
    Name: 13 Port Independent Headphones (IDT Hi
    
    4

    1 回答 1

    3

    此代码可能会对您有所帮助。请注意,这取自此链接:音频视频。我发现使用谷歌搜索,我只是在这里发布代码以防链接变得过时。

    导入 javax.media.*;
    导入 javax.media.format.*;
    导入 javax.media.protocol.*;
    导入 java.util.*;
    
    /************************************************* ******************************
     * 一个简单的应用程序,允许用户通过设备捕获音频或视频
     * 连接到电脑。通过命令行参数,用户指定是否
     * 音频(-a)或视频(-v)捕获,捕获的持续时间(-d)在
     * 秒,以及将媒体写入的文件 (-f)。
     *
     * 如果它提供控制,应用程序将更加有用和通用
     * 捕获的音频和视频的格式以及内容类型
     * 的输出。
     *
     * 该类搜索支持特定默认值的捕获设备
     * 轨道格式:音频为线性,视频为 Cinepak。作为后备二
     * 设备名称被硬编码到应用程序中,作为如何
     * 当设备名称已知时获取 DeviceInfo。用户可以强制
     * 应用程序通过使用 -k(已知设备)标志来使用这些名称。
     *
     * 该类是静态的,但使用了较早的 Location2Location 示例
     * 执行所有 Processor 和 DataSink 相关的工作。因此应用
     * 主要涉及 CaptureDevice 相关操作。
     *
     * @作者迈克尔(斯派克)巴洛
     ****************************************************** ******************************/
    公共类 SimpleRecorder {
    
      ///////////////////////////////////////// ///////////
      // 音频和视频捕获设备的名称
      // 作者的系统。这些将因系统而异,但
      // 仅用作后备。
      ///////////////////////////////////////// ///////////
      私有静态最终字符串 AUDIO_DEVICE_NAME = "DirectSoundCapture";
    
      private static final String VIDEO_DEVICE_NAME = "vfw:Microsoft WDM Image Capture:0";
    
      ///////////////////////////////////////// /////////
      // 将输出写入的文件的默认名称 for
      // 用户不提供它们的情况。
      ///////////////////////////////////////// ////////
      私有静态最终字符串 DEFAULT_AUDIO_NAME = "file://./captured.wav";
    
      私有静态最终字符串 DEFAULT_VIDEO_NAME = "file://./captured.avi";
    
      ////////////////////////////////////
      // 用户请求的捕获类型。
      ///////////////////////////////////
      私有静态最终字符串音频=“音频”;
    
      私有静态最终字符串 VIDEO = "视频";
    
      private static final String BOTH = "音频和视频";
    
      ///////////////////////////////////////// /////////////////
      // 特定应用程序唯一的音频和视频格式
      // 支持。更好的程序将允许用户选择格式
      // 但会增长到超过小的示例大小。
      ///////////////////////////////////////// /////////////////
      私有静态最终格式 AUDIO_FORMAT = new AudioFormat(
          音频格式.LINEAR);
    
      私有静态最终格式 VIDEO_FORMAT = new VideoFormat(
          视频格式.CINEPAK);
    
      公共静态无效主要(字符串[]参数){
    
        ///////////////////////////////////////// ////
        // 处理对象的处理和下沉
        // 从设备捕获的数据。
        ///////////////////////////////////////// ////
        Location2位置捕获;
    
        ////////////////////////////////
        // 音频和视频捕获设备。
        ///////////////////////////////
        CaptureDeviceInfo audioDevice = null;
        CaptureDeviceInfo videoDevice = null;
    
        ///////////////////////////////////////// ///////////
        // 捕获设备的“位置”加上名称和位置
        // 目的地。
        ///////////////////////////////////////// ///////////
        MediaLocator captureLocation = null;
        MediaLocator 目的地位置;
        字符串目的地名称=空;
    
        ///////////////////////////////////////// //////////
        // 处理器(在 Location2Location 中)必须匹配的格式。
        ///////////////////////////////////////// //////////
        格式 [] 格式 = 新格式 [1];
    
        ///////////////////////////////////////
        // 音频或视频捕获的内容类型。
        //////////////////////////////////////
        ContentDescriptor audioContainer = new ContentDescriptor(
            文件类型描述符.WAVE);
        ContentDescriptor videoContainer = new ContentDescriptor(
            文件类型描述符.MSVIDEO);
        ContentDescriptor 容器 = null;
    
        ///////////////////////////////////////// /////////////////
        // 记录的持续时间(以秒为单位)和之后等待的时间
        ///////////////////////////////////////// ////////////////
        双倍持续时间 = 10;
        诠释等待= 0;
    
        ///////////////////////
        // 音频或视频捕获?
        ///////////////////////
        选择的字符串 = 音频;
    
        ///////////////////////////////////////// //////
        // 支持相关格式的所有设备。
        // 一种“确保”程序在不同环境下工作的方法
        // 具有不同捕获设备的机器。
        ///////////////////////////////////////// //////
        矢量设备;
    
        ///////////////////////////////////////// ////////
        // 是否搜索支持的采集设备
        // 格式化或使用名字已经存在的设备
        // 应用程序已知。
        ///////////////////////////////////////// ////////
        boolean useKnownDevices = false;
    
        ///////////////////////////////////////// ///////
        // 处理有关音频或视频的命令行选项,
        // 持续时间和要保存到的文件。
        ///////////////////////////////////////// ///////
        for (int i = 0; i 0 && !useKnownDevices) {
            audioDevice = (CaptureDeviceInfo) devices.elementAt(0);
          } 别的
            audioDevice = CaptureDeviceManager.getDevice(AUDIO_DEVICE_NAME);
          if (audioDevice == null) {
            System.out.println("找不到合适的音频设备。正在退出");
            System.exit(1);
          }
          captureLocation = audioDevice.getLocator();
          格式[0] = 音频格式;
          if (destinationName == null)
            目的地名称 = DEFAULT_AUDIO_NAME;
          容器 = 音频容器;
        }
        ///////////////////////////////////////// ///////////////
        // 执行视频捕获设置。包括寻找合适的
        // 设备,获取其 MediaLocator 并设置内容
        // 类型。
        ///////////////////////////////////////// //////////////
        else if (selected.equals(VIDEO)) {
          设备 = CaptureDeviceManager.getDeviceList(VIDEO_FORMAT);
          if (devices.size() > 0 && !useKnownDevices)
            videoDevice = (CaptureDeviceInfo) devices.elementAt(0);
          别的
            videoDevice = CaptureDeviceManager.getDevice(VIDEO_DEVICE_NAME);
          if (videoDevice == null) {
            System.out.println("找不到合适的视频设备。正在退出");
            System.exit(1);
          }
          captureLocation = videoDevice.getLocator();
          格式[0] = VIDEO_FORMAT;
          if (destinationName == null)
            目的地名称 = DEFAULT_VIDEO_NAME;
          容器 = 视频容器;
        } else if (selected.equals(BOTH)) {
          捕获位置=空;
          格式=新格式[2];
          格式[0] = 音频格式;
          格式[1] = VIDEO_FORMAT;
          容器 = 视频容器;
          if (destinationName == null)
            目的地名称 = DEFAULT_VIDEO_NAME;
        }
    
        ///////////////////////////////////////// /////////////////
        // 执行所有必要的处理器和数据接收器准备通过
        // Location2Location 类。
        ///////////////////////////////////////// /////////////////
        目的地位置 = 新媒体定位器(目的地名称);
        System.out.println("正在配置捕获。请稍候。");
        捕获 = 新 Location2Location(捕获位置,目标位置,
            格式,容器,1.0);
    
        ///////////////////////////////////////// ////////////////////////
        // 开始录制并告诉用户。指定长度
        // 记录。然后等待最多 4 倍的持续时间
        // 记录
        //(可能需要更长的时间来接收/写入数据,所以应该稍等一下)。
        ///////////////////////////////////////// ////////////////////////
        System.out.println("开始录制" + 持续时间 + " 秒数 "
            + 选定 + " ...");
        capture.setStopTime(new Time(duration));
        如果(等待 == 0)
          waitFor = (int) (4000 * 持续时间);
        别的
          等待 *= 1000;
        int 等待 = capture.transfer(waitFor);
    
        ///////////////////////////////////////// ///////
        // 报告录制成功(或其他)。
        ///////////////////////////////////////// ///////
        int state = capture.getState();
        如果(状态 == Location2Location.FINISHED)
          System.out.println(选中
              +“大约捕获成功”
              + ((int) ((等待 + 500) / 1000))
              + " 秒。数据写入 " + destinationName);
        否则如果(状态 == Location2Location.FAILED)
          System.out.println(选中
              +“大约在大约之后捕获失败”
              + ((int) ((等待 + 500) / 1000)) + "秒");
        别的 {
          System.out.println(选中
              +“大约在大约之后捕获仍在进行中”
              + ((int) ((等待 + 500) / 1000)) + "秒");
          System.out.println("进程可能失败");
        }
    
        System.exit(0);
      }
    }
    
    
    于 2012-12-20T07:24:27.383 回答