【问题标题】:The start timestamp is non zero-when remuxing using libavformat使用 libavformat 重新混合时,开始时间戳不为零
【发布时间】:2020-03-22 08:49:00
【问题描述】:

我正在使用 libavformat 的示例 remuxing.c 重新混合实时 rtmp 流,我的代码几乎与该示例相同,但它还解码音频和视频以便使用 SDL 呈现预览,效果很好。

我的应用程序有一个开始录制的按钮,每当用户按下它时,主循环就会重新组合到一个文件中,在典型情况下,用户会在开始录制之前等待几秒钟,这就是问题所在出现,生成的视频具有非零开始时间。 (如果我在打开输入流后立即手动启动录制,我看不到这些问题)

例如 用户在开始录制前等待 5 秒,然后录制 5 秒:报告的持续时间约为 5 秒,而开始时间戳约为 9 秒。 VLC 无法正确显示持续时间/位置,但在其他播放器中运行良好。

这是我的主循环的一个例子

while (1) {
    ret = av_read_frame(ifmt_ctx, &pkt);

    //decode and preview
    //set pts, dts and duration
    //...

    if(ost->record){
        //remux
        ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
        if (ret < 0) {
            fprintf(stderr, "Error muxing packet\n");
            break;
        }
    }

    av_packet_unref(&pkt);
}

我试过设置输入流的mux_ts_offset,但是没有用。

【问题讨论】:

  • 可能与原始视频中使用的关键帧间隔有关(例如每 10 秒)。应该可以在开头插入新的关键帧并重新编码视频片段直到下一个关键帧(可能有更简单的方法,但这取决于实际使用的视频编解码器)。
  • 不确定是否相关,偏移量是相对于打开输入后经过的时间,例如,如果我运行应用程序并等待 5 分钟,则偏移量将为 5 分钟。

标签: ffmpeg sdl video-processing libavformat


【解决方案1】:

您获得的 tps 与您连接到流的时刻有关。当你开始记录你时,记住第一个数据包的 tps 和 dps,然后将所有内容都移动那个偏移量。

first_packet = true;
while (1) {
    ret = av_read_frame(ifmt_ctx, &pkt);

    //decode and preview
    //set pts, dts and duration
    //...

    if(ost->record){

        if (first_packet) { // memorize the tps and dps of the first recorded packet
            start_pts = pkt.pts;
            start_dts = pkt.dts;
            first_packet = false;
        }

        // apply offset
        pkt.pts = pkt.pts - start_pts;
        pkt.dts = pkt.dts - start_dts;

        //remux
        ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
        if (ret < 0) {
            fprintf(stderr, "Error muxing packet\n");
            break;
        }
    }

    av_packet_unref(&pkt);
}

【讨论】:

    猜你喜欢
    • 2018-12-10
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多