ffmpeg 写入 mp4,编码时出现字幕错误

问题描述 投票:0回答:1

我正在努力编写尝试编写带有嵌入字幕的 mp4 视频文件的代码。

我成功编写了 h264 帧,但是当我尝试向该文件添加字幕时,我在 avcodec_encode_subtitle 上遇到错误。

我也尝试使用 rect->type = SUBTITLE_TEXT,但我收到此错误:

[mov_text @ 0000000006df0040] Only SUBTITLE_ASS type supported.

这是实现:

AVSubtitle subtitle;
memset(&subtitle, 0, sizeof(AVSubtitle));

subtitle.format = 1;
subtitle.num_rects = 1;
subtitle.rects = (AVSubtitleRect**)av_mallocz(sizeof(AVSubtitleRect*));
subtitle.rects[0] = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect));
AVSubtitleRect* rect = subtitle.rects[0];
int buf_size = 65536;
char* text = "Test subtitles";
rect->type = SUBTITLE_ASS; //dà errore
rect->ass = av_strdup(text);
subtitle.start_display_time = 0;
subtitle.end_display_time = 0;
subtitle.pts = mp4h->av_pkt.pts;

uint8_t* buf = (uint8_t*)av_malloc(buf_size);
if (!buf) {
    trace_error("Could not allocate buffer");
    return -1;
}

int encoded_size = avcodec_encode_subtitle(subtitleCtx, buf, buf_size, &subtitle);
if (encoded_size < 0) {
    char strE[256];
    av_strerror(encoded_size, strE, sizeof(strE));
    trace_error("Failed to encode subtitle with error: %s", strE);
}
else
{
    AVPacket* pkt = av_packet_alloc();
    if (av_packet_from_data(pkt, buf, encoded_size) < 0) {
        av_free(buf);
        av_packet_free(&pkt);
        trace_error("Error setting packet data");
    }
    else
    {
        pkt->stream_index = subtitleStream->index;
        pkt->pts = av_rescale_q(subtitle.pts, subtitleCtx->time_base, subtitleStream->time_base);

        pkt->pts = pkt->pts;
        pkt->dts = pkt->dts;
        pkt->duration = 0;

        ret = av_interleaved_write_frame(av_fmt_ctx_out, pkt);
        if (ret != 0) {
            char strE[256];
            av_strerror(ret, strE, sizeof(strE));
            trace_error("av_interleaved_write_frame returns %d - %s", ret, strE);
        }
    }
}

我在

avcodec_encode_subtitle
(ret = -12) 上遇到错误,但我不知道如何修复它。

subtitleCtx是这样初始化的:

enum AVCodecID id = AV_CODEC_ID_MOV_TEXT;
subtitleCodec = avcodec_find_encoder(id);
if (subtitleCodec)
{
    subtitleStream = avformat_new_stream(av_fmt_ctx_out, subtitleCodec);
    subtitleCtx = avcodec_alloc_context3(subtitleCodec);
    if (subtitleCtx == NULL) {
        eth_trace_error("avcodec_alloc_context3 failed");
        goto FnExit;
    }
    if (subtitleCtx)
    {
        subtitleCtx->codec_id = id;
        subtitleCtx->codec_type = AVMEDIA_TYPE_SUBTITLE;
        subtitleCtx->width = par.width;
        subtitleCtx->height = par.height;
        subtitleCtx->framerate = av_make_q(1000, 1);
        subtitleCtx->time_base = av_make_q(1, 1000);
    }

    subtitleStream->id = 1;
    subtitleStream->codecpar->codec_id = id;
    subtitleStream->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
    subtitleStream->codecpar->width = par.width;
    subtitleStream->codecpar->height = par.height;
    subtitleStream->time_base = av_make_q(1, 1000);
    subtitleStream->avg_frame_rate = av_make_q(1000, 1);

    if (av_fmt_ctx_out->oformat->flags & AVFMT_GLOBALHEADER)
        subtitleCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

if (avformat_write_header(mp4h->av_fmt_ctx_out, &mp4h->dict) < 0) {
    trace_error("Fail to write the header of output file");
}

有人可以帮我解决这个问题吗?

c++ ffmpeg mp4
1个回答
0
投票
当遇到

avcodec_

 错误时,
-12
函数返回
AVERROR_INVALIDDATA
值。因此,您不使用
AV_CODEC_ID_ASS
打开
libass
副标题的上下文,而是使用
AV_CODEC_ID_MOV_TEXT
标识符。
mov_text
编解码器似乎与您提供给它的图形字幕格式不兼容。

© www.soinside.com 2019 - 2024. All rights reserved.