You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Base64字节数据转为AVSubtitle并编码封装进MPEG-TS?

问题描述

我需要将Base64编码后的字节数据封装到MPEG-TS容器中,但找不到将这些数据编码为AVPacket的方法。使用avcodec_encode_subtitle需要构造包含有效数据的AVSubtitle,但不知道如何用自有数据创建/分配AVSubtitle。

更新:尝试实现后报错

我在Kotlin(项目为KMP)中编写了一段实现代码,但编码时出现Invalid data found when processing input错误,代码如下:

val data = AVSubtitleRect()
data.type(SUBTITLE_ASS)
data.ass(BytePointer(buffer))
val subtitle = AVSubtitle()
val pointerPointer = PointerPointer<AVSubtitleRect>(1)
pointerPointer.put(data)
subtitle.rects(pointerPointer)
subtitle.pts(packet.pts())

val bufferSize = 1024 * 1024
val encodedBuffer = BytePointer(av_malloc(bufferSize.toLong()))

val result = avcodec_encode_subtitle(subtitleContext, encodedBuffer, bufferSize, subtitle)

if (result >= 0) {
    val outSubtitlePacket = AVPacket()
    outSubtitlePacket.apply {
        data(encodedBuffer)
        outSubtitlePacket.size(result)
        outSubtitlePacket.stream_index(subtitleStreamIndex)
        duration(packet.duration())
        dts(packet.dts())
        pts(packet.pts())
        pos(packet.pos())
    }

    av_interleaved_write_frame(avOutputCtx, outSubtitlePacket)

    av_packet_unref(outSubtitlePacket)
    av_free(encodedBuffer)
}

对应的C语言等效代码:

// Allocate the subtitle rect
AVSubtitleRect *data = av_mallocz(sizeof(AVSubtitleRect));
if (!data) {
    fprintf(stderr, "Could not allocate AVSubtitleRect.\n");
    return AVERROR(ENOMEM);
}
data->type = SUBTITLE_ASS;
data->ass = av_strdup(buffer);
if (!data->ass) {
    fprintf(stderr, "Could not allocate ASS buffer.\n");
    av_free(data);
    return AVERROR(ENOMEM);
}

// Allocate the subtitle
AVSubtitle subtitle;
memset(&subtitle, 0, sizeof(subtitle));
subtitle.rects = av_mallocz(sizeof(*subtitle.rects));
if (!subtitle.rects) {
    fprintf(stderr, "Could not allocate AVSubtitle rects.\n");
    av_free(data->ass);
    av_free(data);
    return AVERROR(ENOMEM);
}
subtitle.rects[0] = data;
subtitle.num_rects = 1;
subtitle.pts = packet->pts;

// Allocate buffer for encoded subtitle
int bufferSize = 1024 * 1024;
uint8_t *encodedBuffer = av_malloc(bufferSize);
if (!encodedBuffer) {
    fprintf(stderr, "Could not allocate buffer for encoded subtitle.\n");
    av_free(subtitle.rects);
    av_free(data->ass);
    av_free(data);
    return AVERROR(ENOMEM);
}

// Encode the subtitle
int result = avcodec_encode_subtitle(subtitleContext, encodedBuffer, bufferSize, &subtitle);
if (result >= 0) {
    // Create the output subtitle packet
    AVPacket outSubtitlePacket;
    av_init_packet(&outSubtitlePacket);
    outSubtitlePacket.data = encodedBuffer;
    outSubtitlePacket.size = result;
    outSubtitlePacket.stream_index = subtitleStreamIndex;
    outSubtitlePacket.duration = packet->duration;
    outSubtitlePacket.dts = packet->dts;
    outSubtitlePacket.pts = packet->pts;
    outSubtitlePacket.pos = packet->pos;

    // Write the subtitle packet
    result = av_interleaved_write_frame(avOutputCtx, &outSubtitlePacket);
    if (result < 0) {
        fprintf(stderr, "Error while writing subtitle packet: %s\n", av_err2str(result));
    }

    av_packet_unref(&outSubtitlePacket);
    av_free(encodedBuffer);
} else {
    fprintf(stderr, "Failed to encode subtitles. Reason: %s\n", av_err2str(result));
    av_free(encodedBuffer);
}

av_free(subtitle.rects);
av_free(data->ass);
av_free(data);

内容的提问来源于stack exchange,提问作者Алексей Красноноженко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:55:02