javaKe视频聊天模块实现

上传人:yo****e 文档编号:61269753 上传时间:2022-03-11 格式:DOC 页数:34 大小:1.68MB
收藏 版权申诉 举报 下载
javaKe视频聊天模块实现_第1页
第1页 / 共34页
javaKe视频聊天模块实现_第2页
第2页 / 共34页
javaKe视频聊天模块实现_第3页
第3页 / 共34页
资源描述:

《javaKe视频聊天模块实现》由会员分享,可在线阅读,更多相关《javaKe视频聊天模块实现(34页珍藏版)》请在装配图网上搜索。

1、蓝杰实训www.NetJ只为不凡而来!javaKe视频聊天模块实现目 录javaKe视频聊天模块实现11JMF概述211 JMF简介与安装212 JMF体系结构313 使用JMF播放多媒体示例52JMF使用RTP协议721. 实时传输协议RTP(Real-Time Transport Protocol)7211 RTP工作机制822 实时传输控制协议RTP(Real-Time Transport Control Protocol)8221 RTCP工作机制8222 RTCP数据包823 JMF中使用RTP824 RTP结构9241 Session管理器SessionManager9242 RT

2、P事件RTPEvent9243 与RTP事件相对应的RTCP类型11244 数据传输格式11245 基于JMF的RTP/RTCP传输模型的整体设计1125 JMF升级为FMJ113FMJ视频聊天室的实现1231 视频聊天整体结构分析1232. 视频聊天客户端代码实现1233 视频聊天服务端代码实现244. FMJ新特性分析321JMF概述JMF是Java多媒体框架(Java Media FrameWork)的简称,JMF使你能够编写出功能强大的多媒体程序,却不用关心底层复杂的实现细节。JMF中包含了许多用于处理多媒体的API。SUN通过它向Java中引入处理多媒体的能力,下面是JMF所支持的功

3、能的概述: 可以在Java Applet和应用程序中播放各种媒体文件,例如AU、AVI、MIDI、MPEG、QuickTime和WAV等文件;可以播放从互联网上下载的媒体流;可以利用麦克风和摄像机一类的设备截取音频和视频,并保存成多媒体文件;处理多媒体文件,转换文件格式;向互联网上传音频和视频数据流;在互联网上广播音频和视频数据。11 JMF简介与安装JMF目前的最新版本是2.1,安装JMF需要JDK1.4以上,JMF的下载地址:针对Windows用户,可以下载JMF2.1.1 with Windows Performance Pack。只有安装Windows Performance Pack

4、才支持视频、音频的捕获。当安装成功后,你需要确认一下安装程序正确设定了CLASSPATH和PATH环境变量。在CLASSPATH中需要包含jmf.jar和sound.jar;在PATH中需要包含JMF动态库的路径。安装好后重启电脑,运行JMStudio.exe,会看到如下界面:在菜单栏中选中FileCapture 或者使用快捷键 Ctrl+P,出现下面的界面:点击OK,JMF即会驱动摄像机设备,让摄象机开始工作。12 JMF体系结构为了更好的说明JMF的结构,我们用立体声音响做一个简单的比喻。当你用CD机播放CD唱片的时候,CD唱片想系统提供音乐信号。这些数据是在录音棚中用麦克风和其它类似设备

5、记录下来的。CD播放机将音乐信号传送到音响系统的音响上,我们才能听到好听的音乐。在这个例子中,麦克风就是一个音频截取设备,CD唱片是数据源,而音响则是输出设备。JMF的结构个这个音响系统非常的相似,在后面的讲述中,我们会常遇到下面这些术语,这些术语就是JMF类库中的几个核心类库: 数据源(Data source) 截取设备(Capture Device,包括视频和音频截取设备) 播放器(Player) 处理器(Processor) 数据格式(Format) 管理器(Manager)数据源就像CD中保存了歌曲一样,数据源中包含了媒体数据流。在JMF中,DataSource对象就是数据源,它可以是

