我想做一个audio/video streaming,从一台机器发送到另外一台机器。
原始数据来自硬盘上的一个mpeg-1文件,我使用JMF标准结构来封装它(DataSource, Processor等),使用JMF自带的格式进行编码(G723_RTP, GSM_RTP, JPEG_RTP等),使用RTPManager来传输数据。所有代码均改编自java.sun.com网站上的example code。
经过实验,audio/video数据的确能够传输到接收端。实现了这个基本功能后,我需要实现的另外一个目标是在传输过程中改变数据编码格式。以video轨道为例,发送端初始编码格式为MPEG_RTP(通过processor的trackControl设定),运行时,我需要改变编码格式(比如说改变为JPEG_RTP)。我查了很多资料,都没有得到解决方法或例程。主要困难在于:
编码格式是在processor.configured状态下设定的,当rtp传输建立后,似乎已经不能够改变processor输出格式了(因为processor已经realized了)。为了解决这个问题,我试图在rtp传输过程中重新生成一个datasource,用这个datasource生成一个新的processor,在这个processor configure()之后设定它的格式为JPEG_RTP,然后把这个新生成的datasource, processor对象付给现有的rtp session。可是实验中我发现,一旦进行进行对象赋予的操作,就会出现hotfix。部分核心代码如下,主要有两个类。一个是Sender类进行数据打包,制定格式,一个是RTPTransmit类,进行rtp数据传输,这两个类都运行在发送端。执行流程是Sender.function1 -> RTPTransmit.function2 -> Sender.function2 -> RTPTransmit.updateProcessor。 public class Sender {
public RTPTransmit rtp; // 记录相关的rtp传输对象 public void function1 () { //这是执行流程的第一步
//这里执行生成初始datasource, processor等操作
........
DataSource ds = Manager.createDataSource(ml);
Processor processor = Manager.createProcessor(ds);
track[i].setFormat(new VideoFormat(VideoFormat.MPEG_RTP));
// 最后生成RTPTransmit类的对象传输数据
........
} public void function3 () { //这是执行流程的第三步
//运行过程中,这里根据新格式生成一个新的dataSource, processor
........
DataSource ds = Manager.createDataSource(ml);
Processor processor = Manager.createProcessor(ds);
track[i].setFormat(new VideoFormat(VideoFormat.JPEG_RTP)); //新格式
........
//接着把生成的process对象传给正在传输数据的RTPTransmit类的对象
this.rtp.updateProcessor(processor)
}
} // end of class Sender
public class RTPTransmit { //这里是启动rtp传输的类
public Processor processor; // 这两个数据结构在运行时
public DataSource dataOutput; //被我试图重新赋值,出错 public void function 2 () { //这是执行流程的第二步
//传输数据
........
RTPManager rtpMgrs[i] = RTPManager.newInstance();
dataOutput = processor.getDataOutput();
sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
sendStream.start();
processor.start();
........
} public void updateProcessor (Processor p) { //这是执行流程的第四步
//这里先停止RTPTransmit对象的数据传输,
//付给新的dataSource, processor,再重启传输
this.dataOutput.stop();
this.processor.stop(); // this.processor.deallocate();
this.dataOutput = p.getDataOutput();
this.dataOutput.start();
this.processor.start();
}
} // end of class RTPTransmit紧急求救各位大侠啊,是不是我的思路有问题,或者是实现发现有问题?多谢多谢
原始数据来自硬盘上的一个mpeg-1文件,我使用JMF标准结构来封装它(DataSource, Processor等),使用JMF自带的格式进行编码(G723_RTP, GSM_RTP, JPEG_RTP等),使用RTPManager来传输数据。所有代码均改编自java.sun.com网站上的example code。
经过实验,audio/video数据的确能够传输到接收端。实现了这个基本功能后,我需要实现的另外一个目标是在传输过程中改变数据编码格式。以video轨道为例,发送端初始编码格式为MPEG_RTP(通过processor的trackControl设定),运行时,我需要改变编码格式(比如说改变为JPEG_RTP)。我查了很多资料,都没有得到解决方法或例程。主要困难在于:
编码格式是在processor.configured状态下设定的,当rtp传输建立后,似乎已经不能够改变processor输出格式了(因为processor已经realized了)。为了解决这个问题,我试图在rtp传输过程中重新生成一个datasource,用这个datasource生成一个新的processor,在这个processor configure()之后设定它的格式为JPEG_RTP,然后把这个新生成的datasource, processor对象付给现有的rtp session。可是实验中我发现,一旦进行进行对象赋予的操作,就会出现hotfix。部分核心代码如下,主要有两个类。一个是Sender类进行数据打包,制定格式,一个是RTPTransmit类,进行rtp数据传输,这两个类都运行在发送端。执行流程是Sender.function1 -> RTPTransmit.function2 -> Sender.function2 -> RTPTransmit.updateProcessor。 public class Sender {
public RTPTransmit rtp; // 记录相关的rtp传输对象 public void function1 () { //这是执行流程的第一步
//这里执行生成初始datasource, processor等操作
........
DataSource ds = Manager.createDataSource(ml);
Processor processor = Manager.createProcessor(ds);
track[i].setFormat(new VideoFormat(VideoFormat.MPEG_RTP));
// 最后生成RTPTransmit类的对象传输数据
........
} public void function3 () { //这是执行流程的第三步
//运行过程中,这里根据新格式生成一个新的dataSource, processor
........
DataSource ds = Manager.createDataSource(ml);
Processor processor = Manager.createProcessor(ds);
track[i].setFormat(new VideoFormat(VideoFormat.JPEG_RTP)); //新格式
........
//接着把生成的process对象传给正在传输数据的RTPTransmit类的对象
this.rtp.updateProcessor(processor)
}
} // end of class Sender
public class RTPTransmit { //这里是启动rtp传输的类
public Processor processor; // 这两个数据结构在运行时
public DataSource dataOutput; //被我试图重新赋值,出错 public void function 2 () { //这是执行流程的第二步
//传输数据
........
RTPManager rtpMgrs[i] = RTPManager.newInstance();
dataOutput = processor.getDataOutput();
sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
sendStream.start();
processor.start();
........
} public void updateProcessor (Processor p) { //这是执行流程的第四步
//这里先停止RTPTransmit对象的数据传输,
//付给新的dataSource, processor,再重启传输
this.dataOutput.stop();
this.processor.stop(); // this.processor.deallocate();
this.dataOutput = p.getDataOutput();
this.dataOutput.start();
this.processor.start();
}
} // end of class RTPTransmit紧急求救各位大侠啊,是不是我的思路有问题,或者是实现发现有问题?多谢多谢
不过有个小疑问,两个clone的DataSource视频同步吗?如果我操作其中一个,会不会影响到另外一个?比如我stop其中一个,另外一个还有数据输出吗?
CLONE了 则互不干扰了
不过JAVA搞JMF的人真的很少哦
国防科大有些人在搞这个 而且有些成果了 可惜不知如何联系