DataSink 经常被用于从DataSource 读取媒体数据并传送媒体数据到一些输出目的地JMF提供一默认的DataSink,可以被用于写数据到文件,其它类型的DataSink类能写数据到网络或另外的目的地。注意,Plaryers、 Processors 和DataSinks 都属于MediaHandlers, 它们都是从DataSource读取数据。如果想保存捕获的媒体数据到文件,必须用Processor替代Player,然后用DataSink从Processor对象输出的DataSource中读取数据并输出数据到文件。
捕获视频及声音
在使用 JMF 之前首先需正确设置开发及运行环境关于如何设置运行Java 及JMF 环境的文章已有很多这里就不详述了为了使用视频和音频设备捕获媒体数据需要以下几个步骤[1]
(1)通过调用方法CaptureDeviceManage()定位想用的捕获设备
(2)对定位的设备获得相应的CaptureDeviceInfo对象
(3)通过CaptureDeviceInfo 对象获得MediaLocator 并用之创建DataSource
(4)用DataSource 创建Player 或Processor
(5)Start 这个Player 或Processor 开始捕获媒体数据相应的代码。
示例如下[1,2] 注意若单独考虑捕获音视频数据到屏幕直接用SUN提供的示例代码即可,但为使录制电影文件与屏幕显示不冲突这里用到了数据克隆。
//定位捕获设备
MediaLocator[] locatorVA = new MediaLocator[2];
locatorVA[0] = newMediaLocator("javasound://0");
locatorVA[1] = new MediaLocator("vfw://0");
//获得MediaLocator 并用之创建DataSource
DataSource[] dsc = new DataSource[2];
dsc[0] =Manager.createDataSource(locatorVA[0]);
dsc[1] =Manager.createDataSource(locatorVA[1]);
//将视频与音频合并
DataSourcemainSource=Manager.createMergingDataSource(dsc);
//为了能让几个Processor 访问同一数据源需将之转换成可克
//隆的数据源
mainSource=Manager.createCloneableDataSource(mainSource);
//用克隆的数据源创建Processor
DataSource camSource =(SourceCloneable)mainSource.
createClone();
Processor processor =Manager.createProcessor(camSource);
// 用类camStateHelper 可帮助控制Processor 的媒体事件
camStateHelper playhelper =new camStateHelper(processor);
//Configure, Realize 然后开始我们的Processor
playhelper.configure(10000);
// Processor 的内容描述符必须设置成空为防止Processor 的数
//据源来自输出的原始数据
processor.setContentDescriptor(null);
playhelper.realize(10000);
processor.start();
//用Processor 的可视组件将电影显示到屏幕上
processor.getVisualComponent().setBackground(Color.white);
centerPanel.add(processor.getVisualComponent(),
BorderLayout.CENTER);
保存一段录像到电影文件
可用 DataSink 从Processor 对象的输出数据源中读取数据并将之输出到文件中具体步骤如下
(1)创建一个MediaLocator 对象用于指定想保存的文件位置
URL movieUrl = file.toURL();
MediaLocator dest = new MediaLocator(movieUrl);
(2)再克隆一份数据源并用之又创建一个Processor
DataSource recordCamSource = dataSource.cloneCamSource();
Processor recordProcessor = Manager.createProcessor
(recordCamSource);
camStateHelper playhelper = new camStateHelper
(recordProcessor);
(3)对该Processor 调用configure
Playhelper.configure(10000);
(4)对每个轨道调用方法getTrackControls和setFormat音视频的轨道序号应与捕获代码中的音视频顺序一致
VideoFormat vfmt = new VideoFormat(VideoFormat.JPEG);
AudioFormat afmt = newAudioFormat(AudioFormat.LINEAR);
(recordProcessor.getTrackControls())[0].setFormat(afmt);
(recordProcessor.getTrackControls())[0].setEnabled(true);
(recordProcessor.getTrackControls())[1].setFormat(vfmt);
(recordProcessor.getTrackControls())[1].setEnabled(true);
(5)用Processor 的输出数据源创建DataSink 并将数据写到指定格式的文件中
recordProcessor.setContentDescriptor(new
FileTypeDescriptor(FileTypeDescriptor.QUICKTIME));
Control control = recordProcessor.getControl("javax.media.
control.FrameRateControl");
playhelper.realize(10000);
DataSink dataSink =Manager.createDataSink(recordProcessor.
getDataOutput(), dest);
recordProcessor.start();
dataSink.open(); //打开文件
dataSink.start();
(6)调用stop()和close()方法结束数据的捕获
recordProcessor.stop();
recordProcessor.close();
dataSink.stop();
dataSink.close();
请注意虽然已经停止了用于录制电影文件的Processor但显示在屏幕上的视频并未受到任何影响仍然显示原因是停止的只是新克隆的数据源