关于go:SkeyeExPlayerWindows开发系列之解决分片录像时间戳不正常的问题

4次阅读

共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。

本篇文章基于上一篇 SkeyeExPlayer(Windows) 开发系列之采纳 ffmpeg 进行录像进行补充,测试发现录像的切片除了第一个工夫戳是失常的,其余的初始工夫戳均不失常而且是之前切片的工夫长度的总和;更有甚者很长一段时间的录像都是黑屏无奈播放的,为了解决这个问题,咱们须要将工夫戳进行修改。

通过剖析,初始工夫戳是 ffmpeg 读取网络流自带的工夫戳,在过程中读取流进行录像,那么势必初始的工夫戳须要进行减掉,执行过程如下:

  1. 首先,申请几个变量用以记录每次开始录像时的开始音视频工夫戳,以及音视频是否进行从新录像标记:
    int64_t audio_start_pts = -1;
    int64_t audio_start_dts = -1;
    int64_t video_start_pts = -1;
    int64_t video_start_dts = -1;

    bool audio_re_record = false;
    bool video_re_record = false;

2. 当达到切片条件时,置从新开启标记为 1,并记录以后帧的工夫戳为了下一个切片的开始工夫戳:

            if (play->record_duration > 0 && fRecTime > play->record_duration && i_pkt.flags == AV_PKT_FLAG_KEY)
            {
                audio_re_record = true;
                video_re_record = true;
            }

这里做了个简略的解决,也就是当以视频为工夫戳检测规范时,须要要在关键帧到来时进行判断,从而保障下一个切片的开始是以关键帧开始的。
3. 当从新录像标记为真的时候,则重置开始工夫戳,从而在下一次切片时保障工夫戳是从 0 开始的;

        if (in_stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)// 不反对的视频 过滤
        {if (video_start_pts < 0)
                video_start_pts = i_pkt.pts;
            if (video_start_dts < 0)
                video_start_dts = i_pkt.dts;

            if (video_re_record)
            {
                video_start_pts = i_pkt.pts;
                video_start_dts = i_pkt.dts;
                video_re_record = false;
            }
            i_pkt.pts = i_pkt.pts - video_start_pts;
            i_pkt.dts = i_pkt.dts - video_start_dts;
        }

        if (in_stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)// 不反对的音频 过滤
        {if (audio_start_pts < 0)
                audio_start_pts = i_pkt.pts;
            if (audio_start_dts < 0)
                audio_start_dts = i_pkt.dts;
            if (audio_re_record)
            {
                audio_start_pts = i_pkt.pts;
                audio_start_dts = i_pkt.dts;
                audio_re_record = false;
            }
            i_pkt.pts = i_pkt.pts - audio_start_pts;
            i_pkt.dts = i_pkt.dts - audio_start_dts;
        }

为了保障录像的胜利,须要把小于 0 的工夫戳置为 0:

        i_pkt.pts = (i_pkt.pts > 0) ? i_pkt.pts : 0;
        i_pkt.dts = (i_pkt.dts > 0) ? i_pkt.dts : 0;
        i_pkt.duration = (i_pkt.duration > 0) ? i_pkt.duration : 0;
正文完
 0