JMF实现声音录制

本系列是多媒体技术课程的实验的整理。

实验一:声音录制

基本要求:使用windows api或Java media Framework(JMF)或javax.media.sound实现类似于windows录音机一类的小工具

bonus: 实现压缩录音

硬件: 麦克风

软件: 无/JMF/JDK

实验指导只给出实现的一种方法,仅供参考。

在实现时用到了JMF,需要先去下载JMF的相关jar包。最终实现的效果是录制声音,并保存为本地的一个.wav文件。关键代码如下所示。

package 声音录制;

import java.io.IOException;
import java.util.Vector;
 
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.DataSink;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoDataSinkException;
import javax.media.NoProcessorException;
import javax.media.Processor;
import javax.media.control.StreamWriterControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;
 
public class CaptureAudio {
	
		public CaptureAudio(){
			
		}
       
       public static void run() {
           CaptureDeviceInfo di = null;
           Processor p = null;
           StateHelper sh = null;//实现处理器(processor)的状态控制管理
           
           Vector deviceList = CaptureDeviceManager.getDeviceList(new AudioFormat(AudioFormat.LINEAR, 44100, 16, 2));
           
           if (deviceList.size() > 0){//得到此设备的CaptureDeviceInfo实例。
        	   di = (CaptureDeviceInfo)deviceList.firstElement();
           }
           else{
               // 找不到满足(linear, 44100Hz, 16 bit,stereo audio.)音频设备,退出。
        	   System.out.println("找不到音频设备");
               System.exit(-1);
           }
           
           try {//获得MediaLocator,并由此创建一个Processor。
               p = Manager.createProcessor(di.getLocator());
               sh = new StateHelper(p);
           } catch (IOException e) {
               e.printStackTrace();
               System.exit(-1);
           } catch (NoProcessorException e) {
               e.printStackTrace();
               System.exit(-1);
           }
                      
           if (!sh.configure(10000)){
               System.out.println("configure wrong!");
               System.exit(-1);
           }
           
           //定义待存储该媒体的内容类型(content type)。
           p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.WAVE));
           // realize the processor.
           if (!sh.realize(10000)){
              System.out.println("realize wrong!");
              System.exit(-1);
           }
           
           DataSource source = p.getDataOutput();
           //定义存储该媒体的文件。
           MediaLocator dest = new MediaLocator(new java.lang.String(
                     "file:///F:/Recorder/sound.wav"));
           //创建一个数据池
           DataSink filewriter = null;
           try {
               filewriter = Manager.createDataSink(source, dest);
               filewriter.open();
           } catch (NoDataSinkException e) {
               e.printStackTrace();
               System.exit(-1);
           } catch (IOException e) {
               e.printStackTrace();
               System.exit(-1);
           } catch (SecurityException e) {
               e.printStackTrace();
               System.exit(-1);
           }
           
           StreamWriterControl swc = (StreamWriterControl)p.getControl("javax.media.control.StreamWriterControl");
           
           if (swc != null)
              swc.setStreamSizeLimit(5000000);//录音最大文件大小
           try {
                filewriter.start();
           } catch (IOException e) {
                e.printStackTrace();
                System.exit(-1);
           }
           sh.playToEndOfMedia(10000);//录音时间设置为10秒
           sh.close();
           
           filewriter.close();
       }
}
package 声音录制;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Recorder extends JFrame{
	
	private static final int WIDE = 350;
	private static final int HEIGHT = 230;
	
	public Recorder(){
		
		this.setSize(WIDE, HEIGHT);
		
		RecorderPanel panel = new RecorderPanel();
		this.add(panel);
				
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocation(100, 100);
		this.setTitle("多媒体实验1——声音录制");
		
	}

	public static void main(String[] args) {
		Recorder frame = new Recorder();
	}

}
package 声音录制;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.io.IOException;
import java.util.Vector;
import javax.media.*;
import javax.media.control.StreamWriterControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;

public class RecorderPanel extends JPanel{
	
