android和ios,音频互通方案
好久不更新博客上,从年前从公司辞职,这半年以来,一直靠做一些外包app养活自己!也算是达成了自己年前制定的目标!可是也想着总不能一直做外包吧,所以决定做一些自己觉得有意思的app,挂到应用商店上和app store上,只要有1-2k或者1-2w的活跃用户,自己也就满足了!
最近寻思做一个语音feed系统,难点呢,其实也就是在android和ios音频互通上!忙了一个星期解决了这个问题,所以就和大家分享下!
先说下整体的设计方案:
服务器:php
数据库:redis
协议:http + json
客户端 : android(java) + ios(oc)
在音频的格式选择问题上,犹豫了很久,这里其实有N个方案的,不过对于我这种非多媒体开发者来讲,还是选择一个最直接最能解决问题的就可以了!起初选择的是amr,android一切都ok,但是在ios上,wav格式的音频文件解析成amr格式的文件,或者amr格式的音频文件解码成wav格式的文件是总是出错,用的是github上的libcoreamr库,不明所以!当然如果谁解决了还是可以跟我聊下!
最终选择了mp3的格式!缺点就是生成的音频文件比amr文件要大!优点就是我解决了!哈哈
下面干货代码:首先是android 部分,相对比较简单,就是通过mic录制成mp3文件,然后上传服务器!
录音部分:其实就是对于MediaRecorder的使用,
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setOutputFile(fileName);
try
{
recorder.prepare();
}
catch (IOException e)
{
}
recorder.start();
Toast.makeText(AddActivity.this, "开始录音", Toast.LENGTH_SHORT).show();
上传服务器,用的是AsyncHttp库,非常方便,这里注意的是对音频文件的上传格式问题,最好还是用文件上传的格式,php也用$_FILES[""]去提取,不要用大家平时长传图片的形式,将文件转换成byte[],再转换成String,再给到php,php再保存文件到服务器,这样极易破坏文件的格式!注意!
RequestParams params = new RequestParams();
params.put("uid", SingleManager.user.getUid());
params.put("textContent", content.getEditableText().toString());
try
{
params.put("radioContent", new File(fileName) );
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
AsyncHttpRequestClient.post(HttpUtil.postUrl, params ,new JSONObjectResponseHandler(AddActivity.this)
{
public void onJsonOk(JSONObject response)
{
try
{
}
catch (Exception e)
{
}
Toast.makeText( AddActivity.this, "发表成功", Toast.LENGTH_SHORT).show();
finish();
}
});
}
如果问题到这里就简单了,后面经过测试发现,这种格式的mp3虽然可以播放,但是支持的效果很差,在第二个版本中果断放弃这种形式,而是采用一种主动编码成mp3格式的方式,使用的是github上的第三方开源库,地址: https://github.com/yhirano/Mp3VoiceRecorderSampleForAndroid
再就是ios部分了,这里先给出一个wav转mp3的库地址,https://github.com/rpplusplus/iOSMp3Recorder,其实就是AVAudioRecorder + lame!
录制部分:对于AVAudioRecorder的使用和一些设置信息:
NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"documents"];
audioFilePath = [NSString stringWithFormat:@"%@/testAudio.caf",dir];
audioFileUrl = [NSURL fileURLWithPath:audioFilePath];
mp3FilePath = [NSString stringWithFormat:@"%@/mp3Audio.mp3",dir];
mp3FileUrl = [NSURL fileURLWithPath:mp3FilePath];
NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];
[recordSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];
[recordSettings setValue :[NSNumber numberWithFloat:11025.0] forKey: AVSampleRateKey];//44100.0
[recordSettings setValue :[NSNumber numberWithInt:] forKey: AVNumberOfChannelsKey];
[recordSettings setValue :[NSNumber numberWithInt:] forKey: AVLinearPCMBitDepthKey];
[recordSettings setValue :[NSNumber numberWithInt:AVAudioQualityLow] forKey:AVEncoderAudioQualityKey];
recorder = [[AVAudioRecorder alloc] initWithURL:audioFileUrl settings:recordSettings error:nil];
recorder.delegate = self;
[recorder record];
转码部分:在录制结束之后,要对录制文件进行转码,转换成mp3格式
@try {
int read, write;
FILE *pcm = fopen([audioFilePath cStringUsingEncoding:], "rb"); //source 被转换的音频文件位置
fseek(pcm, *, SEEK_CUR); //skip file header
FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:], "wb"); //output 输出生成的Mp3文件位置
;
;
];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 11025.0);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
do {
read = fread(pcm_buffer, *sizeof(short int), PCM_SIZE, pcm);
)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, , mp3);
} );
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
@finally
{
}
最后是上传服务器部分:这里使用的AFNETWORKING,ios常用的一个异步网络库,很好用,功能和android的aysncHttp库类似,这里和android上传使用的同一个php接口,所以音频文件按照文件形式上传,而不是转换成NSData再上传,容易破坏音频格式!
SingleManager *single = [SingleManager shareManager];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *uid = [NSString stringWithFormat:@"%d",single.user.userId];
NSString *textContent = self.textContent.text;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *data = [fileManager contentsAtPath:mp3FilePath];
NSDictionary *parameters = @{@"uid":uid,@"textContent":textContent,@"radioContent":data};
[manager POST:[baseUrl stringByAppendingString:post] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData){[formData appendPartWithFileURL:mp3FileUrl name:@"radioContent" error:nil];
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSMutableDictionary *result = (NSMutableDictionary *)responseObject;
NSLog(@"Result: %@",result);
[self.navigationController popViewControllerAnimated:YES];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
}];
最后是php部分,这里php做的工作比较简单,就是得到客户端上传的文件,然后保存成mp3文件就可以了!还是给出部分代码:
$body["rId"] = $rId; $base_path = "../radio/"; //接收文件目录 $target_path = $base_path .$rId.".mp3"; move_uploaded_file ( $_FILES ['radioContent'] ['tmp_name'], $target_path ); outPut($body);
剩下的播放部分就很简单了,无论是android还是ios,只要使用系统提供的播放器,从服务器拿到mp3文件的url,就可以只接播放了,因为mp3是通用的音频格式,无论是android还是ios都不需要做什么转换!直接播放就ok!
android和ios,音频互通方案的更多相关文章
- iOS音频AAC视频H264编码 推流最佳方案
iOS音频AAC视频H264编码 推流最佳方案 项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1 功能概况 * 实现音视频的数据的采集 * 实现音视频数据的编码,视频编码成 ...
- android和ios流媒体库推荐
1基本信息编辑 Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染.从2011年8月上线到2014年1月,Vitamio 凭借其简洁易用的 ...
- 提供给Android和iOS开发人员的UWP移植向导
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:前几天微软发布了一个针对Android和iOS开发人员理解Windows Apps概念 ...
- iOS动态部署方案
转载: iOS动态部署方案 前言 这里讨论的动态部署方案,就是指通过不发版的方式,将新的内容.新的业务流程部署进已发布的App.因为苹果的审核周期比较长,而且苹果的限制比较多,业界在这里也没有特别多的 ...
- javafx for android or ios ?
javafx是否支持android 或者 ios这是一个令人感兴趣的话题.google一番,发现有可行方案: 1. javafx on android: 两种方案:(事实上差点儿相同) 1.有位大神已 ...
- JSBridge(Android和IOS平台)的设计和实现
前言 对于商务类的app,随着app注册使用人数递增,app的运营者们就会逐渐考虑在应用中开展一些推广活动.大多数活动具备时效性强.运营时间短的特征,一般产品们和运营者们都是通过wap页面快速投放到产 ...
- ArcGIS Runtime SDKs v10.2.4最新(Android、iOS、OSX和.NET)
ArcGIS Runtime SDKs v10.2.4最新,它包含:Android.iOS.OS X和.NET四大平台,用户和开发人员可以登录Esri最新的SDK安装包.或者通过云盘下载(http:/ ...
- 测试中Android与IOS分别关注的点
主要从本身系统的不同点.系统造成的不同点.和注意的测试点做总结 1.自身不同点 研发商:Adroid是google公司做的手机系统,IOS是苹果公司做的手机系统 开源程度:Android是开源的,IO ...
- IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...
随机推荐
- Js 数据容量单位转换(kb,mb,gb,tb)
function bytesToSize(bytes) { if (bytes === 0) return '0 B'; var k = 1000, // or 1024 sizes = ['B', ...
- GTD时间管理(3)---项目
一:什么是项目? 一个项目是由多步骤,多阶段组成的,不可能一步到位的. 项目分为可大可小. 魔兽世界这个程序是一个项目,是一个用10年开发的大型项目 搭建一个博客也可以成为一个项目,可以用一天时间去搭 ...
- android获取本机的IP地址和mac物理地址
/获取本机IP地址 public String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemServi ...
- WPF应用程序最小化到系统托盘
using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; u ...
- Jquery+artTemplate+layPage 封装datagrid
导言 在日常开发中经常会用到列表,相信用过easyui,Ext等很多,的确很强大,但想修改确实也不容易,我也用了几年的easyui,有时间时会想一下,自已随然没有前端的精湛技术,但可以在有这些技术的开 ...
- 可能 delphi7 下稳定的最后一版本 GDIPLUS
可能 delphi7 下稳定的最后一版本 GDIPLUS 万一的 blog 说"终于, Delphi XE2 携带 GDI+ 库了 使用了较早的 http://www.progdigy.co ...
- Android学习笔记----Activity的生命周期图示
转载,一目了然.
- PD16 Generate Datebase For Sql2008R2时报脚本错误“对象名sysproperties无效”
PowerDesinger16创建数据库表到SQL2008R2时,执行报“对象名sysproperties无效”错误. 主要是在建模时我们对表.列增加了些说明注释,而Sql2005之后系统表syspr ...
- [转]LINQ To SQL 语法及实例大全
转载自:http://blog.csdn.net/pan_junbiao/article/details/7015633 LINQ to SQL语句(1)之Where Where操作 适用场景:实现过 ...
- CSS基础(一):开篇
背景 HTML是一种超文本标记语言,用来定义文档的结构和内容,例如标题.段落和列表等等,而文档内容如何渲染.如何展示,这就需要样式来修饰了.CSS正是可以与HTML很好地结合.如果将HTML比作水,那 ...