6、一个多媒体文件,也可以是从互联网上下载的数据流。对于DataSource对象,一旦你确定了它的位置和类型,对象中就包含了多媒体的位置信息和能够播放该多媒体的软件信息。当创建了DataSource对象后,可以将它放在Player对象中,而Player对象不关心DateSource中多媒体是如何获得的,以及格式是什么。有些时候,我们需要将多少个数据员合并成一个数据源。例如当我们在制作一段录像时,我们需要将音频数据源和视频数据源合并在一起。JMF支持数据的合并,在后面我们会讲解这一点。截取设备截取设备指的是可以截取到音频或视频的硬件,如麦克风、摄象机等,截取到的数据可以放在Player对象中进行处理

7、。播放器在JMF中对应的播放器的接口是Player。Player对象将音频或视频作为数据流输入,然后将数据流输出到音响或屏幕上,就像CD播放机读取CD唱片中的歌曲,然后将信号送到音响上一样。Player对象有多种状态,JMF中定义了JMF的六种状态,在正常情况下Player对象需要经历每个状态,然后才能播放多媒体:状态说明Unrealized在这种状态下,Player对象已经实例化,但是并不知道它需要播放的多媒体的任何信息Realizing当调用realize()方法时,Player对象的状态从Unrealized转变成为Realizing,在这种状态下Player对象正在确定它需要占用哪些资

8、源。Realized在这种状态下,Player对象已经确定它需要哪些资源,并且也知道需要播放的多媒体的类型。Prefetching当调用prefecth()方法时,Player对象的状态变为Prefetching,这时Player对象正在为播放多媒体做一些准备工作,包括加载多媒体数据,获得需要独占的资源等,这个过程被称作预取(Prefetch)。Prefetched完成预取操作后到达该状态。Started当调用start()方法后,Player对象进入该状态并播放多媒体数据。处理器处理器对应的接口是Processor,它是一种播放器。在JMF API中,Processor接口继承了Player

9、接口。Processor对象除了支持Player对象所支持的所有功能,还可以控制对于输入的多媒体数据进行处理和通过数据源向其它的Player对象或Processor对象输出数据。除了在播放器中提到的六种状态,Processor对象还包括两种新的状态,这两种状态是在Unrealized状态之后,在Realizing状态之前:状态说明Configuring调用configure()方法后,Processor对象连接到数据源并获取输入数据的格式信息Configured完成数据连接,获得输入数据的格式信息后,Processor对象就处于Configured状态数据格式数据格式对应的类是Format,F

10、ormat对象中保存了多媒体的格式信息。该对象中本身没有记录多媒体编码的相关信息,但是它保存了编码的名称。Format的子类包括AudioFormat、VideoFormat类,VideoFormat又包括了H261Format、H263Format、IndexCOlorFormat、JPEGFormat、RGBFormat和YUVFormat六个子类,继承关系如下:管理器JMF提供了四种管理器:管理器说明ManagerManager相当于两个类之间的接口。例如你需要播放一个DateSource对象,你可以通过使用Manager对象创建一个Player对象来播放它,使用Manager对象可以创

11、建Player、Processor、DateSource和DateSink对象PackageManager保存JMF类注册信息的管理器类CaptureDeviceManager保存截取设备注册信息的管理器类PlugInManager保存JMF插件注册信息的管理器类13 使用JMF播放多媒体示例下面我们用一个例子来说明使用JMF来播放多媒体,先新建一个项目,在项目中导入JMF的类库文件,类库文件在安装好的JMF中的lib目录下。package java.vedio;import java.io.File;import .URL;import javax.media.Manager;import

12、javax.media.Player;public class VedioPlayer public static void main(String args) String path = E:music光辉岁月.mp3;VedioPlayer vp = new VedioPlayer();vp.playVedio(path);/* * 播放指定音频文件的方法 * * param path:要播放的音频文件的路径 */public void playVedio(String path) File f = new File(path);/ 根据音频文件的路径创建File对象try URL url

13、 = f.toURI().toURL();/ 得到音频文件的URL地址/ 调用管理器创建Player对象的方法Player player = Manager.createRealizedPlayer(url);/ 加载多媒体音频的数据player.prefetch();/ 调用播放的方法player.start(); catch (Exception e) e.printStackTrace();运行这段程序,打开你的耳麦,我们就可以开始听音乐了,呵呵.只有音乐,没有视频,是不是还不过瘾?下面我们在看一个视频的例子,先定义一个类用来放界面和得到Player对象:package java.ved

