分享

使用FFmpeg将mp4转为ts(代码实现)

 mediatv 2015-11-04


 使用ffmpeg将mp4转为ts的命令格式如下:

点击(此处)折叠或打开

  1. ffmpeg -i b.mp4 -codec copy -bsf h264_mp4toannexb a.ts

如果不使用-bsf h264_mp4toannexb参数,会提示错误,错误信息如下:

点击(此处)折叠或打开

  1. ffmpeg -i b.mp4 -codec copy a.ts
  2. ffmpeg version N-65108-gf2855eb Copyright (c) 2000-2014 the FFmpeg developers
  3.   built on Jul 31 2014 02:29:27 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
  4.   configuration: --prefix=/usr/local --enable-gpl --enable-nonfree --enable-libfaac --enable-libfreetype --enable-libx264 --enable-libx265
  5.   libavutil 52. 93.100 / 52. 93.100
  6.   libavcodec 55. 71.100 / 55. 71.100
  7.   libavformat 55. 49.100 / 55. 49.100
  8.   libavdevice 55. 13.102 / 55. 13.102
  9.   libavfilter 4. 11.102 / 4. 11.102
  10.   libswscale 2. 6.100 / 2. 6.100
  11.   libswresample 0. 19.100 / 0. 19.100
  12.   libpostproc 52. 3.100 / 52. 3.100
  13. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'b.mp4':
  14.   Metadata:
  15.     major_brand : isom
  16.     minor_version : 512
  17.     compatible_brands: isomiso2avc1mp41
  18.     title : ????????
  19.     encoder : Lavf55.49.100
  20.     copyright : (C) 2004 HFD2B
  21.   Duration: 00:04:09.44, start: 0.000000, bitrate: 568 kb/s
  22.     Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 592x336, 436 kb/s, 23.98 fps, 23.98 tbr, 785647.00 tbn, 47.95 tbc (default)
  23.     Metadata:
  24.       handler_name : VideoHandler
  25.     Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
  26.     Metadata:
  27.       handler_name : SoundHandler
  28. File 'a.ts' already exists. Overwrite ? [y/N] y
  29. [adts @ 0x2269660] Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead.
  30. Output #0, mpegts, to 'a.ts':
  31.   Metadata:
  32.     major_brand : isom
  33.     minor_version : 512
  34.     compatible_brands: isomiso2avc1mp41
  35.     title : ????????
  36.     copyright : (C) 2004 HFD2B
  37.     encoder : Lavf55.49.100
  38.     Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 592x336, q=2-31, 436 kb/s, 23.98 fps, 90k tbn, 23.98 tbc (default)
  39.     Metadata:
  40.       handler_name : VideoHandler
  41.     Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, 127 kb/s (default)
  42.     Metadata:
  43.       handler_name : SoundHandler
  44. Stream mapping:
  45.   Stream #0:0 -> #0:0 (copy)
  46.   Stream #0:1 -> #0:1 (copy)
  47. Press [q] to stop, [?] for help
  48. [mpegts @ 0x22761a0] H.264 bitstream malformed, no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)
  49. av_interleaved_write_frame(): Invalid argument
  50. frame= 1 fps=0.0 q=-1.0 Lsize= 1kB time=00:00:00.04 bitrate= 216.3kbits/s
  51. video:1kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
  52. Conversion



从上面的提示纤细可以看到,提示了:
[mpegts @ 0x22761a0] H.264 bitstream malformed, no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)
av_interleaved_write_frame(): Invalid argument
主要是因为使用了mp4中的h264编码,而h264有两种封装:
一种是annexb模式,传统模式,有startcode,SPS和PPS是在ES中;另一种是mp4模式,一般mp4、mkv、avi会没有 startcode,SPS和PPS以及其它信息被封装在container中,每一个frame前面是这个frame的长度,很多解码器只支持 annexb这种模式,因此需要将mp4做转换;在ffmpeg中用h264_mp4toannexb_filter可以做转换;所以需要使用-bsf h264_mp4toannexb来进行转换;

下面介绍一下代码实现:
代码实现主要分为三个步骤:

点击(此处)折叠或打开

  1. 1. 初始化filterav_bitstream_filter_init
  2. 2. 使用filter转换av_bitstream_filter_filter
  3. 3. 关闭filter av_bitstream_filter_close

