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/
FFmpeg - Ultimate Guide | IMG.LY Blog
This guide covers the ins and outs of FFmpeg starting with fundamental concepts and moving to media transcoding and video and audio processing providing practical examples along the way.
img.ly
[참조2] https://present.do/documents/636474014e11750badbcb4cc?page=0
FFmpeg
Brief introduction of FFmpeg and its tool(ffmpeg) and how I managed to changed the video exporting logic
present.do
[참조3] https://testfairy.com/blog/fine-tuned-video-compression-in-ios-swift-4-no-dependencies/
Fine Tuned Video Compression in iOS (Swift 4, no dependencies)
Working compression code, configurable a/v bitrate, video resolution, audio sample rate and many other fine tuning operations
testfairy.com
GitHub - testfairy-blog/VideoCompressionTutorial: iOS - Fine tuned video compression in Swift 4
iOS - Fine tuned video compression in Swift 4. Contribute to testfairy-blog/VideoCompressionTutorial development by creating an account on GitHub.
github.com
'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 |