2016-07-11 3 views
6

여러 오디오 및 배경 오디오 트랙을 결합한 응용 프로그램에서 작업 중입니다. 그것은 또한 다른 비디오에 대해 서로 다른 오디오 레벨을 설정해야합니다.AVMutableAudioMixInputParameters가 AudioMiX에 올바르게 적용되지 않았습니다.

는 다음 방법은 BuildingCompositions

위의 코드에서
func buildCompositionTrack(forExport : Bool) { 

    var cursorTIme = kCMTimeZero 
    var transitionDurationForEffect = kCMTimeZero 

    // Create a mutable composition instructions object 
    var videoCompositionInstructions = [AVMutableVideoCompositionInstruction]() 
    var audioMixInputParameters = [AVMutableAudioMixInputParameters]() 

    let timeRanges = calculateTimeRangeForAssetLayer() 
    self.passThroughTimeRangeValue = timeRanges.passThroughTimeRangeValue 
    self.transitionTimeRangeValue = timeRanges.transitionTimeRangeValue 

    let defaultMuteSoundTrackURL: NSURL = bundle.URLForResource("30sec", withExtension: "mp3")! 
    let muteSoundTrackAsset = AVURLAsset(URL: defaultMuteSoundTrackURL, options: nil) 
    let muteSoundTrack = muteSoundTrackAsset.tracksWithMediaType(AVMediaTypeAudio)[0] 

    for (index,assetItem) in self.assetsList.enumerate() { 
     let trackIndex = index % 2 

     let assetVideoTrack = assetItem.asset.movieAsset.tracksWithMediaType(AVMediaTypeVideo)[0] 

     let timeRange = CMTimeRangeMake(kCMTimeZero, assetItem.videoLength) 

     do { 
      try self.videoTracks[trackIndex].insertTimeRange(timeRange, ofTrack: assetVideoTrack, atTime: cursorTime) 
     } catch let error1 as NSError { 
      error = error1 
     } 
     if error != nil { 
      print("Error: buildCompositionTracks for video with parameter index: %@ and VideoCounts: %@ error: %@", ["\(index)", "\(self.assetsList.count)", "\(error?.description)"]) 
      error = nil 
     } 

     if assetItem.asset.movieAsset.tracksWithMediaType(AVMediaTypeAudio).count > 0 { 
      let clipAudioTrack = assetItem.asset.movieAsset.tracksWithMediaType(AVMediaTypeAudio)[0] 

      do { 
       try audioTracks[trackIndex].insertTimeRange(timeRange, ofTrack: clipAudioTrack, atTime: cursorTime) 
      } catch let error1 as NSError { 
       error = error1 
      } 
     }else { 
      do { 
       try audioTracks[trackIndex].insertTimeRange(timeRange, ofTrack: muteSoundTrack, atTime: cursorTime) 
      }catch let error1 as NSError { 
       error = error1 
      } 
     } 

     // The end of this clip will overlap the start of the next by transitionDuration. 
     // (Note: this arithmetic falls apart if timeRangeInAsset.duration < 2 * transitionDuration.) 

     if assetItem.assetEffect == FLIXAssetEffectType.Default { 

      transitionDurationForEffect = kCMTimeZero 
      let timeRange = CMTimeRangeMake(cursorTime, assetItem.videoLength) 
      self.compositionTimeRanges.append(NSValue(CMTimeRange: timeRange)) 
      cursorTime = CMTimeAdd(cursorTime, assetItem.videoLength) 
     } else { 
      transitionDurationForEffect = self.transitionDuration 
      let timeRange = CMTimeRangeMake(cursorTime, CMTimeSubtract(assetItem.videoLength, transitionDurationForEffect)) 
      self.compositionTimeRanges.append(NSValue(CMTimeRange: timeRange)) 
      cursorTime = CMTimeAdd(cursorTime, assetItem.videoLength) 
      cursorTime = CMTimeSubtract(cursorTime, transitionDurationForEffect) 
     } 

      videoCompositionInstructions.appendContentsOf(self.buildCompositionInstructions(index, assetItem : assetItem)) 

    } 

    if self.project.hasProjectMusicTrack() && self.backgroundMusicTrack != nil { 

     let url: NSURL = bundle.URLForResource("Music9", withExtension: "mp3")! 
     bgMusicSound = AVURLAsset(URL: url, options: nil) 
     backgroundAudioTrack = bgMusicSound.tracksWithMediaType(AVMediaTypeAudio)[0] 

     let compositionBackgroundTrack = self.composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) 

     let soundDuration = CMTimeCompare(bgMusicSound.duration, self.composition.duration) 

     if soundDuration == -1 { 

      let bgMusicSoundTimeRange = CMTimeRangeMake(kCMTimeZero, bgMusicSound.duration) 

      let noOftimes = Int(CMTimeGetSeconds(self.composition.duration)/CMTimeGetSeconds(bgMusicSound.duration)) 
      let remainingTime = CMTimeGetSeconds(self.composition.duration) % CMTimeGetSeconds(bgMusicSound.duration) 

      var musicCursorTime = kCMTimeZero 

      for _ in 0..<noOftimes { 

       do { 
        try compositionBackgroundTrack.insertTimeRange(bgMusicSoundTimeRange, ofTrack: backgroundAudioTrack, atTime: musicCursorTime) 
        } catch let error1 as NSError { 
         error = error1 
        } 
       musicCursorTime = CMTimeAdd(bgMusicSound.duration, musicCursorTime) 
       } 
     } 

      let backgroundMusciMixInputParameters = AVMutableAudioMixInputParameters(track: compositionBackgroundTrack) 
      backgroundMusciMixInputParameters.trackID = compositionBackgroundTrack.trackID 

      // setting up music levels for background music track. 

      for index in 0 ..< Int(self.compositionTimeRanges.count) { 

      let timeRange = self.compositionTimeRanges[index].CMTimeRangeValue 
      let scene = self.assetsList[index].assetSceneType 

      let volumeOfBGMusic = self.assetsList[index].volumeOfBGMusic 
      var nextvolumeOfBGMusic : Float = 0.0 

       if let nextAsset = self.assetsList[safe: index + 1] { 
       nextvolumeOfBGMusic = nextAsset.volumeOfBGMusic 
       } 
       backgroundMusciMixInputParameters.setVolume(volumeOfBGMusic, atTime: timeRange.start) 
     backgroundMusciMixInputParameters.setVolumeRampFromStartVolume(volumeOfBGMusic, toEndVolume: nextvolumeOfBGMusic, timeRange: CMTimeRangeMake(CMTimeSubtract(timeRange.end,CMTimeMake(2, 1)), CMTimeMake(2, 1))) 
     } 

     audioMixInputParameters.append(backgroundMusciMixInputParameters) 

    } // End of If for ProjectMusic Check 


    for (index, assetItem) in self.assetsList.enumerate(){ 

     let trackIndex = index % 2 

     let timeRange = self.compositionTimeRanges[index].CMTimeRangeValue 
     let sceneType = assetItem.assetSceneType 
     let volumnOfVideoMusic = assetItem.volumeOfVideoVoice 

     let audioTrackParamater = AVMutableAudioMixInputParameters(track: self.audioTracks[trackIndex]) 

     audioTrackParamater.trackID = self.audioTracks[trackIndex].trackID 
     audioTrackParamater.setVolume(0.0, atTime: kCMTimeZero) // Statement 1 
     audioTrackParamater.setVolume(volumnOfVideoMusic, atTime: timeRange.start) // Statement 2 
     audioTrackParamater.setVolume(0.0, atTime: timeRange.end) // statement 3 
     audioMixInputParameters.append(audioTrackParamater) 
    } 

    self.audioMix.inputParameters = audioMixInputParameters 
    self.composition.naturalSize = self.videoRenderSize 
    self.videoComposition!.instructions = videoCompositionInstructions 
    self.videoComposition!.renderSize = self.videoRenderSize 
    self.videoComposition!.frameDuration = CMTimeMake(1, 30) 
    self.videoComposition!.renderScale = 1.0  // This is a iPhone only option. 

    } 

