Long time not updated blog, from the company resigned years ago, this six months, has been to do some outsourcing app to feed themselves! is also to achieve their own years ago set goals! But also think that can not always do outsourcing it, so decided to do some of their own feel interesting app, hang to the App Store and App Store, as long as there are 1-2k or 1-2w active users, they are satisfied!
Recently thinking to make a voice feed system, difficult, in fact, is in the Android and iOS audio interoperability! Busy one weeks to solve the problem, so I share with you!
First, the overall design scheme:
Server: PHP
Database: Redis
Protocol: HTTP + JSON
Client: Android (Java) + iOS (OC)
In the audio format selection problem, hesitated for a long time, here in fact there are n programs, but for me this kind of non-media developers, or choose a most direct and most can solve the problem on it! Initially selected is amr,android everything OK, but on iOS, WAV format audio file parsing into AMR format file, or AMR format audio file decoding into WAV format file is always wrong, with the LIBCOREAMR library on GitHub, unknown so! Of course, if anyone solves it, you can talk to me!
Finally choose the format of MP3! The disadvantage is that the generated audio file is larger than the AMR file! The advantage is that I solved it! Ha ha
The following dry code: the first is the Android part, relatively simple, is recorded through the mic MP3 file, and then upload the server!
Recording part: Actually is for the use of Mediarecorder,
1Recorder =NewMediarecorder ();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 } Ten Catch(IOException e) One { A - } - Recorder.start (); theToast.maketext (addactivity. This, "Start recording", Toast.length_short). Show ();
View Code
Upload the server, with the Asynchttp library, very convenient, here is the attention to the audio file upload format problem, preferably with the file upload format, PHP is also used $_files[""] to extract, do not use the usual long pass picture of the form, the file converted to byte[], Then convert to a string, and then to the php,php to save the file to the server, it is very easy to destroy the file format! Attention!
Requestparams params =NewRequestparams (); Params.put ("UID", SingleManager.user.getUid ()); Params.put ("Textcontent", Content.geteditabletext (). toString ()); Try{params.put ("Radiocontent",NewFile (fileName)); } Catch(FileNotFoundException E1) {e1.printstacktrace (); } asynchttprequestclient.post (Httputil.posturl, params,NewJsonobjectresponsehandler (addactivity. This) { Public voidOnjsonok (jsonobject response) {Try { } Catch(Exception e) {} Toast.maketext (addactivity. This, "Publishing Success", Toast.length_short). Show (); Finish (); } }); }
View Code
And then the iOS part, here first give a WAV to mp3 the library address, Https://github.com/rpplusplus/iOSMp3Recorder, in fact, is Avaudiorecorder + lame!
Recording section: For Avaudiorecorder usage and some setup information:
1NSString *dir = [Nshomedirectory () stringByAppendingPathComponent:@"Documents"];2Audiofilepath = [NSString stringWithFormat:@"%@/TESTAUDIO.CAF", dir];3Audiofileurl =[Nsurl Fileurlwithpath:audiofilepath];4 5Mp3filepath = [NSString stringWithFormat:@"%@/mp3audio.mp3", dir];6Mp3fileurl =[Nsurl Fileurlwithpath:mp3filepath];7 8 9Nsmutabledictionary *recordsettings =[[Nsmutabledictionary alloc] init];Ten [recordsettings setValue: [NSNumber NUMBERWITHINT:KAUDIOFORMATLINEARPCM] forkey:avformatidkey]; One[Recordsettings setValue: [NSNumber numberwithfloat:11025.0] Forkey:avsampleratekey];//44100.0 A[Recordsettings setValue: [NSNumber numberwithint:2] Forkey:avnumberofchannelskey]; -[Recordsettings setValue: [NSNumber numberwithint: -] Forkey:avlinearpcmbitdepthkey]; - [recordsettings setValue: [NSNumber Numberwithint:avaudioqualitylow] forkey:avencoderaudioqualitykey]; the - -Recorder =[[Avaudiorecorder alloc] Initwithurl:audiofileurl settings:recordsettings Error:nil]; -Recorder.Delegate=Self ; +[Recorder record];
View Code
transcoding section: After the recording is finished, the recording file will be transcoded and converted into MP3 format.
1 @try {2 intread, write;3 4FILE *PCM = fopen ([Audiofilepath cstringusingencoding:1],"RB");//Source converted audio file location5Fseek (PCM,4*1024x768, seek_cur);//Skip File Header6FILE *mp3 = fopen ([Mp3filepath cstringusingencoding:1],"WB");//Mp3 file location generated by output outputs7 8 Const intPcm_size =8192;9 Const intMp3_size =8192;Ten Short intpcm_buffer[pcm_size*2]; OneUnsignedCharMp3_buffer[mp3_size]; A -lame_t lame =lame_init (); -Lame_set_in_samplerate (Lame,11025.0); the 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); A Else atWrite =lame_encode_buffer_interleaved (Lame, pcm_buffer, read, Mp3_buffer, mp3_size); - -Fwrite (Mp3_buffer, Write,1, mp3); - -} while(Read! =0); - in lame_close (lame); - fclose (mp3); to fclose (PCM); + } - @catch(NSException *exception) { theNSLog (@"%@", [exception description]); * } $ @finallyPanax Notoginseng { -}
View Code
The last is the Upload Server section: Here used Afnetworking,ios commonly used an asynchronous network library, very easy to use, the function and Android Aysnchttp library similar, here and Android upload using the same PHP interface, so the audio file as a file upload, Instead of converting to nsdata and uploading, it's easy to destroy the audio format!
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":d ATA}; [Manager Post:[baseurl Stringbyappendingstring:post] parameters:parameters constructingbodywithblock:^(ID<AFMultipartFormData> formData) {[FormData Appendpartwithfileurl:mp3fileurl name:@"radiocontent"Error:nil]; } Success:^ (Afhttprequestoperation *operation,IDresponseobject) {Nsmutabledictionary*result = (Nsmutabledictionary *) Responseobject; NSLog (@"Result:%@", result); [Self.navigationcontroller Popviewcontrolleranimated:yes]; } Failure:^ (Afhttprequestoperation *operation, Nserror *error) { }];
View Code
Finally is the PHP section, here PHP does the work is relatively simple, is to get the client to upload the file, and then save to MP3 file on it! Or give some of the code:
$body ["rId"] =// receive file directory $target _path = $base _path. $rId. ". MP3 "; Move_uploaded_file ($_files [' radiocontent '] [' tmp_name '], $target _path); OutPut ($body);
View Code
The rest of the playback section is very simple, whether it is Android or iOS, as long as the system provided by the player, from the server to get the URL of the mp3 file, you can only play, because MP3 is a common audio format, both Android and iOS do not need to do what conversion! Direct playback on ok!
Android and iOS, Audio interoperability Solutions