iOS视频添加背景音乐同时保留原音

话不多说,请看代码:

//抽取原视频的音频与需要的音乐混合
-(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;
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • iOS App中实现播放音效和音乐功能的简单示例

    播放音效 iOS开发过程中可能会遇到播放音效的功能 其实很简单,iOS已经提供了一个框架直接负责播放音效 AudioToolbox.framework 新建项目  TestWeChatSounds 给新建的项目导入AudioToolbox.framework 导入成功之后如下图 项目目录如下 接下来我们给项目中添加几个caf格式的音效文件 接下来 我们打开 项目默认生成的ViewController中添加代码 导入 AudioToolbox 复制代码 代码如下: #import <AudioTo

  • iOS实现播放远程网络音乐的核心技术点总结

    一.前言 这两天做了个小项目涉及到了远程音乐播放,因为第一次做这种音乐项目,边查资料边做,其中涉及到主要技术点有: 如何播放远程网络音乐 如何切换当前正在播放中的音乐资源 如何监听音乐播放的各种状态(播放器状态.播放的进度.缓冲的进度,播放完成) 如何手动操控播放进度 如何在后台模式或者锁屏情况下正常播放音乐 如何在锁屏模式下显示音乐播放信息和远程操控音乐 如果您对一块技术点有兴趣或者正在寻找相关资料,那么本篇或许能提供一些参考或启发. 二. 网络音乐播放的核心技术点 根据自己的经验和查了一些音

  • iOS利用AVPlayer播放网络音乐的方法教程

    前言 假如你现在打算做一个类似百度音乐.豆瓣电台的在线音乐类APP,你会怎样做? 首先了解一下音频播放的实现级别: (1) 离线播放:这里并不是指应用不联网,而是指播放本地音频文件,包括先下完完成音频文件再进行播放的情况,这种使用AVFoundation里的AVAudioPlayer可以满足 (2) 在线播放:使用AVFoundation的AVPlayer可以满足 (3) 在线播放同时存储文件:使用AudioFileStreamer + AudioQueue 可以满足 (4) 在线播放且带有音效

  • ios开发:一个音乐播放器的设计与实现案例

    这个Demo,关于歌曲播放的主要功能都实现了的.下一曲.上一曲,暂停,根据歌曲的播放进度动态滚动歌词,将当前正在播放的歌词放大显示,拖动进度条,歌曲跟着变化,并且使用Time Profiler进行了优化,还使用XCTest对几个主要的类进行了单元测试. 已经经过真机调试,在真机上可以后台播放音乐,并且锁屏时,显示一些主要的歌曲信息. 根据歌曲的播放来显示对应歌词的.用UITableView来显示歌词,可以手动滚动界面查看后面或者前面的歌词. 并且,当拖动进度条,歌词也会随之变化,下一曲.上一曲依

  • iOS中关于音乐锁屏控制音乐(锁屏信息设置)的实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <pre name="code" class="objc">appDelegate里面加入如下代码获取后台播放权限</pre><pre name="code" class="objc">- (void)setAudioBackstagePlay{ AVAudioSession *audioSession = [AVAudioSession

  • 实例解析iOS中音乐播放器应用开发的基本要点

    一.调整项目的结构,导入必要的素材 调整后的项目结构如下: 二.新建两个控制器 (1)新建一个控制器,用于展示音乐文件列表界面,其继承自UITableViewController (2)新建一个控制器,用于展示播放界面,其继承自UIViewController (3)在storyboard中,把之前的控制器删除,换上一个导航控制器,设置tableViewController与之前新建的控制器类进行关联 三.音乐文件列表控制器中基本界面的搭建 (1)新建一个音乐文件的模型 根据plist文件建立模

  • iOS实现获取系统iTunes音乐的方法示例

    播放音乐库中的音乐 音乐是iOS的重要组成播放,无论是iPod.iTouch.iPhone还是iPad都可以在iTunes购买音乐或添加本地音乐到音乐库中同步到你的iOS设备. 本文将给大家详细介绍关于iOS获取系统iTunes音乐的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 首先来看看效果图 简介 获取类型iTune音乐非常类似于UIKit框架中UIImagePickerController图片选取器的用法,既可以直接使用系统自带的媒体选择器也可以只获取系统的数

  • 运用iOS教你轻松制作音乐播放器

    本文实例为大家分享了iOS音乐播放器制作的具体代码,供大家参考,具体内容如下 效果图 目录结构 代码 // // ViewController.m // 播放音乐 // // Created by xubh on 2017/3/24. // Copyright © 2017年 xubh. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @inte

  • 讲解iOS开发中对音效和音乐播放的简单实现

    音效的播放 一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称"短音频",通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的"背景音乐",一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 复制代码 代码如下: NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_

  • iOS开发中音频工具类的封装以及音乐播放器的细节控制

    一.控制器间数据传递 两个控制器之间数据的传递 第一种方法: 复制代码 代码如下: self.parentViewController.music=self.music[indexPath.row]; 不能满足 第二种做法:把整个数组传递给它 第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器.self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议的可以作为数据源. 第四种做法:把整个项目会使用到的音频资源交给一个工具类去

随机推荐