ffmpeg本地TS和M3U8播放流程及调试过程

本地TS播放过程

本地M3U8播放过程

http工作流程

http分两个步骤

1、获取m3u8文件,这个是在哪里开始读的?

2、获取data数据,这个是从http_read开始读,可以通过修改这里实现buffer数据和引擎对接

3、s->user_agent,s->off,s->end_off,s->seekable这些是什么时候赋值的?

从 http_get_line获取到

4、需要修改的几个地方

1)http_get_line->ffurl_read

获取header

这个就模拟,主要是拿到长度

2)http_buf_read->ffurl_read

获取真正数据

调试过程

1、demo测试

通过URL传m3u8索引文件夹,真正TS数据通过读取本地文件来获取

修改:

http_buf_read

即可

2、m3u8通过buffer方式获取

先拿到m3u8数据

hls以及能解析得到playlist,但是获取第一个block数据后还会去获取m3u8的数据,也就是之前的m3u8的connect还没断开

通过log看到header少了Connection: close,以及一个回车,通过添加Connection: close解决了m3u8会多次连接的问题,但会出现

导致这个原因是因为读完第一个block后,没继续读下个block?

去掉之前私有协议的seek逻辑,在ijk_mediasource_readAt函数里去掉if (pointer_pos != position )

这么修改后,能播放了,看到希望咯

3、播放10左右,就把索引表的所有TS读完了,啥情况?

是因为ffurl_read有阻塞?而ijk_mediasource_readAt没有阻塞?

下面分析ffurl_read

int ffurl_read(URLContext *h, unsigned char *buf, int size)
{
    if (!(h->flags & AVIO_FLAG_READ))
        return AVERROR(EIO);
    return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read);
}

ffurl_read() -> retry_transfer_wrapper()

static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
                                         int size, int size_min,
                                         int (*transfer_func)(URLContext *h,
                                                              uint8_t *buf,
                                                              int size))
{
    int ret, len;
    int fast_retries = 5;
    int64_t wait_since = 0;

    len = 0;
    while (len < size_min) {//如果len小于size_min,则循环,这里size_min=1
        if (ff_check_interrupt(&h->interrupt_callback))//检查是否结束
            return AVERROR_EXIT;
        ret = transfer_func(h, buf + len, size - len);//拉取数据
        if (ret == AVERROR(EINTR))//出错,继续
            continue;
        if (h->flags & AVIO_FLAG_NONBLOCK)
            return ret;
        if (ret == AVERROR(EAGAIN)) {//从新再来
            ret = 0;
            if (fast_retries) {//初始值5,尝试5次,5次后
                fast_retries--;
            } else {//睡眠方式尝试
                if (h->rw_timeout) {
                    if (!wait_since)
                        wait_since = av_gettime_relative();
                    else if (av_gettime_relative() > wait_since + h->rw_timeout)
                        return AVERROR(EIO);
                }
                av_usleep(1000);//开始睡眠1000us
            }
        } else if (ret < 1)
            return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
        if (ret) {
            fast_retries = FFMAX(fast_retries, 2);
            wait_since = 0;
        }
        len += ret;
    }
    return len;
}
相关推荐
Fre丸子_8 小时前
ffmpeg之播放一个yuv视频
ffmpeg·音视频
yinqinggong11 小时前
从源码编译支持FFmpeg的OpenCV
opencv·ffmpeg
冰山一脚201312 小时前
ffmpeg添加sps,pps
ffmpeg
嘟嘟实验室1 天前
微信小程序xr-frame透明视频实现
微信小程序·ffmpeg·音视频·xr
泰勒朗斯2 天前
如何编译Opencv +ffmpeg linux 明明安装了ffmpeg但是opencv就是找不到
linux·opencv·ffmpeg
-Mr_X-2 天前
windows下srs流媒体服务器使用ffmpeg推流
ffmpeg
dvlinker2 天前
C++开源项目 VLC 源代码的交叉编译以及库的裁剪方法详解
ffmpeg·mingw-w64·msys2·cygwin·开源vlc·vlc编译·vlc裁剪
因我你好久不见2 天前
springboot java ffmpeg 视频压缩、提取视频帧图片、获取视频分辨率
java·spring boot·ffmpeg
cuijiecheng20183 天前
音视频入门基础:MPEG2-TS专题(21)——FFmpeg源码中,获取TS流的视频信息的实现
ffmpeg·音视频
cuijiecheng20183 天前
音视频入门基础:AAC专题(13)——FFmpeg源码中,获取ADTS格式的AAC裸流音频信息的实现
ffmpeg·音视频·aac