2017-07-25 16 views
0

私の質問は、以下の関数を使ってビデオとオーディオを構成しています。私はビデオの元の音を保ちたいと思っていますが、何とか消えてしまいます。私は何の手がかりも持っていません。ビデオとオーディオの作成 - ビデオのオーディオがなくなった

私は右のAVMutableCompositionTrack秒を付加した後、ボリュームを変更しようとしましたが、それは例えば

を動作しませんでしたthis answer

からこの機能を得ました。

mutableVideoCompositionTrack.prefferedVolume = 1.0 
mutableAudioCompositionTrack.prefferedVolume = 0.05 

まだ聞こえるのは、音声ファイルだけです。

関数です。

private func mergeAudioAndVideo(audioUrl: URL, videoUrl: URL, completion: @escaping (Bool)->Void){ 

    let mixComposition = AVMutableComposition() 
    var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = [] 
    var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = [] 
    let totalVideoCompositionInstruction = AVMutableVideoCompositionInstruction() 

    let videoAsset = AVAsset(url: videoUrl) 
    let audioAsset = AVAsset(url: audioUrl) 

    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)) 
    mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)) 
    mutableCompositionAudioTrack[0].preferredVolume = 0.05 
    mutableCompositionVideoTrack[0].preferredVolume = 1.0   


    let videoAssetTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 
    let audioAssetTrack = audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 

    do { 
     try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration), of: videoAssetTrack, at: kCMTimeZero) 
     try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration), of: audioAssetTrack, at: kCMTimeZero) 
    }catch{ 
     print("ERROR#1") 
    } 

    totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAssetTrack.timeRange.duration) 

    let mutableVideoComposition = AVMutableVideoComposition() 
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30) 
    mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720) 

    //exporting 

    savePathUrl = try! FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("merged").appendingPathExtension("mov") 

    let assetExport = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)! 
    assetExport.outputFileType = AVFileTypeMPEG4 
    assetExport.outputURL = savePathUrl 
    assetExport.shouldOptimizeForNetworkUse = true 

    do { 
     try FileManager.default.removeItem(at: savePathUrl) 
    }catch { 
     print(error) 
    } 

    assetExport.exportAsynchronously { 
     switch assetExport.status{ 
     case .completed: 
      print("completed") 
      completion(true) 
     default: 
      print("failed \(assetExport.error!)") 
      completion(false) 
     } 
    } 

} 

答えて

1

私はそれを理解しました。ビデオをロードするAVAssetのように、オーディオとビデオを別々に保持しているようです。だから、だから私はコードにこれらの行を追加し、それが働いた

videoAsset.tracks(withMediaType: AVMediaTypeAudio)[0] //audio of a video 
videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] //video of a video(without sound) 

writing``それらに到達することができます!

​​

私は、方法がわからず、これらのオーディオアセットのボリュームを設定しています。方法を見つけたらすぐにこの回答を更新します。

+0

私は最終的なビデオを再生しながら、それは両方のオーディオを果たしているように、一つのファイルに私のカスタムサウンドとビデオのオーディオを維持したいです。この機能はこれで可能ですか? – parth

+0

これはまさに私がここでやったことです。しかし、私が言ったように、私はどのように各オーディオの音量レベルを変更するか分からない。 @parth – Faruk

1

ビデオとオーディオの音量を個別に調整することができます@Faruk、ここでは少しのコードです。

 //Extract audio from the video and the music 
let audioMix: AVMutableAudioMix = AVMutableAudioMix() 
var audioMixParam: [AVMutableAudioMixInputParameters] = [] 

let assetVideoTrack: AVAssetTrack = assetVideo.tracksWithMediaType(AVMediaTypeAudio)[0] 
let assetMusicTrack: AVAssetTrack = assetMusic.tracksWithMediaType(AVMediaTypeAudio)[0] 

let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack) 
videoParam.trackID = compositionAudioVideo.trackID 

let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack) 
musicParam.trackID = compositionAudioMusic.trackID 

//Set final volume of the audio record and the music 
videoParam.setVolume(volumeVideo, atTime: kCMTimeZero) 
musicParam.setVolume(volumeAudio, atTime: kCMTimeZero) 

//Add setting 
audioMixParam.append(musicParam) 
audioMixParam.append(videoParam) 

//Add audio on final record 
//First: the audio of the record and Second: the music 
do { 
try compositionAudioVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, assetVideo.duration), ofTrack: assetVideoTrack, atTime: kCMTimeZero) 
} catch _ { 
assertionFailure() 
} 

do { 
try compositionAudioMusic.insertTimeRange(CMTimeRangeMake(CMTimeMake(Int64(startAudioTime * 10000), 10000), assetVideo.duration), ofTrack: assetMusicTrack, atTime: kCMTimeZero) 
} catch _ { 
assertionFailure() 
} 

//Add parameter 
audioMix.inputParameters = audioMixParam 

let completeMovie = "\(docsDir)/\(randomString(5)).mp4" 
let completeMovieUrl = NSURL(fileURLWithPath: completeMovie) 
let exporter: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)! 

exporter.outputURL = completeMovieUrl 
exporter.outputFileType = AVFileTypeMPEG4 
exporter.audioMix = audioMix 
exporter.exportAsynchronouslyWithCompletionHandler({ 

switch exporter.status { 

case AVAssetExportSessionStatus.Completed: 
    print("success with output url \(completeMovieUrl)") 
    case AVAssetExportSessionStatus.Failed: 
     print("failed \(String(exporter.error))") 
    case AVAssetExportSessionStatus.Cancelled: 
     print("cancelled \(String(exporter.error))") 
    default: 
     print("complete") 
    }    
}) 

}

関連する問題