前言
最近在開發(fā)中發(fā)現(xiàn)一部分m3u8文件在播放時無法快進糜芳,并且在播放時播放一段時間后時間會重置為0魄衅,經(jīng)過一通分析后發(fā)現(xiàn)這部分m3u8文件中有#EXT-X-DISCONTINUITY這個標簽,ffmpeg目前對這個標簽是不支持的邪驮,ijkplayer是支持的傲茄,但是ijkplayer沒有添加帶這個標簽的視頻seek的處理盘榨,會造成當前的分片視頻可以seek,但是直接跳到后面的分片視頻會無法seek草巡,#EXT-X-DISCONTINUITY標簽后面的視頻的pts和標簽之前的視頻是不連續(xù)的,而ffmpeg在seek時弥喉,會去將要seek的timestamp與當前包的pts區(qū)間進行對比由境,來查看查找的是否是當前包,但由于pts不連續(xù)的問題虏杰,會導致seek的timestamp總是大于包的pts區(qū)間纺阔,所以到會導致一直卡著修然,無法播放,后面在ijkplayer的issue中找到處理方法。
處理過程
首先在hls.c文件里添加一個函數(shù)拯杠,用于查找當前packet之前的視頻的總時長潭陪,用于得出正確的pts:
static int find_timestamp_in_seq_no( struct playlist *pls,int64_t *timestamp, int seq_no)
{
int i;
*timestamp=0;
for (i = 0; i < seq_no; i++) {
*timestamp += pls->segments[i]->duration ;
}
return 0;
}
修改hls_read_packet函數(shù)
1.聲明變量
int64_t timestamp = AV_NOPTS_VALUE;
2.調(diào)用find_timestamp_in_seq_no函數(shù)
for (i = 0; i < c->n_playlists; i++) {
struct playlist *pls = c->playlists[i];
find_timestamp_in_seq_no(pls,×tamp,pls->cur_seq_no);//add
/* Make sure we've got one buffered packet from each open playlist
* stream */
if (pls->needed && !pls->pkt.data) {
....
}
3.最后在計算seek的timestamp是否在當前packet的區(qū)間的代碼上加上這個時長
ts_diff = timestamp + av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
tb.den, AV_ROUND_DOWN) -
pls->seek_timestamp;//edit
if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY ||
pls->pkt.flags & AV_PKT_FLAG_KEY)) {
pls->seek_timestamp = AV_NOPTS_VALUE;
break;
}
結語
目前測試是沒問題的老厌,但是在issue中有人反饋出現(xiàn)崩潰情況黎炉,后續(xù)會跟進。