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的使用,

 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();

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

                });

            }

  

  再就是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.0
12     [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];

  转码部分:在录制结束之后,要对录制文件进行转码,转换成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             else
23                 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     @finally
37     {
38     }

  最后是上传服务器部分:这里使用的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!

时间: 2024-10-15 05:17:06

android和ios,音频互通方案的相关文章

转: ios与android语音互通方案,类微信

Ios实现amr编解码 Feb 5th, 2012 介绍 学习ios第一个练手功能就是给已有产品加上语音通信功能,能够互通ios与android.这里给出自己的一些心得,希望能给他人一些参考. 资料搜集与参考 类似产品使用的技术 talkbox Android版用的是ilbc的第三方编解码库,在iPhone上用的是caf 微信 Android版估计是amr估计转码的是交给腾讯强大的服务器了. 米聊 Android版和Iphone版用的都是speex 目前支持的开源第三方库也就只有 ilbc和sp

ios与android设备即时语音互通的录音格式

在做iphone开发之前,我(ray)对声音格式了解的相当少.我知道一些“wav”和“mp3”声音格式的差异,但是我肯定不能准确地告诉你“AAC”.“CAF”是什么格式的声音文件,同时也不知道在MAC上最好的转换音频文件的方法是什么. 我深知,假如你想要成为一名合格的iphone开发者,你必须对声音文件数据格式,转换,录音和使用什么音频操作API有个基本的了解. 这篇文章是三篇涵盖音频开发教程中的第一篇.在这篇文章中,我们将会从文件和数据格式开始. 文件格式和数据格式 首先我们要知道的是,对每个

iOS音频AAC视频H264编码 推流最佳方案

项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1    功能概况 *  实现音视频的数据的采集 *  实现音视频数据的编码,视频编码成h264,音频编码成aac *  实现音视频数据的发布,将编码好的音视频数据传输到服务器 2 视频和音频编码方案 视频硬编码需要使用AVAssetWriter,但是他只支持直接将数据编码成h264并写入文件,不提供接口中途获取视频数据处理,我们需要在保存的文件中读出数据 据顶采用软编码,主流开源编解码器Xvid,x264,ffmpeg,Xvid是

ios音频降噪/拼接

1. http://www.leiphone.com/news/201406/record.html 关于手机录音和降噪那些事 本文作者是科通芯城的何顺义工程师. 想必大家都有这样的经历:接到朋友从火车站.地铁.会场.KTV等场合打来的电话,有时候很难听清楚,有时候却听得很清晰.这是为什么? 通常我们会认为是对方信号不稳定,所以通话质量有好有坏.其实不然,这种环境下能否听清对方讲话,主要取决于对方手机录音和降噪功能的优劣.同时,这也是高端手机和普通手机的一个重要区别. 任何功能的差别,归根到底,

Android 与 iOS 下 Speex的使用

首先,在现在这个微信的时代,做一个IMapp,绝对不能少了语音通讯这个功能,如果没有了语音通讯功能我相信在当下已经不能算是一个IM了. 由于前段时间在忙碌一个新的项目,导致这个模块已经耽误了一个月了.终于在今天另一个项目上线之后我从新开始这个模块的研究. 在研究开始之前,我首先去市场下载了几个目前比较流行IM,然后通过强大的反编译和文件查找能力,发现即使是陌陌这个app ,他们的语音传输都是没有经过比较大的压缩的(MEWOW同样地没没有经过较大的压缩),但微信则是通过自身强大的算法,对音频文件进

android和ios流媒体库推荐

1基本信息编辑 Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染.从2011年8月上线到2014年1月,Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐,全球已经有超过3000 种应用在使用Vitamio,覆盖用户超过5亿. 2功能特性编辑 Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS

Android、IOS浏览器的适配问题整理

相关知识点: 移动端. 兼容/适配 . IOS点击事件300ms延迟 .点击穿透 . 定位失败 ... 手机浏览器特有的事件: onTouchmove . ontouched . ontouchstart . ontouchcancel. 使用Zepto的原因: jQuery适用于PC端桌面环境,桌面环境更加复杂,jQuery需要考虑的因素非常多,尤其表现在兼容性上面. 与PC端相比,移动端的发展远不及PC端,手机上的带宽永远比不上pc端. pc端下载jQuery到本地只需要1~3秒(90+K)

javafx for android or ios ?

javafx是否支持android 或者 ios这是一个令人感兴趣的话题.google一番,发现有可行方案: 1. javafx on android: 两种方案:(事实上差点儿相同) 1.有位大神已经编译好javafx on  android执行环境dalvik-sdk,只是仅仅支持jdk7的特性. 大神博客地址:http://java.dzone.com/articles/javafx-and-android dalvik-sdk地址:https://bitbucket.org/javafx

如何在Android和iOS设备上录制游戏?

内容简介 如何在Android和iOS设备上录制游戏? 如何在Android和iOS设备上录制游戏? Xbox One,PS4,Windows 10等都集成了游戏录制功能,而且可以把录制的视频分享到网上. 现在,Android和iOS设备也可以实现游戏录制了. 怎么做呢?我们分为Android和iOS平台来介绍. Android平台 首先下载安装一个App,叫做<Google Play Games>. 运行此App,在菜单中点击<My Game>(英语<我的游戏>的意思