我在windows下直接用ffmpeg.exe把aac和h264文件编码为mp4,又能在mac和ios上播放。
下两张图是windowsffmpeg.exe编码的结果图。
==========分割线==============
所以我怀疑是不是我代码写的有问题,大家看看这段代码吧:
下面这段是faac编码pcm为aac文件的代码:
ULONGnSampleRate=32000;//采样率UINTnChannels=1;//声道数UINTnPCMBitSize=16;//单样本位数ULONGnInputSamples=0;ULONGnMaxOutputBytes=0;intnRet;faacEncHandlehEncoder;faacEncConfigurationPtrpConfiguration;intnBytesRead;intnPCMBufferSize;BYTE*pbPCMBuffer;BYTE*pbAACBuffer;FILE*fpIn;//PCMfileforinputFILE*fpOut;//AACfileforoutput//NSString*cachePath=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];[CacheManagerwriteDataString:@""toFile:@"swa.aac"];//NSString*pathToPCM=[CacheManagerreadFile:@"swa.pcm"];NSString*pathToAAC=[CacheManagerwriteWithPath:@"swa.aac"];fpIn=fopen([pathStrUTF8String],"rb");fpOut=fopen([pathToAACUTF8String],"wb");//(1)OpenFAACenginehEncoder=faacEncOpen(nSampleRate,nChannels,&nInputSamples,&nMaxOutputBytes);if(hEncoder==NULL){printf("[ERROR]FailedtocallfaacEncOpen()\n");returnNO;}nPCMBufferSize=nInputSamples*nPCMBitSize/8;pbPCMBuffer=newBYTE[nPCMBufferSize];pbAACBuffer=newBYTE[nMaxOutputBytes];//(2.1)GetcurrentencodingconfigurationpConfiguration=faacEncGetCurrentConfiguration(hEncoder);pConfiguration->inputFormat=FAAC_INPUT_16BIT;pConfiguration->mpegVersion=MPEG4;//pConfiguration->outputFormat=0;pConfiguration->bitRate=320;pConfiguration->bandWidth=(nSampleRate*16*1/8);//(2.2)SetencodingconfigurationnRet=faacEncSetConfiguration(hEncoder,pConfiguration);for(inti=0;1;i++){//读入的实际字节数,最大不会超过nPCMBufferSize,一般只有读到文件尾时才不是这个值nBytesRead=fread(pbPCMBuffer,1,nPCMBufferSize,fpIn);//输入样本数,用实际读入字节数计算,一般只有读到文件尾时才不是nPCMBufferSize/(nPCMBitSize/8);nInputSamples=nBytesRead/(nPCMBitSize/8);//(3)EncodenRet=faacEncEncode(hEncoder,(int*)pbPCMBuffer,nInputSamples,pbAACBuffer,nMaxOutputBytes);fwrite(pbAACBuffer,1,nRet,fpOut);printf("%d:faacEncEncodereturns%d\n",i,nRet);if(nBytesRead<=0){break;}}/*while(1){//(3)FlushingnRet=faacEncEncode(hEncoder,(int*)pbPCMBuffer,0,pbAACBuffer,nMaxOutputBytes);if(nRet<=0){break;}}*///(4)CloseFAACenginenRet=faacEncClose(hEncoder);delete[]pbPCMBuffer;delete[]pbAACBuffer;fclose(fpIn);fclose(fpOut);returnYES;
=======分割线============
这段代码是ffmpeg编码aac和h264为mp4的代码:
AVOutputFormat*ofmt=NULL;//InputAVFormatContextandOutputAVFormatContextAVFormatContext*ifmt_ctx_v=NULL,*ifmt_ctx_a=NULL,*ofmt_ctx=NULL;AVPacketpkt;AVCodec*dec;intret,i;intvideoindex_v=-1,videoindex_out=-1;intaudioindex_a=-1,audioindex_out=-1;intframe_index=0;int64_tcur_pts_v=0,cur_pts_a=0;//constchar*in_filename_v="cuc_ieschool.ts";//InputfileURLconstchar*in_filename_v=[inputH264FileNamecStringUsingEncoding:NSASCIIStringEncoding];//constchar*in_filename_a="cuc_ieschool.mp3";//constchar*in_filename_a="gowest.m4a";//constchar*in_filename_a="gowest.aac";constchar*in_filename_a=[inputAacFileNamecStringUsingEncoding:NSASCIIStringEncoding];constchar*out_filename=[outMP4FileNamecStringUsingEncoding:NSASCIIStringEncoding];//OutputfileURLprintf("==========inh264==filename:%s\n",in_filename_v);printf("==========inaac===filename:%s\n",in_filename_a);printf("==========outfile:%s\n",out_filename);avcodec_register_all();av_register_all();//Inputif((ret=avformat_open_input(&ifmt_ctx_a,in_filename_a,NULL,NULL))<0){//printf("=====11========RET:%d\n",ret);printf("Couldnotopenaacinputfile.%d",ret);charbuf[]="";av_strerror(ret,buf,1024);printf("Couldn'topenaacfile%s:%d(%s)\n",in_filename_a,ret,buf);returnNO;}//printf("=====2========RET:%d\n",ret);if((ret=avformat_find_stream_info(ifmt_ctx_a,0))<0){printf("Failedtoretrieveaccinputstreaminformation%d",ret);returnNO;}if((ret=avformat_open_input(&ifmt_ctx_v,in_filename_v,NULL,NULL))<0){printf("Couldnotopenh264inputfile:%d\n",ret);returnNO;}//printf("=====0========RET:%d\n",ret);if((ret=avformat_find_stream_info(ifmt_ctx_v,0))<0){printf("Failedtoretrieveh264inputstreaminformation%d",ret);returnNO;}///*initthevideodecoder*///if((ret=avcodec_open2(ifmt_ctx_a->,dec,NULL))<0){//printf("Cannotopenvideodecoder\n");//returnret;//}//printf("===========InputInformation==========\n");av_dump_format(ifmt_ctx_v,0,in_filename_v,0);av_dump_format(ifmt_ctx_a,0,in_filename_a,0);printf("======================================\n");//Outputavformat_alloc_output_context2(&ofmt_ctx,NULL,NULL,out_filename);if(!ofmt_ctx){printf("Couldnotcreateoutputcontext\n");ret=AVERROR_UNKNOWN;returnNO;}ofmt=ofmt_ctx->oformat;for(i=0;i<ifmt_ctx_v->nb_streams;i++){//CreateoutputAVStreamaccordingtoinputAVStreamif(ifmt_ctx_v->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){AVStream*in_stream=ifmt_ctx_v->streams[i];AVStream*out_stream=avformat_new_stream(ofmt_ctx,in_stream->codec->codec);videoindex_v=i;if(!out_stream){printf("Failedallocatingoutputstream\n");ret=AVERROR_UNKNOWN;returnNO;}videoindex_out=out_stream->index;//CopythesettingsofAVCodecContextret=av_dict_set(&out_stream->metadata,"rotate","90",0);//设置旋转角度if(ret>=0){printf("=========yes=====setrotatesuccess!===\n");}if(avcodec_copy_context(out_stream->codec,in_stream->codec)<0){printf("Failedtocopycontextfrominputtooutputstreamcodeccontext\n");returnNO;}out_stream->codec->codec_tag=0;if(ofmt_ctx->oformat->flags&AVFMT_GLOBALHEADER)out_stream->codec->flags|=CODEC_FLAG_GLOBAL_HEADER;break;}}for(i=0;i<ifmt_ctx_a->nb_streams;i++){//CreateoutputAVStreamaccordingtoinputAVStreamif(ifmt_ctx_a->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){AVStream*in_stream=ifmt_ctx_a->streams[i];AVStream*out_stream=avformat_new_stream(ofmt_ctx,in_stream->codec->codec);audioindex_a=i;if(!out_stream){printf("Failedallocatingoutputstream\n");ret=AVERROR_UNKNOWN;returnNO;}audioindex_out=out_stream->index;//CopythesettingsofAVCodecContextif(avcodec_copy_context(out_stream->codec,in_stream->codec)<0){printf("Failedtocopycontextfrominputtooutputstreamcodeccontext\n");returnNO;}out_stream->codec->codec_tag=0;if(ofmt_ctx->oformat->flags&AVFMT_GLOBALHEADER)out_stream->codec->flags|=CODEC_FLAG_GLOBAL_HEADER;break;}}printf("==========OutputInformation==========\n");av_dump_format(ofmt_ctx,0,out_filename,1);printf("======================================\n");//Openoutputfileif(!(ofmt->flags&AVFMT_NOFILE)){if(avio_open(&ofmt_ctx->pb,out_filename,AVIO_FLAG_WRITE)<0){printf("Couldnotopenoutputfile'%s'",out_filename);returnNO;}}//Writefileheaderif(avformat_write_header(ofmt_ctx,NULL)<0){printf("Erroroccurredwhenopeningoutputfile\n");returnNO;}//FIX#ifUSE_H264BSFAVBitStreamFilterContext*h264bsfc=av_bitstream_filter_init("h264_mp4toannexb");#endif#ifUSE_AACBSFAVBitStreamFilterContext*aacbsfc=av_bitstream_filter_init("aac_adtstoasc");#endifwhile(1){AVFormatContext*ifmt_ctx;intstream_index=0;AVStream*in_stream,*out_stream;//GetanAVPacketif(av_compare_ts(cur_pts_v,ifmt_ctx_v->streams[videoindex_v]->time_base,cur_pts_a,ifmt_ctx_a->streams[audioindex_a]->time_base)<=0){ifmt_ctx=ifmt_ctx_v;stream_index=videoindex_out;if(av_read_frame(ifmt_ctx,&pkt)>=0){do{in_stream=ifmt_ctx->streams[pkt.stream_index];out_stream=ofmt_ctx->streams[stream_index];if(pkt.stream_index==videoindex_v){//FIX:NoPTS(Example:RawH.264)//SimpleWritePTSif(pkt.pts==AV_NOPTS_VALUE){//WritePTSAVRationaltime_base1=in_stream->time_base;//Durationbetween2frames(us)int64_tcalc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);//Parameterspkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);pkt.dts=pkt.pts;pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);frame_index++;}cur_pts_v=pkt.pts;break;}}while(av_read_frame(ifmt_ctx,&pkt)>=0);}else{break;}}else{ifmt_ctx=ifmt_ctx_a;stream_index=audioindex_out;if(av_read_frame(ifmt_ctx,&pkt)>=0){do{in_stream=ifmt_ctx->streams[pkt.stream_index];out_stream=ofmt_ctx->streams[stream_index];if(pkt.stream_index==audioindex_a){//FIX:NoPTS//SimpleWritePTSif(pkt.pts==AV_NOPTS_VALUE){//WritePTSAVRationaltime_base1=in_stream->time_base;//Durationbetween2frames(us)int64_tcalc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);//Parameterspkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);pkt.dts=pkt.pts;pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);frame_index++;}cur_pts_a=pkt.pts;break;}}while(av_read_frame(ifmt_ctx,&pkt)>=0);}else{break;}}//FIX:BitstreamFilter#ifUSE_H264BSFav_bitstream_filter_filter(h264bsfc,in_stream->codec,NULL,&pkt.data,&pkt.size,pkt.data,pkt.size,0);#endif#ifUSE_AACBSFav_bitstream_filter_filter(aacbsfc,out_stream->codec,NULL,&pkt.data,&pkt.size,pkt.data,pkt.size,0);#endif//ConvertPTS/DTSpkt.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;pkt.stream_index=stream_index;printf("Write1Packet.size:%5d\tpts:%lld\n",pkt.size,pkt.pts);//Writeif(av_interleaved_write_frame(ofmt_ctx,&pkt)<0){printf("Errormuxingpacket\n");break;}av_free_packet(&pkt);}//Writefiletrailerav_write_trailer(ofmt_ctx);#ifUSE_H264BSFav_bitstream_filter_close(h264bsfc);#endif#ifUSE_AACBSFav_bitstream_filter_close(aacbsfc);#endifavformat_close_input(&ifmt_ctx_v);avformat_close_input(&ifmt_ctx_a);/*closeoutput*/if(ofmt_ctx&&!(ofmt->flags&AVFMT_NOFILE))avio_close(ofmt_ctx->pb);avformat_free_context(ofmt_ctx);if(ret<0&&ret!=AVERROR_EOF){printf("Erroroccurred.\n");returnNO;}printf("======muxermp4success=====!\n");returnYES;
/*FIX:H.264insomecontainerformat(FLV,MP4,MKVetc.)need"h264_mp4toannexb"bitstreamfilter(BSF)*AddSPS,PPSinfrontofIDRframe*Addstartcode("0,0,0,1")infrontofNALUH.264insomecontainer(MPEG2TS)don'tneedthisBSF.*///'1':UseH.264BitstreamFilter#defineUSE_H264BSF1/*FIX:AACinsomecontainerformat(FLV,MP4,MKVetc.)need"aac_adtstoasc"bitstreamfilter(BSF)*///'1':UseAACBitstreamFilter#defineUSE_AACBSF1
来个人吧。。你好我能问下ffmpeg怎么连接的x264吗,搞不定