14、io;import java.io.IOException;import javax.media.NoPlayerException;import javax.media.Player;import javax.swing.JFrame;/* * 视频播放测试 */public class VedioTest extends JFrame private Player player;public static void main(String args) String path = file:/E:/movie/test.avi;VedioTest vt = new VedioTest(pat

15、h);vt.initUI();/* * 在构造器中初始化数据 * param:要初始化的数据源,即视频文件的路径 */public VedioTest(String path) / 确定视频文件的位置javax.media.MediaLocator ml = new javax.media.MediaLocator(path);try /创建一个播放器对象player = javax.media.Manager.createPlayer(ml);/创建一个播放器的控制器监听器对象MyConreollerListener l = new MyConreollerListener(player,

16、this);/给播放器对象注册控制器监听器player.addControllerListener(l);/开始播放player.start(); catch (Exception e) e.printStackTrace();/* * 初始化界面 */public void initUI() this.setTitle(JMF播放视频示例);this.setSize(400, 300);this.setDefaultCloseOperation(3);this.setVisible(true);另外我们还要给Player对象注册一个监听器,用来控制视频的加载、播放,暂停和结束等行为:pack

17、age java.vedio;import java.awt.Component;import javax.media.ControllerEvent;import javax.media.Player;import javax.swing.JFrame;/* * 视频控制器监听器类 */public class MyConreollerListener implements javax.media.ControllerListener private Player player;private JFrame jf;public MyConreollerListener(Player play

18、er, JFrame jf) this.player = player;this.jf = jf;/* * 实现监听器接口中的方法.此方法可通知应用程序对播放器的事件做出反应 */public synchronized void controllerUpdate(ControllerEvent e) if (e instanceof javax.media.RealizeCompleteEvent) Component comp;/得到播放器的可视容器,即播放器显示视频的容器if (comp = player.getVisualComponent() != null) /将可视容器加到窗体上j

19、f.add(Center, comp);/得到播放器的控制面板容器if (comp = player.getControlPanelComponent() != null) /添加到窗体上jf.add(South, comp);jf.validate();/刷新窗体2JMF使用RTP协议21. 实时传输协议RTP(Real-Time Transport Protocol)实时传输协议RTP(Real-Time Transport Protocol)是针对Internet上多媒体数据流的一个传输协议,由IETF(Internet工程任务小组)作为RFC1889发布。RTP被定义为在一对一或一对多

20、的传输情况下工作,其目的是提供时间信息和实现流同步。RTP的典型应用建立在UDP上,但也可以建立在TCP或ATP等其它协议之上工作。RTP本身只保证实时数据的传输,并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。211 RTP工作机制多媒体数据传输最大的问题就是不可预料数据到达的时间。但是流媒体的传输是需要数据的适时到达用于播放和回放。RTP协议就是提供了时间标签、序列号以及其它的结构用于控制适时数据的流放。在流的概念中“时间标签”是最重要的信息。发送端依照即时的采样在数据包里隐藏的设置了时间标签。在接受端收到数据包后,就依照时间标签正确的速

21、率恢复成原始的适时数据。不同的媒体格式调时属性是不同的。但是RTP本身并不负责同步,RTP只是传输层协议,为了简化传输层处理,提高该层的效率,将部分传输层协议功能(比如流量控制)上移到应用层来完成,同步就属于应用层协议应该完成的任务。它没有传输层协议的完成功能,不提供任何机制来保证实时的传输数据,不支持资源预留,也不保证服务质量。RTP报文甚至不包括长度和报文边界的描述。同时RTP协议的数据报文和控制报文的使用相邻的不同的端口,这样大大提高了协议的灵活性和处理的简单性。RTP协议和UDP二者共同完成传输层协议功能。UDP协议只是传输数据包,不管数据包传输的时间顺序,RTP协议数据单元是用UDP

22、分组来承载的,在承载RTP数据包的时候,有时一帧数据被分割成几个包具有相同的时间标签,则可以知道是标签并不是必须的。而UDP的多路复用让RTP协议利用支持显示的多点投递,可以满足多媒体会话的需求。RTP协议和虽然是传输层协议但是它没有作为OSI体系结构中单独的一层来实现。RTP协议通常根据一个具体的应用来提供服务RTP只是提供协议框架,开发者可以根据应用具体要求对协议进行充分扩展。22 实时传输控制协议RTP(Real-Time Transport Control Protocol)RTCP(Real-Time Transport Control Protocol)负责挂你传输质量在当前应用进

