【问题标题】:How to concatenate/merge two videos in a new video file in Java?如何在 Java 的新视频文件中连接/合并两个视频?
【发布时间】:2023-03-15 14:06:01
【问题描述】:

我正在使用humble-video 的RecordAndEncodeVideo.java 创建视频。

我现在想合并两个视频,第一个是录制的视频,第二个是我的system 上预存的相同帧率和分辨率的视频。由于限制,我想通过在java中使用humble-video apis来做到这一点。如果有人用过,请指导我如何做。

这是我尝试过的代码:

  public static void combineVideo() throws InterruptedException, IOException {
    final Demuxer demuxer = Demuxer.make();
    demuxer.open("a.mp4", null, false, true, null, null);
    final Muxer muxer = Muxer.make("b.mp4", null, null);
    final MuxerFormat format = muxer.getFormat();
    final MediaPacket packet = MediaPacket.make();
    muxer.open(null, null);
    while (demuxer.read(packet) >= 0) {
        muxer.write(packet, false);
    }
    muxer.close();
    demuxer.close();
}

更新

我想连接两个视频文件并另存为一个新的视频文件。我知道在之前的问题中已经问过这个问题例如-

  1. how-to-concat-or-merge-two-or-more-video-files-in-android
  2. merge-multiple-video-file-in-a-file

但大多数答案都链接到不可用的资源或库。谁能指导我一些资源。任何代码 sn-p 都可能会有所帮助。

【问题讨论】:

  • 到目前为止你尝试过什么?我怀疑 SO 上的任何人都愿意为你做这个项目。他们可能只会帮助您完成迄今为止的尝试。
  • @Jimenemex 请看问题,我更新了吗?

标签: java video merge concatenation


【解决方案1】:

大多数编解码器也不支持串联 - 它不会帮助您将比特流串联在一起。

但是,如果您确定编解码器具有相同的属性,则某些容器格式支持串联。 MPEG-TS 就是其中之一。您可以将视频复制到传输流中而无需重新编码,然后使用正常的文件操作连接传输流。

【讨论】:

  • 你有没有其他库可以在java中将两个视频一个接一个地组合成一个视频
  • 如我所说,将其转换为传输流,然后将传输流连接在一起。
  • @ANUJSINGH 参考 ffmpeg 检查我的回答。
【解决方案2】:

我无法为现有文件打开多路复用器并附加到它,但可以创建一个新的多路复用器并将来自多个多路分离器的数据写入其中。要做的另一件事是移动数据包的 dts/pts,以便它们在生成的文件中递增。

下面是一个工作代码 sn-p 将多个 avi 连接成一个(假设所有源文件中的编解码器、时基等相同):

private static void merge(File aggregate, Collection<File> segments) throws InterruptedException, IOException {

    Muxer muxer = Muxer.make(aggregate.toString(), null, "avi");

    final MediaPacket packet = MediaPacket.make();
    long dts_offset = 0;
    long pts_offset = 0;

    for (File segment : segments) {
        Demuxer demuxer = Demuxer.make();
        demuxer.open(segment.toString(), null, false, true, null, null);
        if (muxer.getState() == State.STATE_INITED) {
            int numStreams = demuxer.getNumStreams();
            for (int s = 0; s < numStreams; s++) {
                DemuxerStream demuxerStream = demuxer.getStream(s);
                Decoder decoder = demuxerStream.getDecoder();
                muxer.addNewStream(decoder);
            }
            muxer.open(null, null);
        }
        long dts_max = 0;
        long pts_max = 0;
        while (demuxer.read(packet) >= 0) {
            if (packet.isComplete()) {
                packet.setDts(packet.getDts() + dts_offset);
                packet.setPts(packet.getPts() + pts_offset);
                dts_max = packet.getDts() + 1;
                pts_max = packet.getPts() + 1;

                muxer.write(packet, false);
            }
        }
        dts_offset = dts_max;
        pts_offset = pts_max;
        demuxer.close();
    }   
    muxer.close();
}

【讨论】:

    【解决方案3】:

    对视频数据的任何操作通常已经在 ffmpeg 及其库中实现。虽然这不是 Java 代码库,但它为您提供了有关如何进行常见视频数据转换(例如连接视频数据)的开源参考。

    您可能想查看here 以了解 ffmpeg 实现了什么。

    话虽如此,您可能想要考虑不实现 ffmpeg 中已经可用、经过验证和测试的东西。如果 Java 代码库跨架构的可移植性不是主要问题,最好从 Java 代码库中调用 ffmpeg 的库来执行需要执行的复杂视频任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 2013-06-15
      • 2018-12-27
      相关资源
      最近更新 更多