【问题标题】:FFmpeg HLS select streams and only retrieve their dataFFmpeg HLS 选择流并仅检索其数据
【发布时间】:2020-11-28 02:39:15
【问题描述】:

使用avformat_open_input 打开 HLS 流会从所有流中检索数据,我只想从其中一些流中检索数据。这可能吗?

考虑以下 MWE:

#include <libavformat/avformat.h>
int main(int argc, char **argv)
{
    AVFormatContext *inFmtCtx = NULL;
    AVPacket packet;
    const char *inUrl;
    int ret;

    if (argc < 2) { return -1; }
    inUrl = argv[1];

    if ((ret = avformat_open_input(&inFmtCtx, inUrl, NULL, NULL)) < 0)
        goto end;
    if ((ret = avformat_find_stream_info(inFmtCtx, NULL)) < 0)
        goto end;

    while (1) {
        ret = av_read_frame(inFmtCtx, &packet);
        if (ret < 0) break;

        // # Placeholder: Do Something # //
        printf("%i, ", packet.stream_index);

        av_packet_unref(&packet);
    }
end:
    avformat_close_input(&inFmtCtx);
    if (ret < 0 && ret != AVERROR_EOF) {
        fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
        return 1;
    }
    return 0;
}

使用示例 HLS url “http://mcdn.daserste.de/daserste/de/master.m3u8”(可能是地理锁定的),printf 返回的值介于 09 之间,表示检索所有 10 个流(5 个视频,5 个音频)。

当然,除了选定的内容之外,其他所有内容都可以在被读取后丢弃,例如使用

    if(packet.stream_index != selectedVideoStreamId && packet.stream_index != selectedAudioStreamId) {
        av_packet_unref(&packet);
        continue;
    }

但是可以将输入上下文/ffmpeg 配置为仅检索选定的流,即不下载所有不需要的数据(未选择的流)吗?

【问题讨论】:

    标签: ffmpeg http-live-streaming libavformat


    【解决方案1】:

    您可以通过丢弃属于它的所有流来禁用 HLS 变体:

    if ((ret = avformat_open_input(&inFmtCtx, inUrl, NULL, NULL)) < 0)
        goto end;
    
    // disable all but the last stream
    for (i = 0; i < inFmtCtx->nb_streams - 1; ++i) {
        AVStream *st = inFmtCtx->streams[i];
        st->discard = AVDISCARD_ALL;
    }
    
    if ((ret = avformat_find_stream_info(inFmtCtx, NULL)) < 0)
        goto end;
    

    阅读您的信息流几秒钟会产生:

    stream=0 pkt_count=0
    stream=1 pkt_count=0
    stream=2 pkt_count=0
    stream=3 pkt_count=0
    stream=4 pkt_count=0
    stream=5 pkt_count=0
    stream=6 pkt_count=0
    stream=7 pkt_count=0
    stream=8 pkt_count=998
    stream=9 pkt_count=937
    

    如您所见,即使启用了单个流,它也会读取与最后一个播放列表中的多路复用音频/视频流相对应的两个流。如果您需要比这更好的粒度,则必须修改 HLS 解复用器。

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 2021-07-30
      • 1970-01-01
      相关资源
      最近更新 更多