【问题标题】:Missing Some Videos When Stitching Using AVFoundations使用 AVFoundations 拼接时缺少一些视频
【发布时间】:2020-12-06 06:37:06
【问题描述】:

我正在尝试使用 AVFoundation 合并多个视频。当我只添加两个视频时它工作正常。但是当我尝试添加 3 个视频时,第 2 个视频轨道是空的,但导出视频的总时长是正确的。

这是我的示例代码:

添加视频的代码:

func addVideo(videoAsset: AVAsset, isLast: Bool = false)
{
    // Add video track
    guard let videoTrack = self.mixComposition.addMutableTrack(
       withMediaType: .video,
       preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
       else { return }
        
    do
    {
        try videoTrack.insertTimeRange(
          CMTimeRangeMake(start: .zero, duration: videoAsset.duration),
          of: videoAsset.tracks(withMediaType: .video)[0],
          at: totalVideoTrackDuration)
            
          // Add instruction for this track
          // video helper fixes the video orientation 
          let instruction = VideoHelper.videoCompositionInstruction(videoTrack, asset: videoAsset)
            
          if !isLast
          {
             // hide this clip when its done rendering
             instruction.setOpacity(0.0, at: videoAsset.duration)
          }
            
          // add to layer instruction
          self.instructions.append(instruction)
            
          // get the sum of all added track durations
          self.totalVideoTrackDuration = CMTimeAdd(self.totalVideoTrackDuration, videoAsset.duration)
      }
            
      catch
      {
          print("Failed to load track")
          return
      }
}

这里是导出视频的代码:

func export()
{
   // 6
   let mainInstruction = AVMutableVideoCompositionInstruction()
        
    // set time range
    mainInstruction.timeRange = CMTimeRangeMake(   
       start: .zero,
       duration: self.totalVideoTrackDuration
    )
        
    
    mainInstruction.layerInstructions = self.instructions
        
    let mainComposition = AVMutableVideoComposition()
    mainComposition.instructions = [mainInstruction]
    mainComposition.frameDuration = CMTimeMake(value: 1, timescale: self.timeScale)
    mainComposition.renderSize = self.videoSize
        
    guard let documentDirectory = FileManager.default.urls(
       for: .documentDirectory,
       in: .userDomainMask).first
       else { return }
        
        // file name
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .long
    dateFormatter.timeStyle = .short
    let date = Date().format(format: "mm-dd-yy-HH-mm-ss")!
    let url = documentDirectory.appendingPathComponent("mergeVideo-\(date).mov")
        
    guard let exporter = AVAssetExportSession(
       asset: self.mixComposition,
       presetName: AVAssetExportPresetHighestQuality)
       else { return }
        
    exporter.outputURL = url
    exporter.outputFileType = AVFileType.mov
    exporter.shouldOptimizeForNetworkUse = true
    exporter.videoComposition = mainComposition
     
    exporter.exportAsynchronously {
            
    PHPhotoLibrary.shared().performChanges({ 
       PHAssetChangeRequest.
          creationRequestForAssetFromVideo(
            atFileURL: exporter.outputURL!)
          }){ 

          saved, error in
          
             if saved 
             {
                print("Export successful")
             } 
             else
             {
                print("video erro: \(error)")
             }
        }
    }
}

这是我如何调用addVideo 函数:

// 4-second video
self.addVideo(videoAsset: asset1) 

// 3-second video
self.addVideo(videoAsset: asset2) 

// 4-second video
self.addVideo(videoAsset: asset3, isLast: true)

// export
self.export()

// the total duration of the exported video is 11 seconds. But the middle part, is blank.

【问题讨论】:

    标签: ios swift video avfoundation video-editing


    【解决方案1】:

    原来有问题的行是:

    if !isLast
    {
       // hide this clip when its done rendering
       instruction.setOpacity(0.0, at: videoAsset.duration)
    }
    
    // get the sum of all added track durations
    self.totalVideoTrackDuration = CMTimeAdd(self.totalVideoTrackDuration, videoAsset.duration)
    
    

    应该是:

    // get the sum of all added track durations
    self.totalVideoTrackDuration = CMTimeAdd(self.totalVideoTrackDuration, videoAsset.duration)
    
    if !isLast
    {
       instruction.setOpacity(0.0, at: self.totalVideoTrackDuration)
    }
    

    setOpacity 的文档有点混乱。我认为at 参数是该特定视频时间范围内的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多