ffmpeg生成HLS(M3U8)非定长切片(提高用户观影体验)

       在视频点播中,M3U8已经广为使用,为了节省用户观看视频前期的等待时间,我们一般将M3U8中前面2~3个切片使用较短的切片时间,这样用户可以更快的完成下载,提高用户体验。本文即介绍如何修改ffmpeg支持非定长的M3U8文件切片。


通过ffmpeg可以轻松实现对文件的M3U8切片,命令如下:

<pre name="code" class="cpp"> ./ffmpeg -i 1939211.ts -y -vcodec copy -acodec copy -map 0 -f segment -segment_list 1939211.m3u8   -segment_time 10 1939211-%03d.ts
 
 


使用-segment_time指定了每片的时长为10秒(实际会受视频中IDR帧的间隔影响)


怎样实现前2片时间为5秒呢?


修改ffmpeg源码方能实现,具体为:

/ffmpeg/libavformat/segment.c中

static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)函数

修改指定区域代码如下:

        if (seg->use_clocktime) {
            int64_t avgt = av_gettime();
            time_t sec = avgt / 1000000;
            localtime_r(&sec, &ti);
            usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
            wrapped_val = usecs % seg->time;
            if (seg->last_cut != usecs && wrapped_val < seg->last_val) {
                seg->cut_pending = 1;
                seg->last_cut = usecs;
            }
            seg->last_val = wrapped_val;
        } else {
	    //modify start
	    //前面两个片使用5秒
	    int64_t t;
            int ret = 0;
            ret = av_parse_time(&t, "5", 1);
            if (ret >= 0)
            {
               if((seg->segment_count == 0) || (seg->segment_count == 1))
               {
                   end_pts = t * (seg->segment_count + 1);

               }
               else
               {

                   end_pts = t*2 +  seg->time * (seg->segment_count - 1);
               }
            }
            else
            {
               av_log(s, AV_LOG_ERROR, "av_parse_time failed  file:%s, line:%d!\n", __FILE__, __LINE__);

               end_pts = seg->time * (seg->segment_count + 1);
            }
	    //modify end
        }

这里写死了前面2片长度为5秒,为了使用灵活建议新增专用的ffmpeg参数。


发布了9 篇原创文章 · 获赞 15 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/mediapro/article/details/50395888