如果是预览视频,添加音乐这个很简单,使用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被初始化过了,后面就不用再初始化了。