gpt4 book ai didi

c++ - ffmpeg和代码生成的碎片化mp4文件的区别

转载 作者:行者123 更新时间:2023-12-03 17:16:46 25 4
gpt4 key购买 nike

目前我在使用 libavformat 从代码生成碎片 MP4 文件时遇到问题。我的文件可以使用 VLC 播放,但不能在(Chrome)浏览器中流式传输(通过 WebSocket)和播放(通过 MediaSource)。 (我使用 this 测试通过 WebSocket 将分段的 MP4 文件流式传输到浏览器)。

注意:以下文件由 Baseline profile 4 级编码。因此您应该将 MIME 类型(在 index.html 中)更改为 const mimeCodec = 'video/mp4;编解码器="avc1.42C028"';能够播放它们。

我查了一下,发现我生成的Mp4文件和使用ffmpeg生成的文件有点不同。工具。

这是我所做的:

我有一个 .h264 file

  • 第一种方法,我使用 ffmpeg 生成 fragmented MP4 file .
    ffmpeg -i temp.h264 -vcodec copy -f mp4 -movflags empty_moov+default_base_moof+frag_keyframe ffmpeg.mp4

    生成的文件可以被Quicktime播放器和VLC播放器播放
  • 第二种方法,我以编程方式生成 fragmented Mp4 file by using libavformat

    首先我初始化上下文,codec代码中是 AVCodecContext*输入流的
     av_register_all();
    avcodec_register_all();
    int ret;
    AVOutputFormat* fmt = av_guess_format("mp4", 0, 0);
    if(!fmt) {
    return;
    }

    AVFormatContext* ctx = avformat_alloc_context();
    // Create AVIO context to capture generated Mp4 contain
    uint8_t *avio_ctx_buffer = NULL;
    size_t avio_ctx_buffer_size = 50000;
    IOOutput buffer = {};
    const size_t bd_buf_size = 50000;
    avio_ctx_buffer = (uint8_t*)av_malloc(avio_ctx_buffer_size);
    buffer.buff = (uint8_t*)av_malloc(bd_buf_size);

    buffer.size = bd_buf_size;
    AVIOContext* ioCtx = avio_alloc_context(avio_ctx_buffer, (int)avio_ctx_buffer_size, 1, &buffer, NULL, MP4Formatter::onWritePacket, NULL);

    ctx->oformat = fmt;
    if (ctx->oformat->flags & AVFMT_GLOBALHEADER)
    ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
    ctx->pb = ioCtx;
    av_opt_set(ctx, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);

    AVStream* st = avformat_new_stream(ctx, codec->codec);
    if (!st) {
    return;
    }

    st->id = (ctx->nb_streams - 1);
    avcodec_parameters_from_context(st->codecpar, codec);
    st->time_base = codec->time_base;
    ioCtx->seekable = false;

    其次我实现了 onWritePacket 回调
     int MP4Formatter::onWritePacket(void *opaque, uint8_t* buf, int buf_size) {
    file.write((char*)buf, buf_size);
    }

    第三,在来自 h264 文件的每个数据包上,我使用 av_interleaved_write_frame 编写它
     if (firstFrame) {
    AVDictionary *opts = NULL;
    av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
    if(!parseSPSPPS(data, length)) {
    return;
    }
    cout << "spslen " << spslen << " ppslen " << ppslen << endl;
    auto c = st->codecpar;
    // Extradata contains PPS & SPS for AVCC format
    int extradata_len = 8 + spslen + 1 + 2 + ppslen;
    c->extradata = (uint8_t*)av_mallocz(extradata_len);
    c->extradata_size = extradata_len;
    c->extradata[0] = 0x01;
    c->extradata[1] = sps[1];
    c->extradata[2] = sps[2];
    c->extradata[3] = sps[3];
    c->extradata[4] = 0xFC | 3;
    c->extradata[5] = 0xE0 | 1;
    int tmp = spslen;
    c->extradata[6] = (tmp >> 8) & 0x00ff;
    c->extradata[7] = tmp & 0x00ff;
    int i = 0;
    for (i=0; i<tmp; i++) {
    c->extradata[8 + i] = sps[i];
    }
    c->extradata[8 + tmp] = 0x01;
    int tmp2 = ppslen;
    c->extradata[8 + tmp + 1] = (tmp2 >> 8) & 0x00ff;
    c->extradata[8 + tmp + 2] = tmp2 & 0x00ff;
    for (i=0; i<tmp2; i++) {
    c->extradata[8 + tmp + 3 + i] = pps[i];
    }
    int ret = avformat_write_header(ctx, &opts);
    if(ret < 0) {
    return;
    }
    firstFrame = false;
    }
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.buf = av_buffer_alloc(length);
    memcpy(pkt.buf->data, data, length);
    pkt.buf->size = length;
    pkt.data = pkt.buf->data;
    pkt.size = pkt.buf->size;
    pkt.pts = ts;
    pkt.dts = ts;

    if (keyFrame) {
    pkt.flags |= AV_PKT_FLAG_KEY;
    }
    else {
    pkt.flags = 0;
    }

    pkt.stream_index = st->id;

    av_interleaved_write_frame(ctx, &pkt);
    av_buffer_unref(&pkt.buf);
    av_packet_unref(&pkt);

  • 你们可以看看我的文件,看看有什么问题吗?

    最佳答案

    也许你可以试试这个:

    AVDictionary* opts = NULL;
    av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0);
    接着:
    avformat_write_header(formatContext, &opts);
    作为这个问题
    How to generate fragmented mp4 files programmatically

    关于c++ - ffmpeg和代码生成的碎片化mp4文件的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42430809/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com