iOS下的ffmpeg编码mp4格式

此文旨在抛砖引玉 跟同道交流学习

#include 
#include 
#include 

int WIDTH=320;
int HEIGHT=240;
int FPS=30;
int BITRATE=16*1000;

@interface ConvertToMov ()
{
    //Input AVFormatContext and Output AVFormatContext
    AVOutputFormat *outFormat;
    AVFormatContext *outfmt_ctx;
    NSString *movBasePath;
    NSString *filePath;
}
@end
@implementation ConvertToMov
-(id)init
{
    self = [super init];
    if (self)
    {
        [self setup];
    }
    return self;
}
-(void)setup
{
  movBasePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}

//保存帧数据
-(void)procWithData:(NSData *)data
{
    int ret;
    AVPacket avPacket;
    av_init_packet(&avPacket);
    avPacket.data = (uint8_t *)[data bytes];
    avPacket.size = (int)data.length;    
    avPacket.pos = -1;    
    ret = av_interleaved_write_frame(outfmt_ctx, &avPacket);//写入(Write)
    if (ret < 0)
    {
        DLog(@ "Error muxing packet\n");
    }
    //Write
    if (av_interleaved_write_frame(outfmt_ctx, &avPacket) < 0)
    {
        DLog(@ "Error muxing packet\n");
    }
    av_free_packet(&avPacket);
}

//写入头信息
-(void)start
{
    int ret;    
    NSFileManager *fileManager = [NSFileManager defaultManager];    
    NSCalendar *curCalendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    
    NSDateComponents *dateComponents = [curCalendar components:unitFlags fromDate:[NSDate date]];
    filePath = [movBasePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%ld-%ld-%ld.mp4",(long)dateComponents.hour, (long)dateComponents.minute, (long)dateComponents.second ]];
    [fileManager createFileAtPath:filePath contents:nil attributes:nil];
    const char *out_filename = [filePath UTF8String];//URL 路径  
    av_register_all();//注册所有容器格式和CODEC   
    avformat_alloc_output_context2(&outfmt_ctx, NULL, "mp4", out_filename);// 初始化一个用于输出的AVFormatContext结构体    
    if (!outfmt_ctx)
    {
        DLog(@ "Could not create output context\n");
//        ret = AVERROR_UNKNOWN;
    }
    outFormat = outfmt_ctx->oformat;
    AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);//查找对应的解码器
    AVStream *out_stream = avformat_new_stream(outfmt_ctx, codec);//创建输出码流的AVStream
    if (!out_stream)
    {
        DLog(@ "Failed allocating output stream\n");
//        ret = AVERROR_UNKNOWN;
    }
    ret = avcodec_copy_context(out_stream->codec, avcodec_alloc_context3(codec));//拷贝输入视频码流的AVCodecContex的数值t到输出视频的AVCodecContext。
    if (ret < 0)
    {
        DLog(@ "Failed to copy context from input to output stream codec context\n");
    }
    out_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;//支持的像素格式
    out_stream->codec->flags = CODEC_FLAG_GLOBAL_HEADER;
    out_stream->codec->width = WIDTH;
    out_stream->codec->height = HEIGHT;
    out_stream->codec->time_base = (AVRational){1,FPS};
    out_stream->codec->gop_size = FPS;
    out_stream->codec->bit_rate = BITRATE;
    out_stream->codec->codec_tag = 0;
    if (outfmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
    {
        out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
//    AVBitStreamFilterContext \*avFilter = av_bitstream_filter_init("h264_mp4toannexb");
//    out_stream->codec->extradata_size = size;
//    out_stream->codec->extradata = (uint8_t \*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
    //输出一下格式------------------
    av_dump_format(outfmt_ctx, 0, out_filename, 1);
    if (!(outFormat->flags & AVFMT_NOFILE))
    {
        ret = avio_open(&outfmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
        if (ret < 0)
        {
            DLog(@ "Could not open output file '%s'", out_filename);
        }
    }
    //写文件头(Write file header)
    ret = avformat_write_header(outfmt_ctx, NULL);
    if (ret < 0)
    {
        DLog(@ "Error occurred when opening output file\n");
    }
}

//写入尾信息
-(void)stop
{
    av_write_trailer(outfmt_ctx);
}

-(void)clean
{
    if (outfmt_ctx && !(outFormat->flags & AVFMT_NOFILE))
    {
        avio_close(outfmt_ctx->pb);
    }
    avformat_free_context(outfmt_ctx);
}
@end

你可能感兴趣的:(iOS下的ffmpeg编码mp4格式)