演示ios平台上的amr音频转码
来源:互联网 发布:java搜索引擎源代码 编辑:程序博客网 时间:2024/05/17 20:29
/*
* 代码演示了:1.怎么使用ffmpeg;2.从确定格式到找到编解码器的过程;3.怎么解码一个音频;4.怎么编码出一个音频;
* 实现把一个音频文件转码成amr文件
* 只作为流程演示,细致有可能需要再作考虑
**/
#import "ViewController.h"
extern "C" {
#include "ffmpeg/include/libavcodec/avcodec.h"
#include "ffmpeg/include/libavformat/avformat.h"
#include "ffmpeg/include/libswresample/swresample.h"
}
@interface ViewController ()
{
AVFormatContext* _inFormatContext;
AVFormatContext* _outFormatContext;
AVCodecContext* _inCodecContext;
AVCodecContext* _outCodecContext;
AVCodec* _inCodec;
AVCodec* _outCodec;
SwrContext *_swr;
int _audiostream_index;
NSString* _infilepath;
};
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// NSString *nofoundfile = [NSHomeDirectory() stringByAppendingString:@"/Documents/allfile.txt"];
// NSMutableArray* filearry = [[NSMutableArray alloc]initWithCapacity:400];
// FILE* file = fopen([nofoundfile UTF8String], "r");
// if (file) {
// char temp[64] = {0};
// while (fgets(temp, 63, file) != NULL) {
// temp[strlen(temp)-1] = 0;
// [filearry addObject:[NSString stringWithUTF8String:temp]];
// }
// fclose(file);
// }
//
// if ([filearry count] > 0) {
// NSString *dirPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/music"];
// NSString *realPath = [dirPath stringByExpandingTildeInPath];
// NSFileManager *fileMgr = [NSFileManager defaultManager];
// NSDirectoryEnumerator *fileEnum = [fileMgr enumeratorAtPath:realPath];
// NSString *filename = [fileEnum nextObject];
// while (filename) {
// BOOL found = NO;
// for (NSString* file in filearry) {
// if ([file isEqualToString:filename]) {
// found = YES;
// break;
// }
// }
// if (found) {
// NSString *fullPath = [NSString stringWithFormat:@"%@/%@", realPath, filename];
// [[NSFileManager defaultManager]removeItemAtPath:fullPath error:nil];
// }
//
// filename = [fileEnum nextObject];
// }
// }
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)openInCodec
{
NSString* inpath = _infilepath;
BOOL openSuccess = NO;
int audio_stream_index = -1;
do {
_inFormatContext = avformat_alloc_context();
int ret = avformat_open_input(&_inFormatContext, [inpath UTF8String], NULL, NULL);
if (ret != 0) {
NSLog(@"open input failed");
break;
}
ret = avformat_find_stream_info(_inFormatContext, NULL);
if (ret < 0) {
NSLog(@"find stream info failed");
break;
}
for (int pos = 0; pos < _inFormatContext->nb_streams; pos ++) {
if (_inFormatContext->streams[pos]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audio_stream_index = pos;
break;
}
}
if (audio_stream_index == -1) {
NSLog(@"no audio stream");
break;
}
_inCodecContext = _inFormatContext->streams[audio_stream_index]->codec;
_inCodec = avcodec_find_decoder(_inCodecContext->codec_id);
if (_inCodec == NULL) {
NSLog(@"no avcodec found");
_inCodecContext = NULL;
break;
}
ret = avcodec_open2(_inCodecContext, _inCodec, NULL);
if (ret != 0) {
NSLog(@"open codec failed");
_inCodecContext = NULL;
break;
}
_audiostream_index = audio_stream_index;
openSuccess = YES;
}while (0);
if (!openSuccess) {
[self destroyffmpeg];
}
return openSuccess;
}
- (BOOL)openOutCodec
{
NSString* outpath = [NSHomeDirectory()stringByAppendingString:@"/Documents/out.amr"];
NSString* outfilepath = outpath;
BOOL openSuccess = NO;
do {
int ret = avformat_alloc_output_context2(&_outFormatContext, NULL, "amr", [outfilepath UTF8String]);
if (ret < 0) {
NSLog(@"alloc output format failed");
break;
}
AVOutputFormat* outFormat = _outFormatContext->oformat;
outFormat->audio_codec = AV_CODEC_ID_AMR_NB;
outFormat->video_codec = AV_CODEC_ID_NONE;
_outCodec = avcodec_find_encoder(outFormat->audio_codec);
if (_inCodec == NULL) {
NSLog(@"no encoder found");
break;
}
AVStream* audioStream = avformat_new_stream(_outFormatContext, _outCodec);
if (audioStream == NULL) {
NSLog(@"new stream failed");
break;
}
audioStream->id = 0;
audioStream->index = 0;
_outCodecContext = audioStream->codec;
if (_outCodecContext == NULL) {
NSLog(@"no codecContext in stream");
break;
}
_outCodecContext->sample_fmt = AV_SAMPLE_FMT_S16;
_outCodecContext->channels = 1;
_outCodecContext->channel_layout = av_get_default_channel_layout(1);
_outCodecContext->sample_rate = 8000;
_outCodecContext->bit_rate = 12200;
if (outFormat->flags & AVFMT_GLOBALHEADER) {
_outCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
ret = avcodec_open2(_outCodecContext, _outCodec, NULL);
if (ret < 0) {
NSLog(@"open encoder failed");
break;
}
av_dump_format(_outFormatContext, 0, [outfilepath UTF8String], 1);
if (!(_outFormatContext->flags & AVFMT_NOFILE)) {
ret = avio_open2(&_outFormatContext->pb, [outfilepath UTF8String], AVIO_FLAG_WRITE, &_outFormatContext->interrupt_callback, NULL);
if (ret < 0) {
NSLog(@"avio_open2 failed: %d(%s)", ret, av_err2str(ret));
break;
}
}
AVDictionary* dict = NULL;
ret = avformat_write_header(_outFormatContext, &dict);
if (ret < 0) {
NSLog(@"write header failed: %d(%s)", ret, av_err2str(ret));
break;
}
openSuccess = YES;
}while (0);
if (!openSuccess) {
[self destroyffmpeg];
}
return openSuccess;
}
- (void)deletetSwr
{
if (_swr) {
swr_free(&_swr);
_swr = NULL;
}
}
- (void)convert
{
BOOL eof = NO;
while (1) {
AVPacket packet;
int ret = av_read_frame(_inFormatContext, &packet);
if (ret < 0) {
if (ret == AVERROR_EOF || url_feof(_inFormatContext->pb)) {
NSLog(@"read_frame eof");
eof = YES;
break;
}
else {
NSLog(@"av_read_frame failed, %d(%s)", ret, av_err2str(ret));
break;
}
}
if (packet.stream_index == _audiostream_index) {
int size = packet.size;
AVFrame frame;
AVPacket encodePacket;
void* out_buffer = NULL;
while (size > 0) {
// av_frame_unref(&frame);
int gotframe = 0;
int len = avcodec_decode_audio4(_inCodecContext, &frame, &gotframe, &packet);
if (len < 0) {
NSLog(@"audio decode failed");
break;
}
if (gotframe) {
bool needConvert = true;
int targetSampelrate = 8000;
int targetChannels = 1;
if (needConvert) {
int out_size = av_samples_get_buffer_size(NULL, targetChannels, frame.nb_samples, AV_SAMPLE_FMT_S16, 0);
if (out_size >= 0) {
// if (_swr) { // more think here for if
// [self deletetSwr];
// }
bool initswr = true;
if (_swr == NULL) {
uint64_t in_channel_layout = av_get_default_channel_layout(av_frame_get_channels(&frame));
uint64_t out_channel_layout = av_get_default_channel_layout(targetChannels);
int inSamplerate = frame.sample_rate;
_swr = swr_alloc_set_opts(NULL,
out_channel_layout, (enum AVSampleFormat )AV_SAMPLE_FMT_S16, targetSampelrate,
in_channel_layout, (enum AVSampleFormat)frame.format, inSamplerate, 0, NULL);
int ret = swr_init(_swr);
if (ret != 0) {
initswr = false;
}
}
if (_swr && initswr) {
if (frame.extended_data && frame.data[0] && frame.linesize[0] > 0) {
out_buffer = av_malloc(out_size);
if (out_buffer) {
int convertSamples = swr_convert(_swr, (uint8_t**)(&out_buffer), frame.nb_samples, (const uint8_t**)frame.extended_data, frame.nb_samples);
int len = convertSamples * targetChannels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
int nb_samples = _outCodecContext->frame_size / 1;
int buffer_size = av_samples_get_buffer_size( NULL, _outCodecContext->channels, nb_samples, AV_SAMPLE_FMT_S16, 0 );
AVFrame* decodeframe = avcodec_alloc_frame();
decodeframe->nb_samples = nb_samples;
ret = avcodec_fill_audio_frame( decodeframe, _outCodecContext->sample_fmt, AV_SAMPLE_FMT_S16, (const uint8_t *)out_buffer, buffer_size, 0 );
if( ret < 0 )
{
NSLog( @"avcodec_fill_audio_frame error!");
break;
}
encodePacket.data = NULL;
encodePacket.size = 0;
av_init_packet(&encodePacket);
ret = avcodec_encode_audio2(_outCodecContext, &encodePacket, decodeframe, &gotframe);
if (ret < 0) {
NSLog(@"encode audio fail: %d(%s)", ret, av_err2str(ret));
break;
}
if (gotframe == 0) {
NSLog(@"did not got frame");
break;
}
encodePacket.stream_index = 0;
ret = av_write_frame(_outFormatContext, &encodePacket);
if (ret < 0) {
NSLog(@"av_write_frame failed: %d(%s)", ret, av_err2str(ret));
break;
}
size -= len;
}
}
}
}
}
}
}
av_free_packet(&encodePacket);
if (out_buffer) {
av_free(out_buffer);
}
}
}
if (eof) {
av_write_trailer(_outFormatContext);
}
}
- (void)ffmpegInit
{
static int times = 0;
if (times == 0) {
times = 1;
av_register_all();
avcodec_register_all();
}
}
- (void)destroyffmpeg
{
if (_inFormatContext) {
avformat_close_input(&_inFormatContext);
avformat_free_context(_inFormatContext);
_inFormatContext = NULL;
}
if (_outFormatContext) {
avformat_free_context(_outFormatContext);
_outFormatContext = NULL;
}
if (_inCodecContext) {
avcodec_close(_inCodecContext);
_inCodecContext = NULL;
}
if (_outCodecContext) {
avcodec_close(_outCodecContext);
_outCodecContext = NULL;
}
[self deletetSwr];
_audiostream_index = -1;
}
-(IBAction)amrConvertBtnClicked:(id)sender
{
NSLog(@"amr convert start");
NSString *dir = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:@"/music"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *arrFiles = [fileManager subpathsAtPath:dir];
if ([arrFiles count] <= 0) {
NSLog(@"no src file");
return;
}
NSString *path = [NSString stringWithFormat:@"%@/%@",dir,[arrFiles objectAtIndex:0]];
_infilepath = [[NSString alloc]initWithString:path];
[self ffmpegInit];
[self destroyffmpeg];
if ([self openInCodec]) {
if ([self openOutCodec]) {
[self convert];
}
}
}
@end
* 代码演示了:1.怎么使用ffmpeg;2.从确定格式到找到编解码器的过程;3.怎么解码一个音频;4.怎么编码出一个音频;
* 实现把一个音频文件转码成amr文件
* 只作为流程演示,细致有可能需要再作考虑
**/
#import "ViewController.h"
extern "C" {
#include "ffmpeg/include/libavcodec/avcodec.h"
#include "ffmpeg/include/libavformat/avformat.h"
#include "ffmpeg/include/libswresample/swresample.h"
}
@interface ViewController ()
{
AVFormatContext* _inFormatContext;
AVFormatContext* _outFormatContext;
AVCodecContext* _inCodecContext;
AVCodecContext* _outCodecContext;
AVCodec* _inCodec;
AVCodec* _outCodec;
SwrContext *_swr;
int _audiostream_index;
NSString* _infilepath;
};
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// NSString *nofoundfile = [NSHomeDirectory() stringByAppendingString:@"/Documents/allfile.txt"];
// NSMutableArray* filearry = [[NSMutableArray alloc]initWithCapacity:400];
// FILE* file = fopen([nofoundfile UTF8String], "r");
// if (file) {
// char temp[64] = {0};
// while (fgets(temp, 63, file) != NULL) {
// temp[strlen(temp)-1] = 0;
// [filearry addObject:[NSString stringWithUTF8String:temp]];
// }
// fclose(file);
// }
//
// if ([filearry count] > 0) {
// NSString *dirPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/music"];
// NSString *realPath = [dirPath stringByExpandingTildeInPath];
// NSFileManager *fileMgr = [NSFileManager defaultManager];
// NSDirectoryEnumerator *fileEnum = [fileMgr enumeratorAtPath:realPath];
// NSString *filename = [fileEnum nextObject];
// while (filename) {
// BOOL found = NO;
// for (NSString* file in filearry) {
// if ([file isEqualToString:filename]) {
// found = YES;
// break;
// }
// }
// if (found) {
// NSString *fullPath = [NSString stringWithFormat:@"%@/%@", realPath, filename];
// [[NSFileManager defaultManager]removeItemAtPath:fullPath error:nil];
// }
//
// filename = [fileEnum nextObject];
// }
// }
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)openInCodec
{
NSString* inpath = _infilepath;
BOOL openSuccess = NO;
int audio_stream_index = -1;
do {
_inFormatContext = avformat_alloc_context();
int ret = avformat_open_input(&_inFormatContext, [inpath UTF8String], NULL, NULL);
if (ret != 0) {
NSLog(@"open input failed");
break;
}
ret = avformat_find_stream_info(_inFormatContext, NULL);
if (ret < 0) {
NSLog(@"find stream info failed");
break;
}
for (int pos = 0; pos < _inFormatContext->nb_streams; pos ++) {
if (_inFormatContext->streams[pos]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audio_stream_index = pos;
break;
}
}
if (audio_stream_index == -1) {
NSLog(@"no audio stream");
break;
}
_inCodecContext = _inFormatContext->streams[audio_stream_index]->codec;
_inCodec = avcodec_find_decoder(_inCodecContext->codec_id);
if (_inCodec == NULL) {
NSLog(@"no avcodec found");
_inCodecContext = NULL;
break;
}
ret = avcodec_open2(_inCodecContext, _inCodec, NULL);
if (ret != 0) {
NSLog(@"open codec failed");
_inCodecContext = NULL;
break;
}
_audiostream_index = audio_stream_index;
openSuccess = YES;
}while (0);
if (!openSuccess) {
[self destroyffmpeg];
}
return openSuccess;
}
- (BOOL)openOutCodec
{
NSString* outpath = [NSHomeDirectory()stringByAppendingString:@"/Documents/out.amr"];
NSString* outfilepath = outpath;
BOOL openSuccess = NO;
do {
int ret = avformat_alloc_output_context2(&_outFormatContext, NULL, "amr", [outfilepath UTF8String]);
if (ret < 0) {
NSLog(@"alloc output format failed");
break;
}
AVOutputFormat* outFormat = _outFormatContext->oformat;
outFormat->audio_codec = AV_CODEC_ID_AMR_NB;
outFormat->video_codec = AV_CODEC_ID_NONE;
_outCodec = avcodec_find_encoder(outFormat->audio_codec);
if (_inCodec == NULL) {
NSLog(@"no encoder found");
break;
}
AVStream* audioStream = avformat_new_stream(_outFormatContext, _outCodec);
if (audioStream == NULL) {
NSLog(@"new stream failed");
break;
}
audioStream->id = 0;
audioStream->index = 0;
_outCodecContext = audioStream->codec;
if (_outCodecContext == NULL) {
NSLog(@"no codecContext in stream");
break;
}
_outCodecContext->sample_fmt = AV_SAMPLE_FMT_S16;
_outCodecContext->channels = 1;
_outCodecContext->channel_layout = av_get_default_channel_layout(1);
_outCodecContext->sample_rate = 8000;
_outCodecContext->bit_rate = 12200;
if (outFormat->flags & AVFMT_GLOBALHEADER) {
_outCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
ret = avcodec_open2(_outCodecContext, _outCodec, NULL);
if (ret < 0) {
NSLog(@"open encoder failed");
break;
}
av_dump_format(_outFormatContext, 0, [outfilepath UTF8String], 1);
if (!(_outFormatContext->flags & AVFMT_NOFILE)) {
ret = avio_open2(&_outFormatContext->pb, [outfilepath UTF8String], AVIO_FLAG_WRITE, &_outFormatContext->interrupt_callback, NULL);
if (ret < 0) {
NSLog(@"avio_open2 failed: %d(%s)", ret, av_err2str(ret));
break;
}
}
AVDictionary* dict = NULL;
ret = avformat_write_header(_outFormatContext, &dict);
if (ret < 0) {
NSLog(@"write header failed: %d(%s)", ret, av_err2str(ret));
break;
}
openSuccess = YES;
}while (0);
if (!openSuccess) {
[self destroyffmpeg];
}
return openSuccess;
}
- (void)deletetSwr
{
if (_swr) {
swr_free(&_swr);
_swr = NULL;
}
}
- (void)convert
{
BOOL eof = NO;
while (1) {
AVPacket packet;
int ret = av_read_frame(_inFormatContext, &packet);
if (ret < 0) {
if (ret == AVERROR_EOF || url_feof(_inFormatContext->pb)) {
NSLog(@"read_frame eof");
eof = YES;
break;
}
else {
NSLog(@"av_read_frame failed, %d(%s)", ret, av_err2str(ret));
break;
}
}
if (packet.stream_index == _audiostream_index) {
int size = packet.size;
AVFrame frame;
AVPacket encodePacket;
void* out_buffer = NULL;
while (size > 0) {
// av_frame_unref(&frame);
int gotframe = 0;
int len = avcodec_decode_audio4(_inCodecContext, &frame, &gotframe, &packet);
if (len < 0) {
NSLog(@"audio decode failed");
break;
}
if (gotframe) {
bool needConvert = true;
int targetSampelrate = 8000;
int targetChannels = 1;
if (needConvert) {
int out_size = av_samples_get_buffer_size(NULL, targetChannels, frame.nb_samples, AV_SAMPLE_FMT_S16, 0);
if (out_size >= 0) {
// if (_swr) { // more think here for if
// [self deletetSwr];
// }
bool initswr = true;
if (_swr == NULL) {
uint64_t in_channel_layout = av_get_default_channel_layout(av_frame_get_channels(&frame));
uint64_t out_channel_layout = av_get_default_channel_layout(targetChannels);
int inSamplerate = frame.sample_rate;
_swr = swr_alloc_set_opts(NULL,
out_channel_layout, (enum AVSampleFormat )AV_SAMPLE_FMT_S16, targetSampelrate,
in_channel_layout, (enum AVSampleFormat)frame.format, inSamplerate, 0, NULL);
int ret = swr_init(_swr);
if (ret != 0) {
initswr = false;
}
}
if (_swr && initswr) {
if (frame.extended_data && frame.data[0] && frame.linesize[0] > 0) {
out_buffer = av_malloc(out_size);
if (out_buffer) {
int convertSamples = swr_convert(_swr, (uint8_t**)(&out_buffer), frame.nb_samples, (const uint8_t**)frame.extended_data, frame.nb_samples);
int len = convertSamples * targetChannels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
int nb_samples = _outCodecContext->frame_size / 1;
int buffer_size = av_samples_get_buffer_size( NULL, _outCodecContext->channels, nb_samples, AV_SAMPLE_FMT_S16, 0 );
AVFrame* decodeframe = avcodec_alloc_frame();
decodeframe->nb_samples = nb_samples;
ret = avcodec_fill_audio_frame( decodeframe, _outCodecContext->sample_fmt, AV_SAMPLE_FMT_S16, (const uint8_t *)out_buffer, buffer_size, 0 );
if( ret < 0 )
{
NSLog( @"avcodec_fill_audio_frame error!");
break;
}
encodePacket.data = NULL;
encodePacket.size = 0;
av_init_packet(&encodePacket);
ret = avcodec_encode_audio2(_outCodecContext, &encodePacket, decodeframe, &gotframe);
if (ret < 0) {
NSLog(@"encode audio fail: %d(%s)", ret, av_err2str(ret));
break;
}
if (gotframe == 0) {
NSLog(@"did not got frame");
break;
}
encodePacket.stream_index = 0;
ret = av_write_frame(_outFormatContext, &encodePacket);
if (ret < 0) {
NSLog(@"av_write_frame failed: %d(%s)", ret, av_err2str(ret));
break;
}
size -= len;
}
}
}
}
}
}
}
av_free_packet(&encodePacket);
if (out_buffer) {
av_free(out_buffer);
}
}
}
if (eof) {
av_write_trailer(_outFormatContext);
}
}
- (void)ffmpegInit
{
static int times = 0;
if (times == 0) {
times = 1;
av_register_all();
avcodec_register_all();
}
}
- (void)destroyffmpeg
{
if (_inFormatContext) {
avformat_close_input(&_inFormatContext);
avformat_free_context(_inFormatContext);
_inFormatContext = NULL;
}
if (_outFormatContext) {
avformat_free_context(_outFormatContext);
_outFormatContext = NULL;
}
if (_inCodecContext) {
avcodec_close(_inCodecContext);
_inCodecContext = NULL;
}
if (_outCodecContext) {
avcodec_close(_outCodecContext);
_outCodecContext = NULL;
}
[self deletetSwr];
_audiostream_index = -1;
}
-(IBAction)amrConvertBtnClicked:(id)sender
{
NSLog(@"amr convert start");
NSString *dir = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:@"/music"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *arrFiles = [fileManager subpathsAtPath:dir];
if ([arrFiles count] <= 0) {
NSLog(@"no src file");
return;
}
NSString *path = [NSString stringWithFormat:@"%@/%@",dir,[arrFiles objectAtIndex:0]];
_infilepath = [[NSString alloc]initWithString:path];
[self ffmpegInit];
[self destroyffmpeg];
if ([self openInCodec]) {
if ([self openOutCodec]) {
[self convert];
}
}
}
@end
0 0
- 演示ios平台上的amr音频转码
- FFmpeg音频转码amr转mp3
- ffmpeg 音频转amr
- iOS平台设备上的音频即时通讯应用开发
- 播放amr格式的音频
- iOS录音转码:amr转wav,wav转amr
- ios 使用音频队列播放amr格式转换成wav的格式,只有嘈杂声
- FFMPEG 音频转换命令 wav转amr
- FFMPEG 音频转换命令 wav转amr
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- iOS 录音Wav 音频 转换 Amr ,Android 播放
- opencore amr在iOS上decode
- ios平台微信的语音文件AUD格式其实就是AMR格式
- AMR音频编解码
- AMR音频编解码
- 详解AMR音频编码器
- AMR音频结构
- 注解定时器的使用
- Embed Tomcat8简单示例
- 更换jdk引发的惨案
- Git 忽略文件规则
- 2.3 自定义BaseAdapter
- 演示ios平台上的amr音频转码
- EJB到底是什么,真的那么神秘吗??
- jpa 实体4个状态
- java volatile关键字
- 【Caffe】001 命令行参数解析
- Android JVM的运行过程
- AndroidStudio快捷键汇总
- Android面试题目
- 百万并发量苹果官网准备好了吗?——一分钟学会服务器压力测试