iOS视频添加背景音乐同时保留原音
程序员文章站
2023-12-20 12:46:34
话不多说,请看代码:
//抽取原视频的音频与需要的音乐混合
-(void)addmusic:(id)sender
{
[mbprogresshuds...
话不多说,请看代码:
//抽取原视频的音频与需要的音乐混合 -(void)addmusic:(id)sender { [mbprogresshudshowhudaddedto:self.viewanimated:yes]; avmutablecomposition *composition =[avmutablecompositioncomposition]; audiomixparams =[[nsmutablearrayalloc]initwithobjects:nil]; //录制的视频 nsurl *video_inputfileurl =[nsurlfileurlwithpath:self.videopath]; avurlasset *songasset =[avurlasseturlassetwithurl:video_inputfileurloptions:nil]; cmtime starttime =cmtimemakewithseconds(0,songasset.duration.timescale); cmtime trackduration =songasset.duration; //获取视频中的音频素材 [selfsetupandaddaudioatpath:video_inputfileurltocomposition:compositionstart:starttimedura:trackdurationoffset:cmtimemake(14*44100,44100)]; //本地要插入的音乐 nsstring *bundledirectory =[[nsbundlemainbundle]bundlepath]; nsstring *path = [bundledirectorystringbyappendingpathcomponent:@"30secs.mp3"]; nsurl *asseturl2 =[nsurlfileurlwithpath:path]; //获取设置完的本地音乐素材 [selfsetupandaddaudioatpath:asseturl2tocomposition:compositionstart:starttimedura:trackdurationoffset:cmtimemake(0,44100)]; //创建一个可变的音频混合 avmutableaudiomix *audiomix =[avmutableaudiomixaudiomix]; audiomix.inputparameters =[nsarrayarraywitharray:audiomixparams];//从数组里取出处理后的音频轨道参数 //创建一个输出 avassetexportsession *exporter =[[avassetexportsessionalloc] initwithasset:composition presetname:avassetexportpresetapplem4a]; exporter.audiomix = audiomix; exporter.outputfiletype=@"com.apple.m4a-audio"; nsstring* filename =[nsstringstringwithformat:@"%@.mov",@"overmix"]; //输出路径 nsstring *exportfile =[nsstringstringwithformat:@"%@/%@",[selfgetlibaraypath], filename]; if([[nsfilemanagerdefaultmanager]fileexistsatpath:exportfile]) { [[nsfilemanagerdefaultmanager]removeitematpath:exportfileerror:nil]; } nslog(@"是否在主线程1%d",[nsthreadismainthread]); nslog(@"输出路径===%@",exportfile); nsurl *exporturl =[nsurlfileurlwithpath:exportfile]; exporter.outputurl = exporturl; self.mixurl =exporturl; [exporterexportasynchronouslywithcompletionhandler:^{ int exportstatus =(int)exporter.status; switch (exportstatus){ caseavassetexportsessionstatusfailed:{ nserror *exporterror =exporter.error; nslog(@"错误,信息: %@", exporterror); [mbprogresshudhidehudforview:self.viewanimated:yes]; break; } caseavassetexportsessionstatuscompleted:{ nslog(@"是否在主线程2%d",[nsthreadismainthread]); nslog(@"成功"); //最终混合 [selfthevideowithmixmusic]; break; } } }]; } //最终音频和视频混合 -(void)thevideowithmixmusic { nserror *error =nil; nsfilemanager *filemgr =[nsfilemanagerdefaultmanager]; nsstring *documentsdirectory =[nshomedirectory() stringbyappendingpathcomponent:@"documents"]; nsstring *videooutputpath =[documentsdirectorystringbyappendingpathcomponent:@"test_output.mp4"]; if ([filemgrremoveitematpath:videooutputpatherror:&error]!=yes) { nslog(@"无法删除文件,错误信息:%@",[error localizeddescription]); } //声音来源路径(最终混合的音频) nsurl *audio_inputfileurl =self.mixurl; //视频来源路径 nsurl *video_inputfileurl = [nsurlfileurlwithpath:self.videopath]; //最终合成输出路径 nsstring *outputfilepath =[documentsdirectorystringbyappendingpathcomponent:@"final_video.mp4"]; nsurl *outputfileurl = [nsurlfileurlwithpath:outputfilepath]; if([[nsfilemanagerdefaultmanager]fileexistsatpath:outputfilepath]) [[nsfilemanagerdefaultmanager]removeitematpath:outputfilepatherror:nil]; cmtime nextclipstarttime =kcmtimezero; //创建可变的音频视频组合 avmutablecomposition* mixcomposition =[avmutablecompositioncomposition]; //视频采集 avurlasset* videoasset =[[avurlassetalloc]initwithurl:video_inputfileurloptions:nil]; cmtimerange video_timerange =cmtimerangemake(kcmtimezero,videoasset.duration); avmutablecompositiontrack*a_compositionvideotrack = [mixcompositionaddmutabletrackwithmediatype:avmediatypevideopreferredtrackid:kcmpersistenttrackid_invalid]; [a_compositionvideotrackinserttimerange:video_timerangeoftrack:[[videoassettrackswithmediatype:avmediatypevideo]objectatindex:0]attime:nextclipstarttimeerror:nil]; //声音采集 avurlasset* audioasset =[[avurlassetalloc]initwithurl:audio_inputfileurloptions:nil]; cmtimerange audio_timerange =cmtimerangemake(kcmtimezero,videoasset.duration);//声音长度截取范围==视频长度 avmutablecompositiontrack*b_compositionaudiotrack = [mixcompositionaddmutabletrackwithmediatype:avmediatypeaudiopreferredtrackid:kcmpersistenttrackid_invalid]; [b_compositionaudiotrackinserttimerange:audio_timerangeoftrack:[[audioassettrackswithmediatype:avmediatypeaudio]objectatindex:0]attime:nextclipstarttimeerror:nil]; //创建一个输出 avassetexportsession* _assetexport =[[avassetexportsessionalloc]initwithasset:mixcompositionpresetname:avassetexportpresetmediumquality]; _assetexport.outputfiletype =avfiletypequicktimemovie; _assetexport.outputurl =outputfileurl; _assetexport.shouldoptimizefornetworkuse=yes; self.theendvideourl=outputfileurl; [_assetexportexportasynchronouslywithcompletionhandler: ^(void ) { [mbprogresshudhidehudforview:self.viewanimated:yes]; //播放 nsurl*url = [nsurlfileurlwithpath:outputfilepath]; mpmovieplayerviewcontroller *themovie =[[mpmovieplayerviewcontrolleralloc]initwithcontenturl:url]; [selfpresentmovieplayerviewcontrolleranimated:themovie]; themovie.movieplayer.moviesourcetype=mpmoviesourcetypefile; [themovie.movieplayerplay]; } ]; nslog(@"完成!输出路径==%@",outputfilepath); } //通过文件路径建立和添加音频素材 - (void)setupandaddaudioatpath:(nsurl*)asseturltocomposition:(avmutablecomposition*)composition start:(cmtime)startdura:(cmtime)duraoffset:(cmtime)offset{ avurlasset *songasset =[avurlasseturlassetwithurl:asseturloptions:nil]; avmutablecompositiontrack *track =[compositionaddmutabletrackwithmediatype:avmediatypeaudiopreferredtrackid:kcmpersistenttrackid_invalid]; avassettrack *sourceaudiotrack =[[songassettrackswithmediatype:avmediatypeaudio]objectatindex:0]; nserror *error =nil; bool ok =no; cmtime starttime = start; cmtime trackduration = dura; cmtimerange trange =cmtimerangemake(starttime,trackduration); //设置音量 //avmutableaudiomixinputparameters(输入参数可变的音频混合) //audiomixinputparameterswithtrack(音频混音输入参数与轨道) avmutableaudiomixinputparameters *trackmix =[avmutableaudiomixinputparametersaudiomixinputparameterswithtrack:track]; [trackmixsetvolume:0.8fattime:starttime]; //素材加入数组 [audiomixparamsaddobject:trackmix]; //insert audio into track //offsetcmtimemake(0, 44100) ok = [trackinserttimerange:trangeoftrack:sourceaudiotrackattime:kcmtimeinvaliderror:&error]; } #pragma mark - 保存路径 -(nsstring*)getlibaraypath { nsfilemanager *filemanager =[nsfilemanagerdefaultmanager]; nsarray* paths =nssearchpathfordirectoriesindomains(nsdocumentdirectory,nsuserdomainmask,yes); nsstring* path = [pathsobjectatindex:0]; nsstring *movdirectory = [pathstringbyappendingpathcomponent:@"tmpmovmix"]; [filemanagercreatedirectoryatpath:movdirectorywithintermediatedirectories:yesattributes:nilerror:nil]; return movdirectory; }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!