嗨,
我们是从事Java项目的学生,我们必须:
- 从网络摄像头捕获视频流
- 将此流与视频文件合并(我们取每个像素的颜色平均值,因此两个流是叠加的)
- 使用RTP或RTSP在网络上传输此合并的结果(理论上,它将被2台Android平板电脑接收)
非常重要的一点是,所有这些操作都应该是实时的(或几乎)。RTP流应在网络摄像头捕捉视频的同时接收。
为了做到这一点,我们使用Java媒体框架(JMF)API。第一点和第二点已经成功实现:每秒,来自网络摄像头的30BufferedImage与来自视频文件的30BufferedImage合并。结果显示在一个经典的JFrame上(我们只使用Swing和JMF),效果非常好。
我们还得做第三点。通过RTP发送视频流不是很难。但问题是:由于第1点和第2点,我们没有视频流,而是一系列BufferedImages。我们知道如何从这些BufferedImage中获取视频文件。但这只是硬盘上录制的视频文件,无法在网络上实时发送。那么,我们如何从这些BufferedImage中生成一个可以通过RTP直接发送的动态流呢?
提前感谢您的帮助。
我想改进我的答案。
首先是一个问题,你是否真的必须使用RTP/RTP。如果你不必这样做,你可以通过DatagramSocket发送图像数据,并假设接收器知道如何解码。使用类似的东西
DatagramSocket socket = new DatagramSocket(port);
DatagramPacket packet = new DatagramPacket(new byte[1], 1);
packet.setAddress(receiver.getAddress());
packet.setPort(port);
while(running)
{
byte[] data = getMergedImageData();
packet.setData(data);
packet.setLength(data.length);
socket.send(packet);
}
如果你必须使用RTP,你应该看看mjsip项目。基本上,您必须创建一个有效的RTP标头(例如,数据缓冲区中的前12个字节)。如果你知道每个比特属于哪里,这就相当简单了
根据您对图像的编码方式,您可能需要警惕其他要求。例如,当通过RTP发送Jpeg时,您必须删除完整的Jpeg标头,并创建一个缩写的RTP/Jpeg标头,然后将其放置在RTP标头和有效负载之间。接收器将不得不从缩写的标头重新创建Jpeg标头。对于Jpeg,如果图像中还没有EOI标记,也要确保添加EOI标记。我认为在这方面,如果你敢于深入JNI,ffmpeg可以为你做很多工作。
有关如何定制RTP有效载荷的更多信息,请参阅。
干杯~