使用FFmpeg将文件转为ts

论坛 期权论坛 脚本     
匿名网站用户   2020-12-19 17:22   11   0

转载http://blog.chinaunix.net/uid-11344913-id-4432752.html

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


点击(此处)折叠或打开

  1. ffmpeg-i b.mp4-codec copy-bsfh264_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,[?]forhelp
  48. [mpegts @ 0x22761a0]H.264 bitstream malformed,no startcode found,use the h264_mp4toannexb bitstream filter(-bsfh264_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. intmain(intargc,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. intret=0;
  18. inti=0;
  19. inthave_key=0;
  20. staticintfirst_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. inta=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 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP