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;
}
相关推荐
七夜zippoe3 小时前
Spring Data JPA原理与实战 Repository接口的魔法揭秘
java·ffmpeg·事务·jpa·repository
Benny的老巢3 小时前
n8n工作流中FFmpeg 视频截取失败排查:文件路径和参数顺序错误解决方案
chrome·ffmpeg·音视频
RockWang.1 天前
【配置】FFmpeg配置环境ubuntu踩坑记录。
ffmpeg
王者鳜錸1 天前
Java使用FFmpeg获取音频文件时长:完整实现与原理详解
java·开发语言·ffmpeg·音频时长
桃杬1 天前
用现代 C++ 封装 FFmpeg:从摄像头采集到 H.264 编码的完整实践
c++·ffmpeg·h.264
cvcode_study2 天前
FFmpeg 工具基础
ffmpeg
1nv1s1ble2 天前
记录一个`ffmpeg`的`swscale`库crash的例子
ffmpeg
CodeOfCC2 天前
C++ 实现ffmpeg解析hls fmp4 EXT-X-DISCONTINUITY并支持定位
开发语言·c++·ffmpeg·音视频
Java程序员 拥抱ai2 天前
SpringBoot + FFmpeg + Redis:视频转码、截图、水印异步处理平台搭建
spring boot·redis·ffmpeg
给算法爸爸上香3 天前
yolo tensorrt视频流检测软解码和硬解码
yolo·ffmpeg·视频编解码·tensorrt·nvcodec