23、程之间交换控制信息。在RTP会话期间,各参与者周期性的传输RTCP包,包中含有已发送信的数据报的数量、丢失的数据报的数量等统计资料。因此,服务器可以利用这些信息动态的改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,能够以有效的反馈和最小的开销使传输效率最佳化,特别适合传送网上的实时数据。221 RTCP工作机制当应用程序开始一个RTP会话时将使用两个端口:一个给RTP,一个给RTCP。RTP依靠RTCP提供按顺序传送数据包提供可靠的传送机制,以及依靠RTCP提高流量控制或拥塞控制。在RTP会话之间周期的发放一些RTCP包以用来监听服务质量和交换会话用户信息等功能。Name = J

24、avaSound audio captureLocator = javasound:/44100Output Formats-0. javax.media.format.AudioFormat LINEAR, 44100.0 Hz, 16-bit, Stereo, LittleEndian, Signed1. javax.media.format.AudioFormat LINEAR, 44100.0 Hz, 16-bit, Mono, LittleEndian, Signed2. javax.media.format.AudioFormat LINEAR, 22050.0 Hz, 16-bi

25、t, Stereo, LittleEndian, Signed3. javax.media.format.AudioFormat LINEAR, 22050.0 Hz, 16-bit, Mono, LittleEndian, Signed4. javax.media.format.AudioFormat LINEAR, 11025.0 Hz, 16-bit, Stereo, LittleEndian, Signed5. javax.media.format.AudioFormat LINEAR, 11025.0 Hz, 16-bit, Mono, LittleEndian, Signed6.

26、javax.media.format.AudioFormat LINEAR, 8000.0 Hz, 16-bit, Stereo, LittleEndian, Signed7. javax.media.format.AudioFormat LINEAR, 8000.0 Hz, 16-bit, Mono, LittleEndian, SignedName = vfw:Microsoft WDM Image Capture (Win32):0Locator = vfw:/0Output Formats-0. javax.media.format.RGBFormat RGB, 320x240, Le

27、ngth=230400, 24-bit, Masks=3:2:1, PixelStride=3, LineStride=960, Flipped1. javax.media.format.RGBFormat RGB, 640x480, Length=921600, 24-bit, Masks=3:2:1, PixelStride=3, LineStride=1920, Flipped2. javax.media.format.YUVFormat YUV Video Format: Size = java.awt.Dimensionwidth=320,height=240 MaxDataLeng

28、th = 153600 DataType = class B yuvType = 32 StrideY = 640 StrideUV = 640 OffsetY = 0 OffsetU = 1 OffsetV = 33. javax.media.format.YUVFormat YUV Video Format: Size = java.awt.Dimensionwidth=640,height=480 MaxDataLength = 614400 DataType = class B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY =

29、0 OffsetU = 1 OffsetV = 34. com.sun.media.format.AviVideoFormat MJPG, 320x240, Length=230400 0 extra bytes5. com.sun.media.format.AviVideoFormat MJPG, 640x480, Length=921600 0 extra bytes222 RTCP数据包在RTCP通信控制中,RTCP协议的功能是通过不同的RTCP数据包来实现的,主要有如下几种类型:类型名称功能SR发送端报告发送端指的是发出RTP数据报的应用程序或者终端,发送端同时也是接收端RR接收端报告

30、接收端是指仅接收但不发送RTP数据报的应用程序或终端SDES源描述作为会话成员有关标识信息的载体,如用户名、邮件地址、电话号码等,此外还具有向会话成员传达会话控制信息的功能BYE通知离开指示某一个或几个源不再有效,即通知会话中的其他成员自己将退出会话APP自定义由应用程序自己定义,解决RTCP的扩展性问题,为协议的实现者提供了很大的灵活性23 JMF中使用RTPJMF中可以实现RTP媒体流的回放(playback)和传输(transmission),主要由javax.media.rtp、javax.media.rtp.event和javax.media.rtp.rtcp包中定义的API完成。J

