相關文章:JMF捕獲音頻和視頻(二)
1.捕獲媒體數據的步驟:
l 查詢CaptureDeviceManager,來定位你需要使用的媒體采集設備。
l 得到此設備的CaptureDeviceInfo實例。
l 從此CaptureDeviceInfo實例獲得一個MediaLocator,並通過它來創建一個DataSource。
l 用此DataSource創建一個Player或Processor。
l 啟動此Player或Processor開始捕獲媒體數據。
2.CaptureDeviceManager、CaptureDeviceInfo、MediaLocator
在JMF中,CaptureDeviceManager也是一個manager類,它提供給了一個列表,這個列表顯示當前系統可以被使用的設備名稱。同時CaptureDeviceManager可以通過查詢的方法對設備進行定位並返回設備的配置信息對象CaptureDeviceInfo,它也可以通過注冊的方法向列表加入一個新的設備信息,以便為JMF使用。
設備可通過CaptureDeviceManager的getDevice()方法直接獲得設備控制權,設備的控制權一旦得到,就可以以此設備作為一個MediaLocator,可以通過CaptureDeviceInfo的getLocator()方法得到。
3.JMF識別的音頻采集設備
4.一個實例實現音頻捕獲
實例有兩個文件組成。CaptureAudio.java實現
①查詢、獲得音頻采集設備。
②捕獲音頻。
③將音頻保存到本地文件foo.wav。
StateHelper實現處理器(processor)的狀態控制管理。以下為流程圖:
5.音頻捕獲代碼實例:
CaptureAudio.java
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 {
/**
* Writing captured audio to a file with a DataSink.
*/
public static void main(String[] args) {
CaptureDeviceInfo di = null;
Processor p = null;
StateHelper sh = null;
//查詢CaptureDeviceManager,來定位你需要使用的媒體采集設備。
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.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);
}
// Configure the processor
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);
}
// get the output of the processor
DataSource source = p.getDataOutput();
//定義存儲該媒體的文件。
MediaLocator dest = new MediaLocator(new java.lang.String(
"file:///D:/Dvp/workspace/JavaSoundMedia/foo.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);
}
// if the Processor implements StreamWriterControl, we can
// call setStreamSizeLimit
// to set a limit on the size of the file that is written.
StreamWriterControl swc = (StreamWriterControl)
p.getControl("javax.media.control.StreamWriterControl");
//set limit to 5MB
if (swc != null)
swc.setStreamSizeLimit(5000000);
// now start the filewriter and processor
try {
filewriter.start();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
// Capture for 5 seconds
sh.playToEndOfMedia(5000);
sh.close();
// Wait for an EndOfStream from the DataSink and close it...
filewriter.close();
}
}
StateHelper.java
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);
}
/**
* To judge whether the processor is configured.
* Configure the processor in the given time which is limited
* by the timeOutMillis.Once a Processor is Configured, you
* can set its output format and TrackControl options.
*/
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;
}
/**
* To judge whether the playerr is realized.
*/
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;
}
/**
* To judge whether the player is prefetched.
*/
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;
}
/**
* To judge whether the player has finished.
*/
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();
}
}
本文出自 “子 孑” 博客,請務必保留此出處http://zhangjunhd.blog.51cto.com/113473/25475