我正在努力编写尝试编写带有嵌入字幕的 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");
}
有人可以帮我解决这个问题吗?
avcodec_
错误时,
-12
函数返回 AVERROR_INVALIDDATA
值。因此,您不使用 AV_CODEC_ID_ASS
打开 libass
副标题的上下文,而是使用 AV_CODEC_ID_MOV_TEXT
标识符。 mov_text
编解码器似乎与您提供给它的图形字幕格式不兼容。