利用JMF开发视频应用代码参考
2005年6月14日,0:26:00 | 马生
获取摄像头视频数据和麦克风音频数据
基本步骤是首先获取视频、音频捕获设备的信息,然后再根据取得的设备信息确定设备的位置。找到设备的位置以后,调用Manager的CreatePlayer方法创建Player,当Player开始播放的时候,就开始了捕获的过程。
有多种方法获得捕获设备信息,可以通过查询指定的格式,也可以查询特定的设备名字。
5.1.1获取音频数据
程序代码片断说明:
获取捕获设备
Vector deviceList = CaptureDeviceManager.getDeviceList(new
AudioFormat("linear", 44100, 16, 2)); //返回能支持这种格式的设备列表
if (deviceList.size() > 0)
di = (CaptureDeviceInfo)deviceList.firstElement();
//di 是CaptureDeviceInfo对象,使用第一个支持这种格式采集的设备
else
System.exit(-1);
建立MediaLocator
MediaLocator=di.getLocator()
创建Player
try{
Player p = Manager.createPlayer(di.getLocator());
}
catch (IOException e) { }
catch (NoPlayerException e) {}
5.1.2捕获视频数据
Vector list=CaptureDeviceManager.getDeviceList(null);
//先把所有的捕获设备调出来
devinfo=(CaptureDeviceInfo)list.elementAt(i);
name=devinfo.getName();
if(name.startsWith("vfw:"))
webCamDeviceInfo=devinfo;
//所有的视频捕获设备的名字都是以vfw开头的,所以取得捕获设备列表中以vfw 开头的设备名字就是视频捕获设备。
medialocator=webCamDeviceInfo.getLocator();
//获取设备的medialocator地址
try{
Player p = Manager.createPlayer(medialocator);
}
catch (IOException e) { }
catch (NoPlayerException e) {}
//创建Player,当Play开始的时候,就开始了视频捕获的过程。
5.2 保存摄像头数据为视频文件
首先是找到捕获设备,然后取的捕获设备的位置信息。如果要保存所采集的数据,就要创建一个处理器。然后将处理器的输出作为数据池的输入。当启动数据池的时候,就可以把捕获的数据保存成文件了。以部分代码为例说明如下过程。
获取捕获设备部分参见上一部分
//创建Processor
mProcessor=Manager.createProcessor(MediaLocator)
//设置Processor,输出类型为AVI格式
mProcessor.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.AVI));
//取得Processor的输出
DataSource source=p.getDataOutput();
//建立一个保存文件位置的MediaLocator
MediaLocator dest=new MediaLocator(“file://test.avi”)
//建立一个DataSink
DataSink filewriter=null;
Try {
Filewriter=Manager.createDataSink(source,dest)
Filewriter.open()
}
//设置Processor控制生成文件的大小,只要调用Processor的StreamWriterControl
StreamWriterControl swc = (StreamWriterControl) processor.getControl (“javax.media.control.StreamWriterControl”);
//设置生成文件大小最大2M
If(swc!=null)
Swc.setStreamSizeLimit(2000000)
//设置完毕,可以启动Processor和DataSink来保存捕获数据了。
try {
filewriter.start();
}
catch (IOException e)
{
System.exit(-1);
}
5.3 捕获音频、视频数据为QuickTime格式的文件
使用处理器模型来捕获实时的视频、音频数据并且将数据轨道进行编码、混合,最后保存为QuickTime 格式的文件。
首先构建一个处理器模型,设定好特定的数据轨道和输出内容格式。然后使用这个处理器模型来创建一个处理器。处理器会自动连接到符合文件格式要求的捕获设备。具体实现参考以下代码:
//设定要输出的音频格式和视频格式
Format formats[] = new Format[2];
formats[0] = new AudioFormat(AudioFormat.IMA4);
formats[1] = new VideoFormat(VideoFormat.CINEPAK);
//设定要输出的文件类型为QuickTime格式
FileTypeDescriptor outputType =
new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME);
//创建ProcessorModel,参数为数据轨道输出格式和文件输出类型
ProcessorModel mProcessorModel=new ProcessorModel(formats,outputType);
//由ProcessorModel对象创建Processor对象
try {
mProcessor=Manager.createRealizedProcessor(mProcessorModel)
}
//获取Processor的输出
DataSource source=mProcessor.getDataOutput()
//建立一个记录保存文件的MediaLocator
MediaLocator dest=new MediaLocator(“file://test.mov”)
//创建数据池
DataSink filewriter=null
Try {
Filewriter=Manager.createDataSink(source,dest);
Filewriter.open();
}
catch(…)
//开始保存数据文件,启动处理器
try {
filewriter.start();
}
catch(…)
p.start();
//当结束捕获视频时,停止处理器,并关掉它
//当数据池接到EndOfStream事件时,停止保存文件。
5.4 发送实时媒体数据
如果需要将媒体数据发送到网络,首先需要用Processor生成RTP编码的数据源,然后创建SessionManager或者DataSink来控制传输过程。
下面以实例来讲解从摄像头捕获视频,并且在网上传输的过程。
首先获取视频采集设备具体请参考5.1.2,取得了CaptureDeviceInfo对象为di
第二步创建Processor
Processor p=Manager.createProcessor(di.getLocator());
第三步设置Processor,使它能够生成RTP格式的编码
processor.configure()
//等待,直到processor的状态变成configured,设置输出格式为RAW_RTP
processor.setContentDescriptor(
new ContentDescriptor(ContentDescriptor.RAW_RTP));
//列出所有的和数据轨道相关的控制器
TrackControl track[]=processor.getTrackControls();
boolean encodingOk = false;
//遍历这些控制器,找到可以控制输出格式的控制器
for (int i = 0; i < track.length; i++) {
if (!encodingOk && track[i] instanceof FormatControl) {
//找到了数据轨道的格式控制器之后,设置输出格式,输出格式输出为VideoFormat.JPEG_RTP>。
VideoFormat jpegFormat = new VideoFormat(VideoFormat.JPEG_RTP,
new Dimension(w, h),
Format.NOT_SPECIFIED,
Format.byteArray,
frameRate);
tracks[i].setFormat(jpegFormat);
//这时,准备工作已经做好,可以调用Processor的realize方法
processor.realize()
//当Processor进出realized状态以后,可以取得Processor的输出作为数据源
processor.realize()
DataSource ds=processor.getDataOutput();
//可以把这个数据源作为参数传递给manager,通过manager创建一个RTP的数据池。先设置一个发送数据流的多播目的网址
String url=“rtp://127.0.0.1:49150/audio/1”
MediaLocator mDest=new MediaLocator(url)
//确定了数据源和发送地址,可以建立数据池DataSink了,建立成功后调用open()和start()方法,就可以在网上以多播方式发送捕获的内容了。
DataSink d=Manager.createDataSink(ds,m)
d.open()
d.start()
5.5 接收实时视频数据
接收网上传输的数据流时,首先要构建一个MediaLocator来描述RTP 进程,Manager为进程中的第一个数据流创建播放器,当从进程中检测到数据时,Player会发出RealizeComplete事件。
通过监听RealizeComplete事件,你可以确定是否有数据到了,还可以确定Player是否准备好播放数据了。当Player发出这个事件时,就可以获取播放器的可视面板和控制面板了。
参考代码片断如下
//RTP 数据源的地址
String url= "rtp://224.144.251.104:49150/audio/1";
//创建MediaLocator
MediaLocator mrl=new MediaLocator(url);
if (mrl == null) {
System.err.println("Can't build MRL for RTP");
return false;
}
//根据MediaLocator创建Player
try {
player = Manager.createPlayer(mrl);
} catch (NoPlayerException e) {
System.err.println("Error:" + e);
return false;
} catch (MalformedURLException e) {
System.err.println("Error:" + e);
return false;
} catch (IOException e) {
System.err.println("Error:" + e);
return false;
}
//添加监听器,以便监听RealizeComplete事件
if (player != null) {
if (this.player == null) {
this.player = player;
player.addControllerListener(this);
player.realize();
}
}
以上的方式只能接收进程中的第一个数据流。为了播放RTP进程中的全部数据流可以按照以下方式。就为每个数据流创建一个Player。当创建一个新的数据流后,SessionManager会发出一个NewReceiveStream Event。注册了ReceiveStream Listener 接收数据流监听器,就会收到这些事件。就可以为每一个新的接收数据流创建Player。从接收数据流中获取DataSource,并作为参数传递给Manager来创建Player。
1、 建立RTP session
a. 创建一个SessionManager
b. 调用SessionManager的addReceiveStreamListener方法注册一个监听器
c. 调用SessionManager的initSession方法初始化SessionManger
d. 调用startSession方法启动SessionManager
2、当新的数据流检测到的时候,可以在ReceiveStreamListener的update方法中获得发现新数据流事件的通知。
3、数据流通知之后,调用getReceiveStream方法获取新的数据流
4、 调用新的数据流的getDataSource方法获取数据流的RTP数据源。这个数据源是RTP特有格式的PushBufferDataSource。
把数据源对象
没有合适的资源?快使用搜索试试~ 我知道了~
JMF的相关资料和实例程序
共47个文件
java:30个
txt:8个
mht:4个
5星 · 超过95%的资源 需积分: 10 415 下载量 151 浏览量
2008-07-19
15:58:42
上传
评论 3
收藏 2.08MB RAR 举报
温馨提示
在sun的解决方案中下载的大量关于JMF的使用的源代码.可以给那些想学习和研究JAVA多媒体的朋友提供解决方案.
资源推荐
资源详情
资源评论
收起资源包目录
JMF资料.rar (47个子文件)
JMF资料
利用JMF进行多媒体编程.mht 170KB
solutions.mht 98KB
新建文本文档 (2).txt 11KB
AVReceive2.java 13KB
minime.jar 23KB
Transcode.java 19KB
边缘人行走五行三界 - 博1客_CN[blogger_cn-blog-中国-china].mht 206KB
新建文件夹
Config.java 4KB
AVReceiver.java 13KB
Rx.java 14KB
Target.java 2KB
RTCPViewer.java 7KB
LiveStream.java 7KB
AudioBufferControl.java 7KB
Cut.java 24KB
新建文件夹 (5)
Config.java 4KB
Tx.java 17KB
AVTransmitter.java 15KB
DataSourceReader.java 15KB
RTCPViewer.java 7KB
新建文件夹 (2)
PcmPacketizer.java 7KB
PcmDepacketizer.java 6KB
新建文本文档.txt 512B
AVCustomTrans.java 16KB
AVCustomRecv.java 14KB
Merge.java 8KB
RTPExport.java 12KB
新建文本文档.txt 8KB
新建文本文档 (4).txt 41KB
Seek.java 7KB
边缘人行走五行三界 - 博客_CN[blogger_cn-blog-中国-china].mht 128KB
新建文件夹 (3)
RTPSocketAdapter.java 9KB
AVReceive3.java 12KB
新建文本文档.txt 487B
AVTransmit3.java 13KB
notepad.exe 1.57MB
新建文本文档 (3).txt 9KB
新建文件夹 (4)
AVTransmit2.java 14KB
新建文本文档.txt 1KB
VideoTransmit.java 11KB
Split.java 16KB
新建文本文档 (5).txt 279B
bluescreen2.mov 1.35MB
Concat.java 26KB
jamp.zip 15KB
monitor.zip 19KB
DataSource.java 4KB
共 47 条
- 1
资源评论
- yuiyinf2011-09-08代码挺好的,就是建议给文件整理改名一下
- xyale2011-10-19谢谢了,内容很丰富,例子很多,还有教程,真不错
- EnjoyL22012-04-25这个真的很不错,又不需要积分,而且里面有几个文档还是很实用的。。美中不足就是有点乱。。。
shmilycharlene
- 粉丝: 15
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功