如何使视频正确循环播放?

时间:2019-05-26 04:42:15

标签: video ffmpeg

我想循环播放https://www.nicovideo.jp/watch/sm16617386的视频。我想以这种方式播放mp4文件,以便每当它到达视频中的某个点(例如30.3秒)时,它将循环播放(例如5.85秒)。

我试图在ffplay.c中添加此代码,但效果不佳,我可以听到转换的声音。我想搜索的速度不够快,或者音频需要以某种独立的方式循环播放。

static void video_refresh(void *opaque, double *remaining_time)
{
   (original code here...)
    time = get_master_clock(is);
    if (isnan(time))
        time = (double)is->seek_pos / AV_TIME_BASE;
    if (time > jump_when) {
        stream_seek(is, (int64_t)(6.0 * AV_TIME_BASE), (int64_t)(0.0 * AV_TIME_BASE), 0);
    }
}

我目前的计划是深入研究ffmpeg,了解视频和音频解码器的工作原理,并保存解码器的状态/负载状态。

1 个答案:

答案 0 :(得分:1)

  
      
  • ”“我想以这种方式播放mp4文件,以便每当到达视频中的某个点(例如:30.3秒)时,它将循环回到更早的时间(例如:5.85)秒)。”

  •   
  • “我能听到转换的声音。我想搜索不够快,或者音频需要以某种独立的方式循环播放。”

  •   

您链接的视频每2秒钟具有一个关键帧(精确地为2.023)。 因此,您只能选择2.023、4.023、6.023、8.023等秒。

如果需要5.850秒,则需要首先在4秒钟处搜索关键帧,然后解码下一个下一帧,直到所需的时间戳为5.850。此时,您可以显示视频。

我过去使用的解决方案是简单地将P / B帧的时间戳( PTS )调整为与关键帧相同,然后再将其字节提供给H264解码器。 (通过这种方式,解码器被迫在视频中快进以保持同步)。我仅在命令行中使用了FFmpeg,所以不确定如何在显示的代码中更改显示时间。

为什么?
在MPEG压缩中,您只能搜索关键帧。每个音频帧都是关键帧,但是视频具有3种类型的帧:I(是关键帧或完整图片),还有PB帧(它们只有很小的帧)与主要图片的差异)。这些P / B帧需要先最近个关键帧进行解码,然后首先解码,因此它们也要显示像素数据。 P / B帧不能仅靠自身解码(因为它们不是完整的图像数据)。