AVFoundation - 비디오의 인코딩(압축) 및 업로드(1) - Export Session 이용
2023. 3. 18. 12:38ㆍiOS/이슈
비디오의 압축
비디오 업로드 시, AWS 서버 비용 때문에 용량을 줄여달라는 요구 사항이 있었다. 그래서 ExportSession를 거쳐 Asset Reader/Writer를 적용한 경험을 포스팅해보려고 한다.
애플 도큐먼트에는 가능하면 버전이 업데이트 될 수록 최신 기술들(HDR 등)이 적용될 테니 프리셋을 사용하라고 나와있었다. custom하면 대응해줘야하기 때문이다. 하지만 프리셋 만으로 원하는 크기만큼 인코딩(압축)되지 않았고, Asset reader/writer를 사용하기로 했다.
간단한 이론
비디오는 무엇인가? FFmpeg는 무엇인가?에 대한 설명들이 참조 링크에 잘 설명되어 있다.
아래 [참조 2]를 보고 [참조 1]을 보는 것을 추천한다.
자세한 내용은 따로 글 써봐야지
ExportSession
// compress completion
......
do {
let composition = try createMutableComposition(asset, range: range)
let session = try createExportSession(composition, preferedPreset: preferredPreset, range: range, outputURL: outputURL)
// session의 프로그래스값을 프로그래스바로 전달하기 위해 sleep()을 줌
// https://stackoverflow.com/questions/45198189/swift-3-how-to-export-video-with-text-using-avvideocomposition
DispatchQueue.main.async {
let progress = session.progress
progressBlock(progress)
sleep(1)
}
session.exportAsynchronously {
switch session.status {
case .failed:
Log.error("Failed: \(session.error?.localizedDescription ?? "unknown")")
completion(.failure(.InProgressError))
case .completed:
completion(.success(outputURL))
default: break
}
}
} catch {
guard let error = error as? VideoError else { return completion(.failure(.unknown)) }
completion(.failure(error))
}
// [참조3]포스팅의 깃헙 소스 참조함
// https://github.com/testfairy-blog/VideoCompressionTutorial/blob/master/VideoCompressionTutorial/VideoCompression.swift
private func createMutableComposition(_ asset: AVAsset, range: CMTimeRange) throws -> AVMutableComposition {
// 트랙 체크 및 트랙 추출
guard asset.isExportable,
let sourceVideoTrack = asset.tracks(withMediaType: .video).first,
let sourceAudioTrack = asset.tracks(withMediaType: .audio).first
else {
Log.error("Track is not exportable")
throw VideoError.trackError
}
// mutable한 트랙 생성 및 트랙 생성
let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)
)
// 트랙에 추출한 트랙 삽입 및 범위 지정
do {
try compositionVideoTrack?.insertTimeRange(range, of: sourceVideoTrack, at: .zero)
try compositionAudioTrack?.insertTimeRange(range, of: sourceAudioTrack, at: .zero)
compositionVideoTrack?.preferredTransform = sourceVideoTrack.preferredTransform
} catch {
Log.error("Track insert error")
throw VideoError.trackError
}
return composition
}
private func createExportSession(_ composition: AVMutableComposition, preferedPreset: String, range: CMTimeRange, outputURL: URL) throws -> AVAssetExportSession {
// 적용 가능 프리셋
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: composition)
// 프리셋 무시
var preset = AVAssetExportPresetPassthrough
// 프리셋이 적용 가능하면 변수에 대입
if compatiblePresets.contains(preferedPreset) {
preset = preferedPreset
}
let fileType: AVFileType = .mp4
// 세션 생성
guard
let exportSession = AVAssetExportSession(asset: composition, presetName: preset),
exportSession.supportedFileTypes.contains(fileType)
else {
throw VideoError.exportSessionError
}
// Set Session
exportSession.timeRange = range
exportSession.outputURL = outputURL
exportSession.outputFileType = fileType
exportSession.shouldOptimizeForNetworkUse = true
return exportSession
}
[참조1] https://img.ly/blog/ultimate-guide-to-ffmpeg/
[참조2] https://present.do/documents/636474014e11750badbcb4cc?page=0
[참조3] https://testfairy.com/blog/fine-tuned-video-compression-in-ios-swift-4-no-dependencies/
'iOS > 이슈' 카테고리의 다른 글
AVFoundation - 비디오의 인코딩(압축) 및 업로드(3) - 업로드 개선 (0) | 2023.03.21 |
---|---|
AVFoundation - 비디오의 인코딩(압축) 및 업로드(2) - AssetReader / Writer 이용 (0) | 2023.03.20 |
잘못된 코드로 인하여 AWS 폭탄 맞은 이야기 (0) | 2023.03.17 |
[AVAsset]에서 duration load delay 이슈 (0) | 2023.02.03 |
iOS 16 orientation change (0) | 2023.01.27 |