使用libav转换mp4-ts

我正在尝试使用libav将mp4文件转换为mpegts。 代码有效,但输出的文件无法由任何播放器播放。

这是输入文件 (它只是video,没有音频)

这是我到目前为止的代码:

int convert(const char *input, const char *output) { AVFormatContext *inputContext = NULL; AVFormatContext *outputContext = NULL; AVCodecContext *input_codec_context = NULL; AVCodecContext *output_codec_context = NULL; AVCodec *output_codec = NULL; AVCodec *input_codec = NULL; AVStream *stream = NULL; AVIOContext *avioContext = NULL; av_register_all(); avformat_network_init(); avformat_alloc_output_context2(&outputContext, NULL, "mpegts", output); avio_open(&avioContext, output, AVIO_FLAG_WRITE); outputContext->pb = avioContext; stream = avformat_new_stream(outputContext, output_codec); avformat_open_input(&inputContext, input, NULL, NULL); input_codec_context = inputContext->streams[0]->codec; input_codec = avcodec_find_decoder(inputContext->streams[0]->codec->codec_id); avcodec_open2(inputContext->streams[0]->codec, input_codec, NULL); avformat_find_stream_info(inputContext, NULL); outputContext->oformat = av_guess_format(NULL, output, NULL); output_codec = input_codec; output_codec_context = avcodec_alloc_context3(NULL); avcodec_copy_context(output_codec_context, input_codec_context); avcodec_open2(output_codec_context, output_codec, NULL); AVPacket packet; av_init_packet(&packet); avformat_write_header(outputContext, NULL); while (!av_read_frame(inputContext, &packet)) { av_write_frame(outputContext, &packet); } av_free_packet(&packet); av_write_trailer(outputContext); avformat_close_input(&inputContext); avformat_free_context(inputContext); avformat_free_context(outputContext); return 0; } 

任何帮助赞赏。

mp4mpegts为h264采用不同的比特流格式。

您需要插入h264_mp4toannexb来重新格式化您正在获取的AVPacket。

分配上下文

  AVBitStreamFilterContext *bsf = av_bitstream_filter_init("h264_mp4toannexb"); 

在你的demux循环中

  AVPacket new_pkt = *pkt; int ret = av_bitstream_filter_filter(bsfc, avctx, NULL, &new_pkt.data, &new_pkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY); if (ret > 0) { // non-zero positive, you have new memory allocated, // keep it referenced in the AVBuffer av_free_packet(pkt); new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, av_buffer_default_free, NULL, 0); // handle memory error here } else if (ret < 0) { // handle failure here } // ret == 0, no problems, nothing else to do *pkt = new_pkt;