博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android和ios,音频互通方案
阅读量:6859 次
发布时间:2019-06-26

本文共 7079 字,大约阅读时间需要 23 分钟。

  好久不更新博客上,从年前从公司辞职,这半年以来,一直靠做一些外包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的使用,

1 recorder = new MediaRecorder(); 2                     recorder.setAudioSource(MediaRecorder.AudioSource.MIC);   3                     recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);   4                     recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);   5                     recorder.setOutputFile(fileName); 6                     try  7                     {   8                         recorder.prepare();   9                     } 10                     catch (IOException e) 11                     {  12                          13                     }  14                     recorder.start();15                     Toast.makeText(AddActivity.this, "开始录音", Toast.LENGTH_SHORT).show();
View Code

  上传服务器,用的是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();                    }                                     });                                            }
View Code

  

  如果问题到这里就简单了,后面经过测试发现,这种格式的mp3虽然可以播放,但是支持的效果很差,在第二个版本中果断放弃这种形式,而是采用一种主动编码成mp3格式的方式,使用的是github上的第三方开源库,地址:  https://github.com/yhirano/Mp3VoiceRecorderSampleForAndroid

 

  再就是ios部分了,这里先给出一个wav转mp3的库地址,https://github.com/rpplusplus/iOSMp3Recorder,其实就是AVAudioRecorder + lame!

  录制部分:对于AVAudioRecorder的使用和一些设置信息:  

1 NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"documents"]; 2     audioFilePath = [NSString stringWithFormat:@"%@/testAudio.caf",dir]; 3     audioFileUrl = [NSURL fileURLWithPath:audioFilePath]; 4      5     mp3FilePath = [NSString stringWithFormat:@"%@/mp3Audio.mp3",dir]; 6     mp3FileUrl = [NSURL fileURLWithPath:mp3FilePath]; 7      8      9     NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];10     [recordSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];11     [recordSettings setValue :[NSNumber numberWithFloat:11025.0] forKey: AVSampleRateKey];//44100.012     [recordSettings setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey];13     [recordSettings setValue :[NSNumber numberWithInt:16] forKey: AVLinearPCMBitDepthKey];14     [recordSettings setValue :[NSNumber numberWithInt:AVAudioQualityLow] forKey:AVEncoderAudioQualityKey];15     16     17     recorder = [[AVAudioRecorder alloc] initWithURL:audioFileUrl settings:recordSettings error:nil];18     recorder.delegate = self;19     [recorder record];
View Code

  转码部分:在录制结束之后,要对录制文件进行转码,转换成mp3格式

1 @try { 2         int read, write; 3          4         FILE *pcm = fopen([audioFilePath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置 5         fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header 6         FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置 7          8         const int PCM_SIZE = 8192; 9         const int MP3_SIZE = 8192;10         short int pcm_buffer[PCM_SIZE*2];11         unsigned char mp3_buffer[MP3_SIZE];12         13         lame_t lame = lame_init();14         lame_set_in_samplerate(lame, 11025.0);15         lame_set_VBR(lame, vbr_default);16         lame_init_params(lame);17         18         do {19             read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);20             if (read == 0)21                 write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);22             else23                 write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);24             25             fwrite(mp3_buffer, write, 1, mp3);26             27         } while (read != 0);28         29         lame_close(lame);30         fclose(mp3);31         fclose(pcm);32     }33     @catch (NSException *exception) {34         NSLog(@"%@",[exception description]);35     }36     @finally37     {38     }
View Code

  最后是上传服务器部分:这里使用的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
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) { }];
View Code

   

  最后是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);
View Code

  

  剩下的播放部分就很简单了,无论是android还是ios,只要使用系统提供的播放器,从服务器拿到mp3文件的url,就可以只接播放了,因为mp3是通用的音频格式,无论是android还是ios都不需要做什么转换!直接播放就ok!

转载地址:http://zkxyl.baihongyu.com/

你可能感兴趣的文章
Javascript图片裁切
查看>>
Android -- Serializable和Parcelable需要注意的
查看>>
Apache -- phpmyadmin导入文件过大
查看>>
吐槽一下Activiti用户手册和一本书
查看>>
解读Web Page Diagnostics网页细分图
查看>>
Enterprise Solution 管理软件开发框架流程实战
查看>>
hibernate缓存机制详细分析
查看>>
Android 动画效果 及 自定义动画
查看>>
基于Servlet、JSP、JDBC、MySQL登录模块(包括使用的过滤器和配置)
查看>>
Python将文本生成二维码
查看>>
统计学习那些事
查看>>
XLT架构图(自己 画的)
查看>>
GitHub Top 100 简介
查看>>
C语言中链表任意位置怎么插入数据?然后写入文件中?
查看>>
文档对象模型DOM(二)
查看>>
loading.io一个loading图标网站,跟大家分享
查看>>
Hadoop之——CentOS构造ssh否password登录注意事项
查看>>
云计算的设计模式(三)——补偿交易模式
查看>>
ACM-凸多边形的计算几何——hrbust1429
查看>>
WPF笔记(2.8 常用的布局属性)——Layout
查看>>