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.
- i have generated lame.framework library project https://github.com/wuqiong/mp3lame-for-ios
- i've added library swift project (build phases -> link binary libraries)
- i've created wrapper using c functions in objective c , bridging header use in swift.
- 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
Post a Comment