其他与正常的转封装相同

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libavformat/avformat.h>
  4. #include <libavutil/avutil.h>

  5. #define FORMAT "mpegts"
  6. #define OUTPUT_FILE "./fuck.ts"
  7. #define INPUT_FILE "./a.avi"

  8. int main(int argc, char *argv[])
  9. {
  10.     AVPacket pkt;
  11.     AVFormatContext *input_fmtctx = NULL;
  12.     AVFormatContext *output_fmtctx = NULL;
  13.     AVCodecContext *enc_ctx = NULL;
  14.     AVCodecContext *dec_ctx = NULL;
  15.     AVCodec *encoder = NULL;
  16.     AVBitStreamFilterContext * vbsf = NULL;
  17.     int ret = 0;
  18.     int i = 0;
  19.     int have_key = 0;
  20.     static int first_pkt = 1;

  21.     av_register_all();

  22.     if (avformat_open_input(&input_fmtctx, INPUT_FILE, NULL, NULL) < 0) {
  23.         av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s\n", "./a.mp4");
  24.         return -ENOENT;
  25.     }

  26.     if (avformat_find_stream_info(input_fmtctx,0) < 0) {
  27.         av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Failed to retrieve input stream information\n");
  28.         return -EINVAL;
  29.     }

  30.     av_dump_format(input_fmtctx, NULL, INPUT_FILE, 0);

  31.     if (avformat_alloc_output_context2(&output_fmtctx, NULL, FORMAT, OUTPUT_FILE) < 0) {
  32.         av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s bbs.chinaffmpeg.com 孙悟空\n", OUTPUT_FILE);
  33.         return -ENOENT;
  34.     }

  35.     /* Process transcode parameters */
  36.     for (i = 0; i < input_fmtctx->nb_streams; i++) {
  37.         AVStream *out_stream = NULL;
  38.         AVStream *in_stream = NULL;

  39.         in_stream = input_fmtctx->streams[i];
  40.         out_stream = avformat_new_stream(output_fmtctx, in_stream->codec->codec);
  41.         if (out_stream < 0) {
  42.             av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Alloc new Stream error\n");
  43.             return -EINVAL;
  44.         }

  45.         avcodec_copy_context(output_fmtctx->streams[i]->codec, input_fmtctx->streams[i]->codec);

  46.         out_stream->codec->codec_tag = 0;
  47.         if (output_fmtctx->oformat->flags & AVFMT_GLOBALHEADER) {
  48.             out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
  49.         }
  50.     }

  51.     vbsf = av_bitstream_filter_init("h264_mp4toannexb");


  52.     av_dump_format(output_fmtctx, NULL, OUTPUT_FILE, 1);

  53.     if (avio_open2(&output_fmtctx->pb, OUTPUT_FILE, AVIO_FLAG_WRITE, &output_fmtctx->interrupt_callback, NULL) < 0) {
  54.         av_log(NULL, AV_LOG_ERROR, "cannot open the output file '%s' bbs.chinaffmpeg.com 孙悟空\n", "./fuck.m3u8");
  55.         return -ENOENT;
  56.     }

  57.     av_opt_set(output_fmtctx->priv_data, "hls_time", "10");

  58.     if ((ret = avformat_write_header(output_fmtctx, NULL)) < 0) {
  59.         av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Cannot write the header for the file '%s' ret = %d\n", "fuck.ts", ret);
  60.         return -ENOENT;
  61.     }

  62.     while (1) {
  63.         AVStream *in_stream = NULL;
  64.         AVStream *out_stream = NULL;

  65.         ret = av_read_frame(input_fmtctx, &pkt);
  66.         if (ret < 0) {
  67.             av_log(NULL, AV_LOG_ERROR, "read frame error %d bbs.chinaffmpeg.com 孙悟空\n", ret);
  68.             break;
  69.         }

  70.         if (pkt.pts == AV_NOPTS_VALUE && first_pkt) {
  71.             pkt.pts = pkt.dts;
  72.             first_pkt = 0;
  73.         }

  74.         in_stream = input_fmtctx->streams[pkt.stream_index];
  75.         out_stream = output_fmtctx->streams[pkt.stream_index];

  76.         pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
  77.         pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
  78.         pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
  79.         pkt.pos = -1;

  80.         if (pkt.stream_index == 0) {

  81.                 AVPacket fpkt = pkt;
  82.                 int a = av_bitstream_filter_filter(vbsf,
  83.                             out_stream->codec, NULL, &fpkt.data, &fpkt.size,
  84.                                                pkt.data, pkt.size, pkt.flags & AV_PKT_FLAG_KEY);
  85.                 pkt.data = fpkt.data;
  86.                 pkt.size = fpkt.size;

  87.         }

  88.         ret = av_write_frame(output_fmtctx, &pkt);
  89.         if (ret < 0) {
  90.             av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Muxing Error\n");
  91.             break;
  92.         }

  93.         av_free_packet(&pkt);
  94.     }

  95.     av_write_trailer(output_fmtctx);
  96.     avformat_close_input(&input_fmtctx);
  97.     avio_close(output_fmtctx->pb);
  98.     avformat_free_context(output_fmtctx);
  99.     av_bitstream_filter_close(vbsf);
  100.     vbsf = NULL;

  101.     return 0;
  102. }




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多