	JButton startbutton = new JButton("start");
	JButton stopbutton = new JButton("close");
	JLabel label = new JLabel("10秒钟声音录制,点击“start”开始",JLabel.CENTER);
	JLabel label2 = new JLabel("录音文件将保存到F盘下的Recorder文件夹中",JLabel.CENTER);
	
	public RecorderPanel(){
		
		this.setLayout(new BorderLayout());
		
		JPanel buttonpanel = new JPanel();
		JPanel labelpanel = new JPanel();
				
		buttonpanel.add(startbutton);
		buttonpanel.add(stopbutton);
		this.add(buttonpanel, BorderLayout.NORTH);
		labelpanel.setLayout(new BorderLayout());
		labelpanel.add(label,BorderLayout.CENTER);
		labelpanel.add(label2,BorderLayout.SOUTH);
		this.add(labelpanel);
		
		startbutton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				//label.setText("正在录音");
				CaptureAudio player = new CaptureAudio();				
				player.run();
				label.setText("声音录制成功");
				label2.setText("可在F盘下的Recorder文件夹中查看");
			}			
		});		
		
		stopbutton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}			
		});	
	}
		
}
package 声音录制;

import javax.media.*;

public class StateHelper implements javax.media.ControllerListener {
    Player player = null;
    boolean configured = false;
    boolean realized = false;
    boolean prefetched = false;
    boolean eom = false;//End of media.
    boolean failed = false;
    boolean closed = false;
    public StateHelper(Player p) {
        player = p;
        p.addControllerListener(this);
    }
    
    public boolean configure(int timeOutMillis) {
        long startTime = System.currentTimeMillis();
        synchronized (this) {
            if (player instanceof Processor)
              ((Processor)player).configure();
            else
              return false;
            while (!configured && !failed) {
              try {
                  wait(timeOutMillis);
              } catch (InterruptedException ie) {
              }
              if (System.currentTimeMillis() - startTime > timeOutMillis)
                  break;
            }
        }
        return configured;
    }
    /**
     * 判断player是否已经实现
     */
    public boolean realize(int timeOutMillis) {
        long startTime = System.currentTimeMillis();
        synchronized (this) {
            player.realize();
            while (!realized && !failed) {
              try {
                  wait(timeOutMillis);
              } catch (InterruptedException ie) {
              }
              if (System.currentTimeMillis() - startTime > timeOutMillis)
                  break;
            }
        }
        return realized;
    }
    
    public boolean prefetch(int timeOutMillis) {
        long startTime = System.currentTimeMillis();
        synchronized (this) {
            player.prefetch();
            while (!prefetched && !failed) {
              try {
                  wait(timeOutMillis);
              } catch (InterruptedException ie) {
              }
              if (System.currentTimeMillis() - startTime > timeOutMillis)
                  break;
            }
        }
        return prefetched && !failed;
    }
    
    public boolean playToEndOfMedia(int timeOutMillis) {
        long startTime = System.currentTimeMillis();
        eom = false;
        synchronized (this) {
            player.start();
            while (!eom && !failed) {
              try {
                  wait(timeOutMillis);
              } catch (InterruptedException ie) {
              }
              if (System.currentTimeMillis() - startTime > timeOutMillis)
                  break;
            }
        }
        return eom && !failed;
    }
    public void close() {
        synchronized (this) {
            player.close();
            while (!closed) {
              try {
                  wait(100);
              } catch (InterruptedException ie) {
              }
            }
        }
        player.removeControllerListener(this);
    }
    public synchronized void controllerUpdate(ControllerEvent ce) {
        if (ce instanceof RealizeCompleteEvent) {
            realized = true;
        } else if (ce instanceof ConfigureCompleteEvent) {
            configured = true;
        } else if (ce instanceof PrefetchCompleteEvent) {
            prefetched = true;
        } else if (ce instanceof EndOfMediaEvent) {
            eom = true;
        } else if (ce instanceof ControllerErrorEvent) {
            failed = true;
        } else if (ce instanceof ControllerClosedEvent) {
            closed = true;
        } else {
            return;
        }
        notifyAll();
    }
}
最终实现实现效果如下所示








  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值