做为强大的音视频处理框架,ffmpeg提供了强大的方法供我们使用。由于本人是第一次使用这个库,所以遇到很多坑。下面给大家说一说ffmpeg从下载到应用的步骤。
关于音频介绍的相关资料:
http://www.cnblogs.com/skyofbitbit/p/3651270.html
1.下载脚本
https://github.com/kewlbear/FFmpeg-iOS-build-script
下载完成后会有如下执行文件
在终端运行执行文件:build-ffmpeg.sh
运行方法:
打开终端-> 打开文件所在文件夹->输入:./build-ffmpeg.sh
然后就是漫长的下载啊,下载。。。
2.开始导入工程
导入的是FFmpeg-iOS ,我修改了一下文件夹的名字改为FFmpeg。
导入Xcode,如下:
3.配置Xcode
1).配置头文件。在如下添加include,lib文件路径。
TARGETS->Build Setting ->Search Paths ->Header Paths
可能会出现的错误,大家可以看看这个链接:
http://blog.csdn.net/fanyong245758753/article/details/53909708
http://www.jianshu.com/p/35ba59292e70
2).导入系统库文件
libz.dylib -> libz.tbd
libbz2.dylib -> libbz2.tbd
libiconv.dylib -> libiconv.tbd
3).开始解码
一些参数的解析可以参考雷神的文章:
http://blog.csdn.net/leixiaohua1020/article/details/15811977/
下面正式解析音频文件:
我生成了一个用来解析音频文件的类:HanFFmpeg
#####.h文件声明如下
\#import <Foundation/Foundation.h>
@interface HanFFmpeg : NSObject
-(int)audio_decode_outfilename:(const char *)outfilename filename:(const char *)filename;
@end
#####.m实现过程如下
#import "HanFFmpeg.h"
#import <stdio.h>
#import <stdlib.h>
#import <libavcodec/avcodec.h>
#import <libavformat/avformat.h>
#import <libswscale/swscale.h>
#include <libavutil/opt.h>
@interface HanFFmpeg()
{
AVFormatContext *fmt_ctx;
AVCodecContext *codec_ctx;
AVPacket packet;
AVFrame *avFrame;
}
@end
@implementation HanFFmpeg
//初始化一些参数
- (instancetype)init
{
if (self = [super init])
{
fmt_ctx = avformat_alloc_context();
packet = *av_packet_alloc();
avFrame = av_frame_alloc();
av_register_all(); //注册所有可解码类型
avformat_network_init();
}
return self;
}
//打开音频文件文件及一些初始化
-(int) open_input_file:(const char *)filename
{
int ret;
AVCodec *dec;
//打开文件
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0)
{
//av_log(NULL, //av_log_ERROR, "Cannot open input file\n");
return ret;
}
else
{
NSLog(@"Can open input file");
}
//流信息
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0)
{
//av_log(NULL, //av_log_ERROR, "Cannot find stream information\n");
return ret;
}
else
{
NSLog(@"Can find stream information");
};
/* select the audio stream */
//输入文件的音频流
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
if (ret < 0)
{
//av_log(NULL, //av_log_ERROR, "Cannot find an audio stream in the input file\n");
return ret;
}
else
{
NSLog(@"Can find an audio stream in the input file");
}
int audio_stream_index = ret;
codec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
av_opt_set_int(codec_ctx, "refcounted_frames", 1, 0);
/* init the audio decoder */
//打开音频解码器
if ((ret = avcodec_open2(codec_ctx, dec, NULL)) < 0)
{
//av_log(NULL, //av_log_ERROR, "Cannot open audio decoder\n");
return ret;
}
else
{
NSLog(@"Can open audio decoder");
}
//打印文件信息
av_dump_format(fmt_ctx, 0, filename, 0);
return 0;
}
\-(int)audio_decode_outfilename:(const char *)outfilename filename:(const char *)filename;
{
if ([self open_input_file:filename] != 0)
{
NSLog(@"初始化失败");
return [self open_input_file:filename];
}
else
{
NSLog(@"初始化成功");
}
int audioStream = -1;
for (int i = 0; i < fmt_ctx->nb_streams; i++)
{
if (fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = i;
break;
}
}
if (audioStream == -1)
{
//NSLog(@"audioStream 信息有误");
return audioStream;
}
FILE *outfile = NULL;
outfile = fopen(outfilename, "wb");
while (av_read_frame(fmt_ctx, &packet) >= 0)
{
static int con = 1;
// NSLog(@"解码中 = %d packet.size = %d",con++,packet.size);
if (packet.size>0)
{
int ret = -1;
ret = avcodec_send_packet(codec_ctx, &(packet));
if (ret < 0)
{
return ret;
}
ret = avcodec_receive_frame(codec_ctx, avFrame);
if (ret < 0)
{
return ret;
}
int data_size = av_get_bytes_per_sample(codec_ctx->sample_fmt);
if (data_size<0)
{
NSLog(@"Failed to calculate data size");
return data_size;
}
if (!outfilename) {
av_free(codec_ctx);
NSLog(@"写入地址错误");
return -1;
}
for (int i=0; i<avFrame->nb_samples; i++)
{
for (int ch=0; ch<codec_ctx->channels; ch++)
{
fwrite(avFrame->data[ch] + data_size*i, 1, data_size, outfile);
}
}
}
}
fclose(outfile);
avcodec_close(codec_ctx);
av_free(codec_ctx);
av_frame_free(&avFrame);
avformat_free_context(fmt_ctx);
return 0;
}
@end
至此音频文件转PCM完成。
相关调用:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *paths1 = [paths objectAtIndex:0];
NSString *filePath = [paths1 stringByAppendingPathComponent:@"han.pcm"];
NSLog(@"===%@",filePath);
> HanFFmpeg *han = [[HanFFmpeg alloc] init];
[han audio_decode_outfilename:[filePath UTF8String ] filename:[path UTF8String]];
参考的其他文章:
http://blog.csdn.net/yang_xian521/article/details/7699620/
http://www.cnblogs.com/XYQ-208910/p/5651166.html
http://www.cnblogs.com/wangguchangqing/p/5788805.html
http://blog.csdn.net/a411358606/article/details/52240529
http://www.360doc.com/content/16/0516/10/474846_559526656.shtml
http://www.cnblogs.com/wangguchangqing/p/5851490.html
https://github.com/brookicv/FFMPEG-study/blob/master/FFmpeg-playAudio.cpp
http://www.360doc.com/content/15/0514/18/7821691_470483326.shtml
http://www.jianshu.com/p/1f92ee874613
//ffmpeg 官方文档
http://ffmpeg.org/doxygen/3.2/examples.html
4).遇到的一些问题
http://www.jianshu.com/p/3fce0bd6f045
http://www.ithao123.cn/content-92295.html
5).下载地址
由于文件太大,只上传了关键的代码,FFmpeg配置好了,就可以直接调用。
http://download.csdn.net/detail/qq_14827361/9917690