31、MF可以通过标准的JMF pulg-in机制来实现支持特定的RTP格式和动态负载。你可以在本地播放RTP数据流,或将其存储到本地文件:同样,你可以通过JMF中RTP API实现传输捕获的或存储的媒体流到网上。RTP媒体流可以创建自一个本地文件或捕获自媒体采集设备。这些RTP媒体流同样可以在本地播放或存储。24 RTP结构241 Session管理器SessionManager在JMF架构中SessionManager对程序之间的会话进行控制和管理。SessionManager主要作用是: 明确每一个会话(Session)中所有参与者(participants); 管理每一个RTP会话; 保存来

32、自每一个发送或者接收到的RTP和RTCP包中的统计信息。SessionManager中包含2个部分:Session Statistics和Session Streams。统计量(Statistics)记录基于每一条媒体流上的整个会话的统计信息GobalReceptionStats包含此会话的全局接收统计信息GobalTransmissionStats包含此会话的全局传输统计信息RecetionStats包含每一个参与者接收统计信息TransmissionStats包含每一个参与者传输统计信息媒体流(Stream)ReceiveStream表示一个接收到的来自远端参与者的媒体流SendStrea

33、m表示一个来自本地的媒体流242 RTP事件RTPEventRTP采用时间架构机制,实现会话,如下图所示,通过继承JMF中的MediaEvent类,可以创建响应的RTP事件:详细的说明如下:ReceiveStreamEvent得到一个正在接收的RTP数据流状态的改变ActiveReceiveStreamEvent表示数据流的传送已经开始ApplicationEvent表示收到了一个RTCP App数据包InactiveReceiveStreamEvent表示数据流的传送已经停止NewReceiveStreamEvent表示SessionManager已经创建了一个从新的侦测到的地址传来的接受数

34、据流RemotePayloadChangeEvent表示接收到的数据流格式已经改变TimeoutEvent表示数据传送超时RemoteEvent得到远端会话参与者的时间或RTP控制信息ReceiveReportEvent表示接收到一个RTCP的RR包SenderReportEvent表示收到一个RTCP的SR包RemoteCollisionEvent表示两个远端的参与者使用了相同的SSRC出错SendStreamEvent得到一个正在传送的RTP数据流状态的改变ActionSendStreamEvent表示从DataSource创建的数据流已经开始传送InactiveSendStreamEve

35、nt表示从本地DataSource创建的数据流已经停止传送LocalPayloadChangeEvent表示数据流格式已经改变NewSendStream表示本地参与者已经创建了一个新的发送数据流StreamClosedEvent表示数据流已经停止SessionEvent得到一个会话状态的改变NewParticipantEvent表示一个新的参与者加入会话LocalCollisionEvent表示参与者请求的同步资源正在使用243 与RTP事件相对应的RTCP类型RTCP类型JMF中的事件类SRSendStreamEventRRReceiveStreamEventSDERSenderReport

36、EventBYEByeEvent(扩展于TimeoutEvent)APPApplicationEvent244 数据传输格式在RTP中,如果还是用传统的AVI、MOV格式的话,将会增加服务器负荷,而且对网络的要求特别高,因此需要将传统的格式转化至易于传送、网络适应性好、抗丢包性能和抗误码性能好的编码格式。下面是JMF目前支持的音频和视频传送的压缩格式,也就是说经过定制后的输出多媒体流,还得进行一次转换,以便网络发送。多媒体类别RTP传输格式音频JAUIO_G711_ULAW/rtp,dvi/rtp,g723/rtp,gsm/rtp视频jpeg/rtp,h261/rtp,h263/rtp245

37、基于JMF的RTP/RTCP传输模型的整体设计25 JMF升级为FMJFMJ(Freedom for Media in Java)是一个Java的开源项目,它是JMF(Java Media Framework)的一个“替代品”,其API与JMF兼容,可用于采集、回放、处理跨平台的流媒体。它不需要给JRE安装任何东西,并能够使用现存的第三方插件如JFFMPEG和MPEF-4,还提供一些JMF没有的特性,如SWT支撑等。FMJ的下载地址:http:/fmj-由于其与JMF兼容,所以我们使用JMF开发的项目可以放在FMJ下运行,我们可以把FMJ看作是JMF的一个扩展,注意,仅仅是可以看作。下面的代码

