将RTP视频流(H264编解码器)写入mp4文件

时间:2011-08-31 10:07:55

标签: java video-streaming h.264 rtp fileoutputstream

我想将从rtp(实时)流录制的H264视频存储到文件中。 我试过一个简单的java程序,但vlc播放器无法打开文件。

这是我的代码:

    try
    {
        socket = new DatagramSocket(port);
        fos = new FileOutputStream(filePath + outputFileName);

        do
        {
            DatagramPacket in = new DatagramPacket(inData, inData.length);
            socket.receive(in);

            byte[] bytes = in.getData();

            if (curPos < buffer.length)
            {
                for (int i = 0; i < bytes.length; i++)
                {
                    buffer[curPos] = bytes[i];
                    curPos++;

                    if (curPos >= buffer.length)
                    {
                        receivePackets = false;
                        break;
                    }
                }
            }
            else
            {
                receivePackets = false;
            }

            Thread.sleep(SOCKET_TIMEOUT);
        }
        while (receivePackets);

        fos.write(buffer, 0, buffer.length);            

        if (fos != null)
        {
            fos.close();
        }

        if (socket != null)
        {
            socket.close();
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }

将创建文件,但无法打开它。 是否有任何标题信息我要剪切或添加到字节数组以获得正确的视频文件?

更新

好吧,问题似乎是h264 rtp数据包的最终标题信息,因为我可以用标准的rtp标题打开录制的h263视频(但视频的质量非常差)。

2 个答案:

答案 0 :(得分:0)

您必须从RTP数据包中解压缩视频数据

答案 1 :(得分:0)

Rtp 的数据包中包含不属于 h264 流一部分的标头,并且具有将一个 nal 单元(基本上是单个 h264“数据包”)拆分为多个数据包或将多个 nal 单元合并为一个数据包的机制,两者都添加了不能成为最终产品一部分的元数据。

此外,RTP 流可能不包含播放视频所需的某些元数据,尤其是在通过 rtsp 协商时。如果是这种情况,您将不得不从 SDP 中的 sprop-parameter-sets 中提取一些 NAL 单元。

您可以在此处找到有关所有这些工作原理的文档:https://tools.ietf.org/html/rfc6184。真的没有听起来那么难。

当 h264 写入文件时,每个 nal 单元前面必须是三个 0 字节,然后是一个 1 字节。您可以在此处找到更多详细信息:https://www.itu.int/rec/T-REC-H.264-201906-I/en

必须与 VLC 对话才能播放原始的 h264 文件。你可以谷歌搜索并找到简单的步骤,它与代码无关,所以我不会在这里复制它们。

如果您希望将文件作为 mp4,最好使用库来执行此操作。如果你想自己做这一切,天堂会帮助你,但你可以在这里找到规范:https://web.archive.org/web/20180921052457/http://l.web.umkc.edu:80/lizhu/teaching/2016sp.video-communication/ref/mp4.pdfhttps://github.com/sannies/mp4parser 库是 java 并且可能会这样做,但是有一些问题。 Ffmpeg 是一个很好的程序,可以做到这一点,我很幸运地将它作为 Java 的子进程运行,并输入其标准并读取其标准输出。

顺便说一句,ffprobe 是一个很棒的程序,在损坏的视频文件上运行它可以提供一些有关它的问题的见解。