如果是预览视频,添加音乐这个很简单,使用AVAudioPlayer来播放音乐,目前我所做的是播放导入在工程本地的音乐文件,在线网络音乐添加尚未涉及。视频播放使用AVplayer。 下面是切换背景音乐的方法:
-(void)anotherMusic:(NSURL *)url withVolume:(CGFloat)volume{ _usingMusic = YES; _musicUrl = url; _musicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil]; [_musicPlayer setVolume:volume]; [_musicPlayer prepareToPlay]; [_musicPlayer play]; }
我的功能基本是仿照微博发布视频做的,也有声音大小控制。一行代码控制,超级简单。
-(void)changeMusic:(CGFloat)value{ [_musicPlayer setVolume:value]; _musicVolume = value; }
如果要关闭背景音乐,调用AVAudioPlayer 的stop方法就行。 如果要控制原声:(想要静音直接将声音的值设为0)
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:_videoUrl options:nil]; NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio]; if(audioTracks.count>0){ AVAssetTrack *assetAudioTrack = audioTracks.firstObject; audioTrack = assetAudioTrack; AVMutableAudioMixInputParameters* audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters]; [audioInputParams setVolume:value atTime:kCMTimeZero]; [audioInputParams setTrackID:[assetAudioTrack trackID]]; NSArray* audioParams = [NSArray arrayWithObject:audioInputParams]; AVMutableAudioMix* audioMix = [AVMutableAudioMix audioMix]; [audioMix setInputParameters:audioParams]; [self.playItem setAudioMix:audioMix];
上面都只是预览时可见的效果,这个时候并没有真正的将你要的背景音乐加到视频中去。我们获取视频的videoTrack和audioTrack进行相应地处理合成再导出,这样才算真正的控制了视频的一切。视频原声的控制(包括音量大小或者直接静音我是写在一个方法中,方便我控制,你也可以写两个方法,静音时不加入audioTrack,但我觉得两个方法麻烦,一个方法简单点)
-(void)removeAudioTrack:(AVAsset*)asset{ self.mutableComposition = [AVMutableComposition composition]; AVMutableCompositionTrack *compositionVideoTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; AVAssetTrack *videoTrack = nil; AVAssetTrack *assetAudioTrack = nil; if([asset tracksWithMediaType:AVMediaTypeVideo].count!=0){ videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0]; } CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, videoTrack.timeRange.duration); if(videoTrack!=nil){ [compositionVideoTrack insertTimeRange:timeRange ofTrack:videoTrack atTime:kCMTimeZero error:nil]; } //测试改变原声 if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) { assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0]; } if (assetAudioTrack != nil) { AVMutableCompositionTrack *compositionAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetAudioTrack.timeRange.duration) ofTrack:assetAudioTrack atTime:kCMTimeZero error:nil]; AVMutableAudioMixInputParameters *mixParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTrack]; [mixParameters setVolumeRampFromStartVolume:_sound toEndVolume:_sound timeRange:CMTimeRangeMake(kCMTimeZero,assetAudioTrack.timeRange.duration)]; self.mutableAudioMix = [AVMutableAudioMix audioMix]; self.mutableAudioMix.inputParameters = @[mixParameters]; } //导出 self.exportSession = [[AVAssetExportSession alloc] initWithAsset:[self.mutableComposition copy] presetName:AVAssetExportPreset1280x720]; // } self.exportSession.videoComposition = self.mutableVideoComposition; self.exportSession.audioMix = self.mutableAudioMix; self.exportSession.outputURL = [NSURL fileURLWithPath:outputURL]; self.exportSession.outputFileType=AVFileTypeQuickTimeMovie; self.exportSession.shouldOptimizeForNetworkUse = YES; [self.exportSession exportAsynchronouslyWithCompletionHandler:^(void){ switch (self.exportSession.status) { case AVAssetExportSessionStatusCompleted:{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ [self writeVideoToPhotoLibrary:[NSURL fileURLWithPath:outputURL]]; }); // Step 3 // Notify AVSEViewController about export completion [[NSNotificationCenter defaultCenter] postNotificationName:AVSEExportCommandCompletionNotification object:self]; } break; case AVAssetExportSessionStatusFailed: NSLog(@"导出失败:Failed:%@",self.exportSession.error); break; case AVAssetExportSessionStatusCancelled: NSLog(@"导出取消:Canceled:%@",self.exportSession.error); break; default: break; } }];
添加本地音乐,传入url。
-(void)addMusic:(AVAsset*)asset{ CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]); AVMutableCompositionTrack *customAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; AVAssetTrack *assetAudioTrack = nil; if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) { assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0]; } AVAsset *audioAsset = [[AVURLAsset alloc] initWithURL:_musicUrl options:nil]; AVAssetTrack *newAudioTrack = [audioAsset tracksWithMediaType:AVMediaTypeAudio][0]; [customAudioTrack insertTimeRange:timeRange ofTrack:newAudioTrack atTime:kCMTimeZero error:nil]; AVMutableAudioMixInputParameters *mixParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:customAudioTrack]; [mixParameters setVolumeRampFromStartVolume:_music toEndVolume:_music timeRange:CMTimeRangeMake(kCMTimeZero,asset.duration)]; NSMutableArray *mut = [NSMutableArray arrayWithArray:self.mutableAudioMix.inputParameters]; [mut addObject:mixParameters]; self.mutableAudioMix.inputParameters = mut;
对了,上面代码还有一个需要注意的地方,如果你只调用addMusic方法,记得 self.mutableAudioMix = [AVMutableAudioMix audioMix]; 我上面的代码是音乐先调用了removeAudioTrack方法,self,mutableAudioMix被初始化过了,后面就不用再初始化了。