을위한 다음, 배경 음악 수준이 제대로 설정되어 & AssetManager 클래스

// AssetItem Class 
class AssetItem : NSObject { 

var asset     : Asset! 
var assetEffect    : AssetEffectType! // Enum 
var assetSceneType   : SceneType!   // Enum 
var videoLength    : CMTime! 
var animationLayer   : AnyObject? 
var volumeOfVideoVoice  : Float = 0.0 
var volumeOfBGMusic   : Float = 0.0 

override init() { 
    super.init() 
    } 
} 

// AssetManager Class implementation 

class AssetManager{ 
var assetList = [AssetItem]() 
var composition      : AVMutableComposition! = AVMutableComposition() 
var videoComposition    : AVMutableVideoComposition? = AVMutableVideoComposition() 
var audioMix      : AVMutableAudioMix = AVMutableAudioMix() 

var transitionDuration    = CMTimeMakeWithSeconds(1, 600) // Default transitionDuration is 1 sec 

var compositionTimeRanges   : [NSValue] = [NSValue]() 

var passThroughTimeRangeValue  : [NSValue] = [NSValue]() 
var transitionTimeRangeValue  : [NSValue] = [NSValue]() 

var videoTracks      = [AVMutableCompositionTrack]() 
var audioTracks      = [AVMutableCompositionTrack]() 


// MARK: - Constructor 
override init() { 

    super.init() 

    let compositionTrackA   = self.composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) 
    let compositionTrackB   = self.composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) 

    let compositionTrackAudioA  = self.composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) 
    let compositionTrackAudioB  = self.composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) 

    self.videoTracks    = [compositionTrackA, compositionTrackB] 
    self.audioTracks    = [compositionTrackAudioA, compositionTrackAudioB] 

    } 

    func buildCompositionTrack(forExport : Bool){ 
     // This is the Method to Build Compositions 
    } 
} 

AssetItem 클래스의 코드이지만, 뭔가 잘못 가고 비디오 트랙의 오디오 레벨. 디버그 컴포지션을 돕기 위해 DebugView를 추가했습니다. 모든 것이 디버그보기에서 완벽하게 보이지만 배경 음악 트랙 이외의 오디오는 더 이상 들리지 않습니다. 내가 잘못하고있는 게 있니?

위의 코드에서 1 번 문을 제거하고 레벨 1.0에서 모든 소리를들을 수 있으며 설정된 수준을 존중하지 않습니다. 새 AVAudioMixInputParameters가 AVMutableCompositionTrack의 각 "클립"에 대한 객체를 사용하고 같은

DebugView of Compositions and Audio Tracks

답변

4

는 것 같습니다. 이 작업은 작동하지 않습니다. 새 오브젝트는 동일한 트랙 ID를 가진 이전 오브젝트와 충돌합니다.

각 AVMutableCompositionTrack에 대해 하나의 AVAudioMixInputParameters 객체를 사용하여 원하는 각 램프 값으로 해당 객체를 업데이트해야합니다.

+0

야, 너 마크맨에 있었어. 나는 지금 바보 같은 느낌. 예, 그것이 문제였습니다. 귀하의 의견을 듣고, 나는 정말로 5 분 안에 문제를 해결했습니다. 당신은 인도를 기반으로하고 있습니까? 당신에게 맥주를 사주는 것을 좋아할 것입니다 :-) – Solid