转载

iOS视频添加音乐 去除原声

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

正文到此结束
Loading...