iOS AVFoundation - после слияния видео увеличивается - PullRequest
0 голосов
/ 13 февраля 2019

Я работаю над объединением видео с помощью avfoundation, объединение работает нормально, но видео масштабируется, я думаю о 2x, после того, как объединение завершено.Я также сыграл один видеоклип после записи, и он работал нормально.Любая помощь будет оценена.Вы можете увидеть ниже в коде, что я также проверил естественный размер видео (высота, ширина), чтобы убедиться, что все правильно.вот код, который я использую для объединения видеоклипов.

private func doMerge(arrayVideos:[AVAsset], animation:Bool, completion:@escaping Completion) -> Void {
    var insertTime = CMTime.zero
    var arrayLayerInstructions:[AVMutableVideoCompositionLayerInstruction] = []
    var outputSize = CGSize.init(width: 0, height: 0)


    // Determine video output size
    for videoAsset in arrayVideos {
        let videoTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]

        let assetInfo = orientationFromTransform(transform: videoTrack.preferredTransform)

        var videoSize = videoTrack.naturalSize

        print("this is natural size(height, width): \(videoSize.height), \(videoSize.width)")
        if assetInfo.isPortrait == true {
            videoSize.width = videoTrack.naturalSize.height
            videoSize.height = videoTrack.naturalSize.width
        }

        if videoSize.height > outputSize.height {
            outputSize = videoSize
        }
        print("this is output size(height, width): \(outputSize.height), \(outputSize.width)")
    }

    if outputSize.width == 0 || outputSize.height == 0 {
        outputSize = defaultSize
    }

    // Init composition
    let mixComposition = AVMutableComposition.init()

    for videoAsset in arrayVideos {
        // Get video track
        guard let videoTrack = videoAsset.tracks(withMediaType: AVMediaType.video).first else { continue }

        // Init video & audio composition track
        let videoCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

        do {
            let startTime = CMTime.zero
            let duration = videoAsset.duration

            // Add video track to video composition at specific time
            try videoCompositionTrack?.insertTimeRange(CMTimeRangeMake(start: startTime, duration: duration), of: videoTrack, at: insertTime)

            videoCompositionTrack?.preferredTransform = videoTrack.preferredTransform
            // Add instruction for video track

            let layerInstruction = videoCompositionInstructionForTrack(track: videoCompositionTrack!,asset: videoAsset, standardSize: outputSize, atTime: insertTime)

            // Hide video track before changing to new track
            let endTime = CMTimeAdd(insertTime, duration)

            if animation {
                let timeScale = videoAsset.duration.timescale
                let durationAnimation = CMTime.init(seconds: 1, preferredTimescale: timeScale)

                layerInstruction.setOpacityRamp(fromStartOpacity: 1.0, toEndOpacity: 0.0, timeRange: CMTimeRange.init(start: endTime, duration: durationAnimation))
            }
            else {
                layerInstruction.setOpacity(0, at: endTime)
            }

            arrayLayerInstructions.append(layerInstruction)

            // Increase the insert time
            insertTime = CMTimeAdd(insertTime, duration)
        }
        catch {
            print("Load track error")
        }
    }

    // Main video composition instruction
    let mainInstruction = AVMutableVideoCompositionInstruction()
    mainInstruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: insertTime)
    mainInstruction.layerInstructions = arrayLayerInstructions

    // Main video composition
    let mainComposition = AVMutableVideoComposition()
    mainComposition.instructions = [mainInstruction]
    mainComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
    mainComposition.renderSize = outputSize

    // Export to file
    let path = NSTemporaryDirectory().appending("mergedVideo.mp4")
    let exportURL = URL.init(fileURLWithPath: path)

    // Remove file if existed
    FileManager.default.removeItemIfExisted(exportURL)

    // Init exporter
    let exporter = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
    exporter?.outputURL = exportURL
    exporter?.outputFileType = AVFileType.mp4
    exporter?.shouldOptimizeForNetworkUse = true
    exporter?.videoComposition = mainComposition

    // Do export
    exporter?.exportAsynchronously(completionHandler: {
        DispatchQueue.main.async {
            self.exportDidFinish(exporter: exporter, videoURL: exportURL, completion: completion)
        }
    })

}
...