0

你好,

我们是从事 Java 项目的学生,我们必须:

  1. 从网络摄像头捕获视频流
  2. 将此流与视频文件合并(我们取每个像素颜色的平均值,因此两个流是叠加的)
  3. 使用 RTP 或 RTSP 在网络上传输此合并的结果(理论上,它将被 2 个 Android 平板电脑接收)。

非常重要的一件事是所有这些操作都应该是实时的(或几乎是实时的)。应该在网络摄像头捕获视频的同时接收 RTP 流。

为此,我们使用 Java Media Framework (JMF) API。第一点和第二点已经成功实现:每秒,来自网络摄像头的 30 个BufferedImage与来自视频文件的30 个BufferedImage合并。结果显示在经典的 JFrame 上(我们只使用 Swing 和 JMF),而且效果非常好。

我们还要做第三点。通过 RTP 发送视频流并不难。 但问题是:由于第 1 点和第 2 点,我们没有视频流,而是一系列 BufferedImages。我们知道如何从这些 BufferedImage 中获取视频文件。但它只是硬盘上录制的视频文件,无法在网络上实时发送。那么我们如何从这些 BufferedImage 中制作一个可以通过 RTP 直接发送的动态流呢?

在此先感谢您的帮助。

4

1 回答 1

1

我想改进我的答案。

首先是你是否真的必须使用 RTP/RTSP 的问题。如果您不需要,您可以仅通过 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 标记。我认为在这方面,如果你敢于深入 JNI,ffmpeg可以为你做很多工作。

有关如何调整 RTP 有效负载的更多信息,请参阅

干杯~

于 2013-03-02T15:32:04.480 回答