iOS Swift - Merge and convert .wav files to .mp3 -


i want merge 2 or more .wav files 1 , convert .mp3 , done in swift (or @ least have option include swift project).

merge 2 .wav files in swift isn't problem. here example don't know how add lame library swift project , how use (how change objective c lame code usage syntax use in swift).

i stuck in swift tried lame library objective c. found example code converting .caf .mp3 tried it. here i've tried:

- (void) tomp3 {     nsstring *caffilepath = [[nsbundle mainbundle] pathforresource:@"sound" oftype:@"caf"];      nsstring *mp3filename = @"mp3file";     mp3filename = [mp3filename stringbyappendingstring:@".mp3"];     nsstring *mp3filepath = [[nshomedirectory() stringbyappendingformat:@"/documents/"] stringbyappendingpathcomponent:mp3filename];      nslog(@"%@", mp3filepath);      @try {         int read, write;          file *pcm = fopen([caffilepath cstringusingencoding:1], "rb");  //source         fseek(pcm, 4*1024, seek_cur);                                   //skip file header         file *mp3 = fopen([mp3filepath cstringusingencoding:1], "wb");  //output          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, 44100);         lame_set_vbr(lame, vbr_default);         lame_init_params(lame);          {             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 {         [self performselectoronmainthread:@selector(convertmp3finish)                                withobject:nil                             waituntildone:yes];     } }  - (void) convertmp3finish { } 

but result of .mp3 noise.

so need fix 3 problems:

  • create correct mp3 caf in objective c
  • change code use wav file
  • and change able use in swift

i know there many questions encoding , converting mp3 in ios can't find 1 swift example , can't find example working objective c code (just code above). help

i post working solution because many thumbs , answer naresh doesn't me much.

  1. i have generated lame.framework library project https://github.com/wuqiong/mp3lame-for-ios
  2. i've added library swift project (build phases -> link binary libraries)
  3. i've created wrapper using c functions in objective c , bridging header use in swift.
  4. for concatenate wav files use avassetexportsession swift

and source codes. first wrapper. it's class converting .wav files .mp3. there many changes (maybe parameter output file , other options) think change it. guess rewritten swift wasn't sure how it. it's objective c class:

#import "audiowrapper.h" #import "lame/lame.h"  @implementation audiowrapper  + (void)convertfromwavtomp3:(nsstring *)filepath {       nsstring *mp3filename = @"mp3file";     mp3filename = [mp3filename stringbyappendingstring:@".mp3"];     nsstring *mp3filepath = [nstemporarydirectory() stringbyappendingpathcomponent:mp3filename];      nslog(@"%@", mp3filepath);      @try {         int read, write;          file *pcm = fopen([filepath cstringusingencoding:1], "rb");  //source         fseek(pcm, 4*1024, seek_cur);                                   //skip file header         file *mp3 = fopen([mp3filepath cstringusingencoding:1], "wb");  //output          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, 44100);         lame_set_vbr(lame, vbr_default);         lame_init_params(lame);          {             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 {         [self performselectoronmainthread:@selector(convertmp3finish)                                withobject:nil                             waituntildone:yes];     } } 

swift audiohelper class concatening audio files , calling method converting .wav file .mp3:

import uikit import avfoundation   protocol audiohelperdelegate {     func assetexportsessiondidfinishexport(session: avassetexportsession, outputurl: nsurl) }  class audiohelper: nsobject {      var delegate: audiohelperdelegate?      func concatenate(audiourls: [nsurl]) {          //create avmutablecomposition object.this object hold our multiple avmutablecompositiontrack.         var composition = avmutablecomposition()         var compositionaudiotrack:avmutablecompositiontrack = composition.addmutabletrackwithmediatype(avmediatypeaudio, preferredtrackid: cmpersistenttrackid())          //create new file receive data         var documentdirectoryurl = nsfilemanager.defaultmanager().urlsfordirectory(.documentdirectory, indomains: .userdomainmask).first! as! nsurl         var filedestinationurl = nsurl(fileurlwithpath: nstemporarydirectory().stringbyappendingpathcomponent("resultmerge.wav"))         println(filedestinationurl)          storagemanager.sharedinstance.deletefileatpath(nstemporarydirectory().stringbyappendingpathcomponent("resultmerge.wav"))          var avassets: [avurlasset] = []         var assettracks: [avassettrack] = []         var durations: [cmtime] = []         var timeranges: [cmtimerange] = []          var inserttime = kcmtimezero          audiourl in audiourls {             let avasset = avurlasset(url: audiourl, options: nil)             avassets.append(avasset)              let assettrack = avasset.trackswithmediatype(avmediatypeaudio)[0] as! avassettrack             assettracks.append(assettrack)              let duration = assettrack.timerange.duration             durations.append(duration)              let timerange = cmtimerangemake(kcmtimezero, duration)             timeranges.append(timerange)              compositionaudiotrack.inserttimerange(timerange, oftrack: assettrack, attime: inserttime, error: nil)             inserttime = cmtimeadd(inserttime, duration)         }          //avassetexportpresetpassthrough => concatenation         var assetexport = avassetexportsession(asset: composition, presetname: avassetexportpresetpassthrough)         assetexport.outputfiletype = avfiletypewave         assetexport.outputurl = filedestinationurl         assetexport.exportasynchronouslywithcompletionhandler({             self.delegate?.assetexportsessiondidfinishexport(assetexport, outputurl: filedestinationurl!)         })     }      func exporttempwavasmp3() {          let wavfilepath = nstemporarydirectory().stringbyappendingpathcomponent("resultmerge.wav")         audiowrapper.convertfromwavtomp3(wavfilepath)     } } 

bridging header contains:

#import "lame/lame.h" #import "audiowrapper.h" 

Comments