38、,我们是在FMJ环境下开发的,当然,你也可以在JMF环境下开发,只是需要引入FMJ的部分API,如在JMF中只提供了一个基于UDP的RTP连接的接口:RTPConnector.java,这个接口在FMJ项目中已经有一个实现类RTPSocketAdapter.java提供给我们使用,当然,你也可以根据RTP协议和UDP协议开发自己的适用于流媒体传输的连接类,只要实现RTPConnector.java接口就可以了。3FMJ视频聊天室的实现31 视频聊天整体结构分析整体流程图示:服务器和客户机通过基于UDP的RTP通信协议传输媒体流数据,在建立RTP会话之前,先建立一个Socket连接,以发送接收其

39、它请求消息,如要发送多媒体数据的请求和应答消息。发送视频请求消息和完成应答之后,服务器利用客户机发上来的消息建立RTP会话,因此在视频请求的消息中应包含客户机的地址、端口等消息,以供服务器建立RTP会话。客户机也要和服务器建立对应的RTP会话,这样,视频数据流就可以通过RTP会话传输:32. 视频聊天客户端代码实现创建项目,在项目下引入FMJ的核心类库:fmj.jar。启动客户端的类:ClientStart.javapackage java.client;import java.awt.event.ActionEvent;import javax.swing.JFrame;import jav

40、ax.swing.JPanel;/* * 界面类*/public class ClientStart extends JFrame public static JPanel panel = new JPanel();public static JFrame jf = new JFrame();public static void main(String args) ClientStart test = new ClientStart();test.initUI();/* * 初始化界面 */public void initUI() jf.setTitle(JMF播放视频示例);jf.setSi

41、ze(560, 480);jf.setLayout(new java.awt.BorderLayout();/ 本地视频显示panel.setPreferredSize(new java.awt.Dimension(560, 410);panel.setLayout(new java.awt.BorderLayout();panel.setBackground(java.awt.Color.BLACK);JPanel panel1 = new JPanel();panel1.setPreferredSize(new java.awt.Dimension(560, 40);javax.swing

42、.JLabel ipLabel = new javax.swing.JLabel(ServerIP:);final javax.swing.JTextField ipText = new javax.swing.JTextField(15);javax.swing.JLabel portLabel = new javax.swing.JLabel(ServerPort:);final javax.swing.JTextField portText = new javax.swing.JTextField(5);javax.swing.JButton button = new javax.swi

43、ng.JButton(开始视频);panel1.add(ipLabel);panel1.add(ipText);panel1.add(portLabel);panel1.add(portText);panel1.add(button);jf.add(java.awt.BorderLayout.NORTH, panel);jf.add(java.awt.BorderLayout.SOUTH, panel1);jf.setResizable(false);jf.setDefaultCloseOperation(3);jf.setVisible(true);button.addActionListe

44、ner(new java.awt.event.ActionListener() public void actionPerformed(ActionEvent e) /获得输入的IP和PORTString ip = ipText.getText();String sport = portText.getText();try int port = Integer.parseInt(sport);if (port 1000 & port 10000) ClientCaptureDevice ccd = new ClientCaptureDevice(ip, port);ccd.start(); e

45、lse javax.swing.JOptionPane.showMessageDialog(null,Port must be between 1000 to 10000); catch (Exception ef) javax.swing.JOptionPane.showMessageDialog(null,Port only is number););接下来,首先要获取本机的多媒体设备,创建多媒体数据源: ClientCaptureDevice.java,注意的是要把这个类作为一个线程:package java.client;import java.io.DataOutputStream;

46、import java.io.IOException;import java.io.OutputStream;import .InetAddress;import .Socket;import .UnknownHostException;import java.util.Vector;import javax.media.CaptureDeviceInfo;import javax.media.CaptureDeviceManager;import javax.media.Format;import javax.media.MediaLocator;import javax.media.for

47、mat.VideoFormat;/* * JMF语音视频获取本地数据源 * author kowloon*/public class ClientCaptureDevice extends Thread private Socket sc; / 连接对象private String serverAddress; / 目标主机IP地址private int port; / 目标主机IP端口private CaptureDeviceInfo audioCapDevInfo; / 多媒体采集信息对象private VideoFormat currentFormat; / 多媒体格式化对象privat

48、e MediaLocator audioCapDevLoc; / 设备定位器对象public ClientCaptureDevice(String serverAddress, int port) this.port = port;this.serverAddress = serverAddress;public void run() initCaptureDevice();/ 调用传输数据的方法startTransmit();/* * 初始化采集设备 */public void initCaptureDevice() / 获取所有的多媒体采集对象Vector audioCapDevList

49、= CaptureDeviceManager.getDeviceList(null);/ 如果存在多媒体采集对象if (audioCapDevList.size() != 0) for (int i = 0; i audioCapDevList.size(); i+) / 获取一个可用设备名字,转换成采集对象audioCapDevInfo = audioCapDevList.elementAt(i);Format videoFormats = audioCapDevInfo.getFormats();/ 如果设备名称以vfw开头if (audioCapDevInfo.getName().sta

50、rtsWith(vfw:) / 获得所有支持RGB格式for (int j = 0; j videoFormats.length; j+) / 我们只需要第一种YUV格式if (videoFormatsj instanceof VideoFormat) currentFormat = (VideoFormat) videoFormatsi;break;if (currentFormat = null) System.err.println(Search For VideoFormat Failed);System.exit(-1);/ 得到该设备的定位器audioCapDevLoc = aud

51、ioCapDevInfo.getLocator();/* * 发送视频 */public void startTransmit() try / 建立Socket连接sc = new Socket(serverAddress, port);/ 此处只针对视屏 本地地址,端口InetAddress add = sc.getLocalAddress();int sport = sc.getLocalPort();String ip = add.toString().substring(1);String session = ip + / + sport;/ 得到输出流OutputStream out

52、 = sc.getOutputStream();DataOutputStream output = new DataOutputStream(out);byte address = session.getBytes();int len = address.length;/ 将视频信息发送给目标主机(包括发送视频的主机地址,端口,消息类型)output.writeInt(8 + len);output.writeInt(10001); / 这里我们设定10001为发送视频请求output.write(address);/创建视频格式化对象Format format = new Format(Vi

53、deoFormat.JPEG);/创建视频发送对象VedioTransmit vedio = new VedioTransmit(audioCapDevLoc, serverAddress, + sport, format);vedio.start();/启动视频发送 catch (Exception e) e.printStackTrace();接下来创建一个类用来发送视频的类,在传输之前,我们做一些准备工作,如:将数据源转换成用于传输的数据格式、设置传输的质量、传输的同时在本地播放,在JMF中,一个DataSource只能用于一个事件,所以在这里,我们要将从多媒体设备获得的数据源实现克隆,

54、再对克隆的数据源进行操作,在这个例子中,我们克隆出一份数据源用于传输到远程,一份用于本地播放。 package java.client;import java.io.IOException;import .InetAddress;import javax.media.*;import javax.media.control.*;import javax.media.protocol.*;import javax.media.rtp.*;import javax.media.format.VideoFormat;import javax.media.rtp.rtcp.SourceDescript

55、ion;import net.sf.fmj.media.rtp.RTPSocketAdapter;/* * JMF语音视频发送*/public class VedioTransmit private MediaLocator locator; / 多媒体数据源private DataSource ds;/ 克隆的数据源private DataSource dataClone;/ 可克隆数据源private String ipAddress; / 发送视频位置IPprivate int portBase; / 端口号private Processor processor = null;/ 媒体处

56、理器private RTPManager rtpMgrs; / RTP管理器private DataSource dataOutput = null;/ 输出数据源public VedioTransmit(MediaLocator locator, String ipAddress, String pb,Format format) this.locator = locator;this.ipAddress = ipAddress;Integer integer = Integer.valueOf(pb);if (integer != null) this.portBase = integer

57、.intValue();/* * 启动传输 返回值为空时,启动成功 否则 返回失败的原因 */public synchronized String start() String result;/ 创建一个Prpcessor针对特殊的媒体result = createProcessor();if (result != null) return result;/ 创建一个会话,包含目标地址和端口号result = createTransmitter();if (result != null) processor.close();processor = null;return result;/ 本地

58、播放克隆数据源ChatSource cs = new ChatSource(dataClone);cs.start();/ 开始传输processor.start();return null;/* * 创建一个Prpcessor * return if null 则说明配置与读取成功 else 返回失败原因 */private String createProcessor() if (locator = null) return Locator is null;try / 根据设备定位器得到数据源dataOutput = Manager.createDataSource(locator);/ 创建可克隆数据源dataClone = Manager.createCloneableDataSourc

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!