📄 voicerecorder.java
字号:
/* * VoiceRecorder.java * * Created on Mar 16, 2004 * */package gov.nist.applet.phone.media.messaging;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Vector;import javax.media.CaptureDeviceInfo;import javax.media.CaptureDeviceManager;import javax.media.ConfigureCompleteEvent;import javax.media.Controller;import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.EndOfMediaEvent;import javax.media.Format;import javax.media.IncompatibleSourceException;import javax.media.Manager;import javax.media.MediaLocator;import javax.media.MediaTimeSetEvent;import javax.media.PrefetchCompleteEvent;import javax.media.Processor;import javax.media.RealizeCompleteEvent;import javax.media.ResourceUnavailableEvent;import javax.media.SizeChangeEvent;import javax.media.StopAtTimeEvent;import javax.media.StopByRequestEvent;import javax.media.control.TrackControl;import javax.media.datasink.DataSinkErrorEvent;import javax.media.datasink.DataSinkEvent;import javax.media.datasink.DataSinkListener;import javax.media.datasink.EndOfStreamEvent;import javax.media.format.AudioFormat;import javax.media.protocol.DataSource;import javax.media.protocol.FileTypeDescriptor;/** * Class allowing one to record some audio in a buffer * Play only MPEG_AUDIO and GSM audio data * With some minor modifications can play RAW data also * * @author Jean Deruelle <jean.deruelle@nist.gov> * * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a> */public class VoiceRecorder implements ControllerListener, DataSinkListener, Runnable{ Processor p; Object waitSync = new Object(); Object waitRecord = new Object(); Object waitBuff = new Object(); boolean stateTransitionOK = true; static boolean monitorOn = false; private MediaLocator audioLocator=null; DataSourceHandler handler =null; Thread recorderThread=null; public static final String STOPPED="Stopped"; public static final String INITIALIZED="Initialized"; public static final String RECORDING="Recording"; private String state=STOPPED; private static VoiceRecorder instance=null; private DataSource ods = null; private VoiceRecorder(){ state=STOPPED; } public static synchronized VoiceRecorder getInstance(){ if(instance==null) instance=new VoiceRecorder(); return instance; } /** * get the devices for the audio capture and print their formats */ public synchronized void initialize() { if(state.equalsIgnoreCase(STOPPED)){ CaptureDeviceInfo audioCDI=null; Vector captureDevices=null; captureDevices= CaptureDeviceManager.getDeviceList(null); System.out.println("- number of capture devices: "+captureDevices.size() ); CaptureDeviceInfo cdi=null; for (int i = 0; i < captureDevices.size(); i++) { cdi = (CaptureDeviceInfo) captureDevices.elementAt(i); Format[] formatArray=cdi.getFormats(); for (int j = 0; j < formatArray.length; j++) { Format format=formatArray[j]; if (format instanceof AudioFormat) { if (audioCDI == null) { audioCDI=cdi; } } } } if(audioCDI!=null) audioLocator=audioCDI.getLocator(); DataSource ds = null; // Create a DataSource given the media locator. try { ds = Manager.createDataSource(audioLocator); } catch (Exception e) { System.err.println("Cannot create DataSource from: " + audioLocator); e.printStackTrace(); } try { p = Manager.createProcessor(ds); } catch (Exception e) { System.err.println("Failed to create a processor from the given DataSource: " + e); e.printStackTrace(); } p.addControllerListener(this); // Put the Processor into configured state. p.configure(); if (!waitForState(Processor.Configured)) { System.err.println("Failed to configure the processor."); } setTrackFormat(); /*ContentDescriptor[] descriptors = p.getSupportedContentDescriptors(); for (int n = 0; n < descriptors.length; n++) { System.out.println("Desc: " + descriptors[n].toString()); }*/ // Get the raw output from the processor. //p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW)); //p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.MPEG_AUDIO)); p.realize(); if (!waitForState(Controller.Realized)) { System.err.println("Failed to realize the processor."); } // Get the output DataSource from the processor and // hook it up to the RawDataSourceHandler. ods = p.getDataOutput(); handler = new DataSourceHandler(); try { handler.setSource(ods); } catch (IncompatibleSourceException e) { System.err.println("Cannot handle the output DataSource from the processor: " + ods); //return false; } System.err.println("Start datasource handler "); handler.addDataSinkListener(this); System.err.println("Prefetch the processor "); // Prefetch the processor. p.prefetch(); if (!waitForState(Controller.Prefetched)) { System.err.println("Failed to prefetch the processor."); } state=INITIALIZED; } } /** * Set the format of the tracks * either to MPEG_AUDIO or GSM */ protected void setTrackFormat(){ //Get the tracks from the processor TrackControl[] tracks = p.getTrackControls(); // Do we have atleast one track? if (tracks == null || tracks.length < 1) System.out.println("Couldn't find tracks in processor"); // Set the output content descriptor to GSM // This will limit the supported formats reported from // Track.getSupportedFormats to only valid AVI formats. //p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.MPEG_AUDIO)); p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.GSM)); Format supported[]; Format chosen=null; boolean atLeastOneTrack = false; // Program the tracks. for (int i = 0; i < tracks.length; i++) { Format format = tracks[i].getFormat(); if (tracks[i].isEnabled()) { supported = tracks[i].getSupportedFormats(); /*System.out.println("track : "+ i); for(int j=0;j<supported.length;j++) System.out.println("Supported format : "+supported[j].getEncoding());*/ // We've set the output content to the GSM. if (supported.length > 0) { for(int j=0;j<supported.length;j++){ System.out.println("Supported format : "+supported[j].toString().toLowerCase()); if (supported[j] instanceof AudioFormat) { chosen = supported[j]; } } if(chosen!=null){ tracks[i].setFormat(chosen); System.err.println("Track " + i + " is set to transmit as:"); System.err.println(" " + chosen); atLeastOneTrack = true; } } else tracks[i].setEnabled(false); } else tracks[i].setEnabled(false); } } /** * Given a DataSource, create a processor and hook up the output * DataSource from the processor to a customed DataSink. * @return false if something wrong happened */ protected boolean record() { if(state.equalsIgnoreCase(INITIALIZED)){ try{ handler.start(); } catch(IOException ioe){ ioe.printStackTrace(); } // Start the processor. p.start(); System.err.println("processor started"); state=RECORDING; synchronized(waitRecord){ waitRecord.notifyAll(); } return true; } return true; } /** * Block until file writing is done. */ /*private boolean waitForFileDone(double duration) { synchronized (waitFileSync) { try { while (!bufferingDone) { if(p.getMediaTime().getSeconds() > duration) p.close(); waitFileSync.wait(500); System.err.print("."); } } catch (Exception e) {} } bufferingDone=false; return true; }*/ /** * Block until the processor has transitioned to the given state. * @param state - the state to wait for * @return false if the transition failed. */ protected boolean waitForState(int state) { synchronized (waitSync) { try { while (p.getState() < state && stateTransitionOK) waitSync.wait(); } catch (Exception e) {} } return stateTransitionOK; } protected void waitForRecording() { synchronized (waitRecord) { try { while ( !state.equalsIgnoreCase(RECORDING)) waitRecord.wait(); } catch (Exception e) {} } } /** * Close the voice recording */ public synchronized void close(){ System.out.println("Closing voice recorder"); System.out.println(state); if(p!=null) p.close(); if(handler!=null) handler.close(); instance=null; state=STOPPED; System.out.println(state); } /** * Tells if the voice recorder is cloaed * @return true if it is closed */ public static boolean isClosed(){ if(instance==null) return true; return false; } /** * Stop the voice recording */ public synchronized boolean stop(){ System.out.println(state); if(state.equalsIgnoreCase(STOPPED)){ System.out.println("Cannot stop recording, it didn't start"); return false; } p.stop(); return true; } /** * Start the voice recording */ public synchronized boolean start(){ System.out.println(state); if(state.equalsIgnoreCase(RECORDING)){ System.out.println("Already recording..."); return false; } //initialize(); if(recorderThread==null){ recorderThread=new Thread(this); recorderThread.setName("Voice Recorder Thread"); } boolean succeeded=record(); if(!succeeded){ return false; } recorderThread.start(); return true; } /** * the process of recording the voice */ public void run(){ synchronized (waitBuff) { try { while ( state.equalsIgnoreCase(RECORDING)) waitBuff.wait(); } catch (Exception e) {} } recorderThread=null; } /** * Controller Listener Method. * Allow one to know what happen on the recorder and the voice * @param evt - event received */ public void controllerUpdate(ControllerEvent evt) { //System.out.println("new Event received"+evt.getClass().getName()); if (evt instanceof ConfigureCompleteEvent || evt instanceof RealizeCompleteEvent || evt instanceof PrefetchCompleteEvent) { synchronized (waitSync) { stateTransitionOK = true; waitSync.notifyAll(); } } else if (evt instanceof ResourceUnavailableEvent) { synchronized (waitSync) { stateTransitionOK = false; waitSync.notifyAll(); } } else if (evt instanceof EndOfMediaEvent) { System.err.println("End of Media"); System.err.println("closing handler" ); //try{ handler.close(); /*} catch(IOException ioe){ ioe.printStackTrace(); }*/ state=STOPPED; /*synchronized(waitBuff){ waitBuff.notifyAll(); }*/ } else if (evt instanceof SizeChangeEvent) { } else if (evt instanceof MediaTimeSetEvent) { System.err.println("- mediaTime set: " + ((MediaTimeSetEvent)evt).getMediaTime().getSeconds()); } else if (evt instanceof StopAtTimeEvent) { System.err.println("- stop at time: " + ((StopAtTimeEvent)evt).getMediaTime().getSeconds()); System.err.println("stoping handler" ); try{ handler.stop(); } catch(IOException ioe){ ioe.printStackTrace(); } System.err.println("...done Buffering."); state=INITIALIZED; synchronized(waitBuff){ waitBuff.notifyAll(); } } else if (evt instanceof StopByRequestEvent) { System.err.println("Stop by request"); //Clean up System.err.println("stoping handler" ); try{ handler.stop(); } catch(IOException ioe){ ioe.printStackTrace(); } System.err.println("...done Buffering."); state=INITIALIZED; synchronized(waitBuff){ waitBuff.notifyAll(); } } } /** * Get the recorded voice buffer * @return the voice recorded in an array of bytes */ public byte[] getRecord(){ if(handler==null) return null; return handler.getRecordBuffer(); } /** * DataSink Listener * @param evt - event received */ public void dataSinkUpdate(DataSinkEvent evt) { if (evt instanceof EndOfStreamEvent) { //waitFileSync.notifyAll(); //state=INITIALIZED; System.out.println("End of Stream event received"); synchronized(waitBuff){ waitBuff.notifyAll(); } System.err.println("closing datasink" ); evt.getSourceDataSink().close(); state=STOPPED; /*try{ evt.getSourceDataSink().stop(); } catch(IOException ioe){ ioe.printStackTrace(); }*/ //System.exit(0); } else if (evt instanceof DataSinkErrorEvent) { //synchronized (waitFileSync) { System.out.println("Data sink error event received"); state=STOPPED; synchronized(waitBuff){ waitBuff.notifyAll(); } System.err.println("closing datasink" ); evt.getSourceDataSink().close(); /*try{ evt.getSourceDataSink().stop(); } catch(IOException ioe){ ioe.printStackTrace(); }*/ } } /** * Utility method to write a recorded voice buffer to a file * @param data - the recorded voice */ private static void writeBufferToFile(byte[] data){ File f=new File("F://test.mov"); FileOutputStream fos=null; try{ fos=new FileOutputStream(f); } catch(FileNotFoundException fnfe){ fnfe.printStackTrace(); } try{ fos.write(data); } catch(IOException ioe){ ioe.printStackTrace(); } } /** * Main program * @param args - */ public static void main(String [] args) { VoiceRecorder voiceRecorder = new VoiceRecorder(); VoicePlayer voicePlayer=new VoicePlayer(); //for(int i=0;i<2;i++){ voiceRecorder.start(); try{ Thread.sleep(5000); } catch(InterruptedException ie){ ie.printStackTrace(); } voiceRecorder.stop(); voicePlayer.initialize(voiceRecorder.getRecord()); voicePlayer.play(); try{ Thread.sleep(5000); } catch(InterruptedException ie){ ie.printStackTrace(); } //} writeBufferToFile(voiceRecorder.getRecord()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -