JMF(五) 之 RTP 应用

1. 发送实时媒体数据

如果需要将媒体数据发送到网络,首先需要用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()

    2. 接收实时视频数据

接收网上传输的数据流时,首先要构建一个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。

把数据源对象作为参数传递到Manager的createPlayer方法中来创建Player。如果要成功的创建Palyer需要必要的支持RTP格式的编码、解码的插件。

具体实现参考以下代码片断

//创建SessionManager

public SessionManager createManager(String address,

int port,

int ttl,

boolean listener,

boolean sendlistener)

{

mgr = (SessionManager)new com.sun.media.rtp.RTPSessionMgr();

if (mgr == null) return null;

mgr.addFormat(new AudioFormat(AudioFormat.DVI_RTP,44100,4,1),18);

//添加监听器,监听收到新数据流时间

if (listener) mgr.addReceiveStreamListener(this);

if (sendlistener) new RTPSendStreamWindow(mgr);

//初始化SessionManager

mgr.initSession(localaddr, userdesclist,0.05,0.25);

//启动SessionManager

mgr.startSession(sessaddr,ttl,null);

} catch (Exception e) {

System.err.println(e.getMessage());

return null;

}

return mgr;

}

//监听事件,如果接收到新数据流后所做的工作

public void update( ReceiveStreamEvent event)

{

Player newplayer = null;

RTPPlayerWindow playerWindow = null;

// 获取新数据流的数据源

SessionManager source = (SessionManager)event.getSource();

// 当检测到新接收数据源时,创建新的播放器

if (event instanceof NewReceiveStreamEvent)

{

String cname = "Java Media Player";

ReceiveStream stream = null;

try

{

// 获取接收数据流

stream =((NewReceiveStreamEvent)event)

.getReceiveStream();

//获取数据流的发送源地址

Participant part = stream.getParticipant();

if (part != null) cname = part.getCNAME();

// 获取发送数据流的数据源

DataSource dsource = stream.getDataSource();

// 将数据源作为参数传递给MediaManager来创建Player

newplayer = Manager.createPlayer(dsource);

System.out.println("created player " + newplayer);

} catch (Exception e) {

System.err.println("NewReceiveStreamEvent exception "

+ e.getMessage());

return;

}

if (newplayer == null) return;

playerlist.addElement(newplayer);

newplayer.addControllerListener(this);

//更新播放器界面,这样就可以同时显示多个数据流了

playerWindow = new RTPPlayerWindow( newplayer, cname);

}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Spring Boot中集成Java Media Framework(JMF)并监听RTP端口,需要完成以下步骤: 1. 添加JMF库到项目的依赖中。可以通过在Maven或Gradle配置文件中添加以下依赖来实现: ```xml <dependency> <groupId>javax.media</groupId> <artifactId>jmf</artifactId> <version>2.1.1e</version> </dependency> ``` 2. 创建一个类,该类实现 `javax.media.protocol.DataSource` 接口。这个类将会被用来接收RTP数据。在这个类中,你需要实现 `getContentType()` 和 `connect()` 方法。 ```java public class RtpDataSource implements DataSource { private final String contentType = "raw"; private RTPManager rtpManager; private boolean connected; @Override public String getContentType() { return contentType; } @Override public void connect() throws IOException { rtpManager = RTPManager.newInstance(); // Configure RTP Manager SessionAddress localAddress = new SessionAddress(); rtpManager.initialize(localAddress); rtpManager.addReceiveStreamListener(new RtpStreamListener()); connected = true; } @Override public void disconnect() { rtpManager.removeTargets("Client disconnected"); rtpManager.dispose(); connected = false; } @Override public void start() throws IOException { rtpManager.startSession(null); } @Override public void stop() throws IOException { rtpManager.stopSession(); } @Override public Object getControl(String controlType) { return null; } @Override public Object[] getControls() { return new Object[0]; } @Override public Time getDuration() { return DURATION_UNKNOWN; } @Override public MediaLocator getLocator() { return null; } @Override public PushSourceStream[] getStreams() { return new PushSourceStream[0]; } @Override public boolean isConnected() { return connected; } } ``` 3. 创建一个类来监听RTP流。这个类必须实现 `javax.media.rtp.ReceiveStreamListener` 接口。在这个类中,你需要实现 `update()` 方法,以处理接收到的数据。 ```java public class RtpStreamListener implements ReceiveStreamListener { @Override public void update(ReceiveStreamEvent receiveStreamEvent) { // Handle the received RTP data here } } ``` 4. 在Spring Boot应用程序中创建一个 `@Configuration` 类,该类将创建一个 `DataSource` 实例并将其注册到Spring容器中。 ```java @Configuration public class RtpDataSourceConfig { @Bean public DataSource rtpDataSource() { return new RtpDataSource(); } } ``` 5. 启动应用程序并监听RTP端口。可以通过以下方式来启动应用程序: ```java @SpringBootApplication public class RtpServerApplication implements CommandLineRunner { @Autowired private DataSource rtpDataSource; public static void main(String[] args) { SpringApplication.run(RtpServerApplication.class, args); } @Override public void run(String... args) throws Exception { rtpDataSource.connect(); rtpDataSource.start(); } } ``` 现在你已经成功地集成了JMF并监听了RTP端口!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值