|
转载http://blog.chinaunix.net/uid-11344913-id-4432752.html
使用ffmpeg将mp4转为ts的命令格式如下:
-
ffmpeg-i b.mp4-codec
copy-bsfh264_mp4toannexb a.ts
如果不使用-bsf h264_mp4toannexb参数,会提示错误,错误信息如下:
-
ffmpeg-i b.mp4-codec
copy a.ts
-
ffmpeg version N-65108-gf2855eb Copyright(c)2000-2014
the FFmpeg developers
-
built on Jul 31 2014 02:29:27 with gcc 4.4.7(GCC)20120313(Red
Hat 4.4.7-4)
-
configuration:--prefix=/usr/local--enable-gpl--enable-nonfree--enable-libfaac--enable-libfreetype--enable-libx264--enable-libx265
-
libavutil 52.93.100 / 52.93.100
-
libavcodec 55.71.100 / 55.71.100
-
libavformat 55.49.100 / 55.49.100
-
libavdevice 55.13.102 / 55.13.102
-
libavfilter 4.11.102 / 4.11.102
-
libswscale 2.6.100 / 2.6.100
-
libswresample 0.19.100 / 0.19.100
-
libpostproc 52.3.100 / 52.3.100
-
Input #0,mov,mp4,m4a,3gp,3g2,mj2,from'b.mp4':
-
Metadata:
-
major_brand:isom
-
minor_version:512
-
compatible_brands:isomiso2avc1mp41
-
title:????????
-
encoder:Lavf55.49.100
-
copyright:(C)2004 HFD2B
-
Duration:00:04:09.44,start:0.000000,bitrate:568
kb/s
-
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)
-
Metadata:
-
handler_name:VideoHandler
-
Stream #0:1(und):Audio:aac(mp4a
/ 0x6134706D),44100 Hz,stereo,fltp,127
kb/s(default)
-
Metadata:
-
handler_name:SoundHandler
-
File'a.ts'already exists.Overwrite?[y/N]y
-
[adts @ 0x2269660]Using AVStream.codec.time_base
as a timebase hint to the muxer is deprecated.Set AVStream.time_base instead.
-
Output #0,mpegts,to'a.ts':
-
Metadata:
-
major_brand:isom
-
minor_version:512
-
compatible_brands:isomiso2avc1mp41
-
title:????????
-
copyright:(C)2004 HFD2B
-
encoder:Lavf55.49.100
-
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)
-
Metadata:
-
handler_name:VideoHandler
-
Stream #0:1(und):Audio:aac(mp4a
/ 0x6134706D),44100 Hz,stereo,127
kb/s(default)
-
Metadata:
-
handler_name:SoundHandler
-
Stream mapping:
-
Stream #0:0->#0:0(copy)
-
Stream #0:1->#0:1(copy)
-
Press[q]to stop,[?]forhelp
-
[mpegts @ 0x22761a0]H.264 bitstream malformed,no
startcode found,use the h264_mp4toannexb bitstream filter(-bsfh264_mp4toannexb)
-
av_interleaved_write_frame():Invalid argument
-
frame=1 fps=0.0 q=-1.0
Lsize=1kB time=00:00:00.04
bitrate=216.3kbits/s
-
video:1kB audio:0kB subtitle:0kB other streams:0kB
global headers:0kB muxing overhead:unknown
-
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.初始化filterav_bitstream_filter_init
-
2.使用filter转换av_bitstream_filter_filter
-
3.关闭filter av_bitstream_filter_close
其他与正常的转封装相同
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<libavformat/avformat.h>
-
#include<libavutil/avutil.h>
-
-
#define FORMAT"mpegts"
-
#define OUTPUT_FILE"./fuck.ts"
-
#define INPUT_FILE"./a.avi"
-
-
intmain(intargc,char*argv[])
-
{
-
AVPacket pkt;
-
AVFormatContext*input_fmtctx=NULL;
-
AVFormatContext*output_fmtctx=NULL;
-
AVCodecContext*enc_ctx=NULL;
-
AVCodecContext*dec_ctx=NULL;
-
AVCodec*encoder=NULL;
-
AVBitStreamFilterContext*vbsf=NULL;
-
intret=0;
-
inti=0;
-
inthave_key=0;
-
staticintfirst_pkt=1;
-
-
av_register_all();
-
-
if(avformat_open_input(&input_fmtctx,INPUT_FILE,NULL,NULL)<0){
-
av_log(NULL,AV_LOG_ERROR,"Cannot
open the file %s\n","./a.mp4");
-
return-ENOENT;
-
}
-
-
if(avformat_find_stream_info(input_fmtctx,0)<0){
-
av_log(NULL,AV_LOG_ERROR,"bbs.chinaffmpeg.com
孙悟空 Failed to retrieve input stream information\n");
-
return-EINVAL;
-
}
-
-
av_dump_format(input_fmtctx,NULL,INPUT_FILE,0);
-
-
if(avformat_alloc_output_context2(&output_fmtctx,NULL,FORMAT,OUTPUT_FILE)<0){
-
av_log(NULL,AV_LOG_ERROR,"Cannot
open the file %s bbs.chinaffmpeg.com 孙悟空\n",OUTPUT_FILE);
-
return-ENOENT;
-
}
-
-
/*Process transcode parameters*/
-
for(i=0;i<input_fmtctx->nb_streams;i++){
-
AVStream*out_stream=NULL;
-
AVStream*in_stream=NULL;
-
-
in_stream=input_fmtctx->streams[i];
-
out_stream=avformat_new_stream(output_fmtctx,in_stream->codec->codec);
-
if(out_stream<0){
-
av_log(NULL,AV_LOG_ERROR,"bbs.chinaffmpeg.com
孙悟空 Alloc new Stream error\n");
-
return-EINVAL;
-
}
-
-
avcodec_copy_context(output_fmtctx->streams[i]->codec,input_fmtctx->streams[i]->codec);
-
-
out_stream->codec->codec_tag=0;
-
if(output_fmtctx->oformat->flags&AVFMT_GLOBALHEADER){
-
out_stream->codec->flags|=CODEC_FLAG_GLOBAL_HEADER;
-
}
-
}
-
-
vbsf=av_bitstream_filter_init("h264_mp4toannexb");
-
-
-
av_dump_format(output_fmtctx,NULL,OUTPUT_FILE,1);
-
-
if(avio_open2(&output_fmtctx->pb,OUTPUT_FILE,AVIO_FLAG_WRITE,&output_fmtctx->interrupt_callback,NULL)<0){
-
av_log(NULL,AV_LOG_ERROR,"cannot
open the output file '%s' bbs.chinaffmpeg.com 孙悟空\n","./fuck.m3u8");
-
return-ENOENT;
-
}
-
-
av_opt_set(output_fmtctx->priv_data,"hls_time","10");
-
-
if((ret=avformat_write_header(output_fmtctx,NULL))<0){
-
av_log(NULL,AV_LOG_ERROR,"bbs.chinaffmpeg.com
孙悟空 Cannot write the header for the file '%s' ret = %d\n","fuck.ts",ret);
-
return-ENOENT;
-
}
-
-
while(1){
-
AVStream*in_stream=NULL;
-
AVStream*out_stream=NULL;
-
-
ret=av_read_frame(input_fmtctx,&pkt);
-
if(ret<0){
-
av_log(NULL,AV_LOG_ERROR,"read
frame error %d bbs.chinaffmpeg.com 孙悟空\n",ret);
-
break;
-
}
-
-
if(pkt.pts==AV_NOPTS_VALUE&&first_pkt){
-
pkt.pts=pkt.dts;
-
first_pkt=0;
-
}
-
-
in_stream=input_fmtctx->streams[pkt.stream_index];
-
out_stream=output_fmtctx->streams[pkt.stream_index];
-
-
pkt.pts=av_rescale_q_rnd(pkt.pts,in_stream->time_base,out_stream->time_base,AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
-
pkt.dts=av_rescale_q_rnd(pkt.dts,in_stream->time_base,out_stream->time_base,AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
-
pkt.duration=av_rescale_q(pkt.duration,in_stream->time_base,out_stream->time_base);
-
pkt.pos=-1;
-
-
if(pkt.stream_index==0){
-
-
AVPacket fpkt=pkt;
-
inta=av_bitstream_filter_filter(vbsf,
-
out_stream->codec,NULL,&fpkt.data,&fpkt.size,
-
pkt.data,pkt.size,pkt.flags&AV_PKT_FLAG_KEY);
-
pkt.data=fpkt.data;
-
pkt.size=fpkt.size;
-
-
}
-
-
ret=av_write_frame(output_fmtctx,&pkt);
-
if(ret<0){
-
av_log(NULL,AV_LOG_ERROR,"bbs.chinaffmpeg.com
孙悟空 Muxing Error\n");
-
break;
-
}
-
-
av_free_packet(&pkt);
-
}
-
-
av_write_trailer(output_fmtctx);
-
avformat_close_input(&input_fmtctx);
-
avio_close(output_fmtctx->pb);
-
avformat_free_context(output_fmtctx);
-
av_bitstream_filter_close(vbsf);
-
vbsf=NULL;
-
-
return 0;
-
}
|