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:2] forKey: AVNumberOfChannelsKey];
    [recordSettings setValue :[NSNumber numberWithInt:16] 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:1], "rb");  //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header
        FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        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, 2*sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                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, 1, mp3);
            
        } while (read != 0);
        
        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!


相关文章
|
1月前
|
机器学习/深度学习 人工智能 语音技术
探索未来:安卓与iOS的人工智能竞赛
在当今数字化时代,安卓和iOS作为两大主流移动操作系统,已经成为人们日常生活不可或缺的一部分。随着人工智能技术的飞速发展,安卓与iOS之间的竞争日益激烈。本文将深入探讨安卓与iOS在人工智能领域的发展现状和未来趋势,分析两者之间的差异和竞争优势,为读者带来全新的视角和思考。
16 1
|
2月前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
31 1
|
2月前
|
API 开发工具 Android开发
iOS 和 Android 平台的开发有哪些主要区别?
iOS与Android开发区别:iOS用Objective-C/Swift,App Store唯一下载渠道;Android用Java/Kotlin,多商店发布(如Google Play、华为市场)。设计上,iOS简洁一致,Android灵活可定制。开发工具,iOS用Xcode,Android用Android Studio。硬件和系统多样性,iOS统一,Android复杂。权限管理、审核流程及API各有特点,开发者需依据目标平台特性进行选择。
38 3
|
12天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
15天前
|
人工智能 安全 Android开发
【专栏】在人工智能时代,Android和iOS两大移动操作系统巨头正加速融合与创新
【4月更文挑战第27天】在人工智能时代,Android和iOS两大移动操作系统巨头正加速融合与创新。Android以其开放性占据广阔市场,集成AI功能如语音助手;而iOS以其稳定性和生态优势,如Siri,提供卓越体验。两者在AI技术、应用场景上相互借鉴,拓展至医疗、教育等领域,并逐步打通生态系统。然而,技术竞争、数据隐私和标准不一是挑战,新市场需求、技术创新和产业合作则带来机遇。未来,二者将继续推动AI发展,为社会进步贡献力量。
|
5天前
|
编解码 调度 Android开发
Android音频框架之一 详解audioPolicy流程及HAL驱动加载与配置
Android音频框架之一 详解audioPolicy流程及HAL驱动加载与配置
11 0
|
13天前
|
缓存 Android开发 iOS开发
打造高效移动应用:Android与iOS性能优化策略
【4月更文挑战第29天】 在移动设备日益成为用户日常互动的主要平台的今天,应用程序的性能已成为决定其成功的关键因素之一。本文将探讨针对Android和iOS平台的性能优化技巧,涵盖内存管理、多线程处理、网络请求优化以及用户界面的流畅性提升等方面。通过分析不同操作系统的架构特点,我们旨在提供一套综合性的策略,帮助开发者构建快速、响应迅捷且用户体验良好的应用。
|
19天前
|
Android开发 内存技术
Android 通过tinyalsa调试解决录制和播放音频问题
Android 通过tinyalsa调试解决录制和播放音频问题
35 1
|
19天前
|
Android开发
Android 新建一个lunch项(全志方案)
Android 新建一个lunch项(全志方案)
17 0
|
19天前
|
安全 Java Shell
Android11以上 Audio音频调试方法
Android11以上 Audio音频调试方法
58 0