[ios] VideoToolbox를 사용한 비디오 분할 및 병합

iOS 앱을 개발하는 중에 비디오 관련 기능을 구현해야 하는 경우가 많습니다. 비디오를 분할하여 여러 부분으로 나누거나, 여러 개의 비디오를 하나로 병합하는 작업은 매우 일반적입니다. iOS에서 이러한 작업을 간편하게 처리할 수 있는 옵션으로 VideoToolbox를 활용할 수 있습니다.

이 기술 블로그에서는 VideoToolbox를 사용하여 iOS 앱에서 비디오를 분할하고 병합하는 방법에 대해 알아보겠습니다.

1. VideoToolbox란?

VideoToolbox는 iOS 및 macOS에서 비디오 처리를 위한 프레임워크로, 비디오 디코딩, 인코딩, 및 처리 관련 작업을 효율적으로 수행할 수 있도록 지원합니다. 이를 사용하여 비디오 스트림에서 샘플 버퍼를 추출하거나, 샘플 버퍼를 이용하여 새로운 비디오 스트림을 생성할 수 있습니다.

2. 비디오 분할하기

비디오를 분할하여 여러 부분으로 나누는 방법은 다음과 같습니다.

import AVFoundation

func splitVideo(inputURL: URL, timeRange: CMTimeRange, outputURL: URL, completion: @escaping (Error?) -> Void) {
    let asset = AVURLAsset(url: inputURL)
    
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
        completion(NSError(domain: "com.example", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetExportSession"]))
        return
    }
    
    exportSession.outputURL = outputURL
    exportSession.outputFileType = AVFileType.mp4
    exportSession.timeRange = timeRange
    
    exportSession.exportAsynchronously {
        if let error = exportSession.error {
            completion(error)
        } else {
            completion(nil)
        }
    }
}

3. 비디오 병합하기

여러 개의 비디오를 하나로 병합하는 방법은 다음과 같습니다.

func mergeVideos(videoURLs: [URL], outputURL: URL, completion: @escaping (Error?) -> Void) {
    let composition = AVMutableComposition()
    var currentTime: CMTime = CMTime.zero
    
    for videoURL in videoURLs {
        let asset = AVURLAsset(url: videoURL)
        guard let track = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) else {
            completion(NSError(domain: "com.example", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetTrack"]))
            return
        }
        
        do {
            try track.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .video)[0], at: currentTime)
        } catch {
            completion(error)
            return
        }
        
        currentTime = CMTimeAdd(currentTime, asset.duration)
    }
    
    guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough) else {
        completion(NSError(domain: "com.example", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetExportSession"]))
        return
    }
    
    exportSession.outputURL = outputURL
    exportSession.outputFileType = AVFileType.mp4
    
    exportSession.exportAsynchronously {
        if let error = exportSession.error {
            completion(error)
        } else {
            completion(nil)
        }
    }
}

4. 결론

VideoToolbox를 사용하면 iOS 앱에서 비디오 분할 및 병합과 같은 작업을 쉽게 수행할 수 있습니다. 이 외에도 다양한 비디오 처리 기능을 제공하므로, 비디오 관련 기능을 개발하는 경우에 유용하게 활용할 수 있습니다.

참고 문헌: