У меня есть видео с этими характеристиками
- Формат: H.264, 1280x544
- ФПС: 25
- Размер данных: 26 МБ
- Продолжительность : 3:00
- Скорость передачи данных: 1,17 Мбит/с
Во время эксперимента я выполнил removeTimeRange(range : CMTimeRange)
для каждого другого кадра (всего кадров = 4225). Это приводит к тому, что видео становится в 2 раза быстрее , поэтому продолжительность становится 1:30.
Однако, когда я экспортирую видео, оно становится в 12 раз больше по размеру, т.е. 325 МБ. Это имеет смысл, поскольку этот метод разбивает видео примерно на 2112 фрагментов и склеивает их вместе. . По-видимому, при этом теряется сжатие между отдельными кадрами, что приводит к огромному размеру.
Это вызывает заикание в видео при воспроизведении с AVPlayer
и, следовательно, низкую производительность.
Вопрос. Как можно применить какое-либо сжатие при склеивании кадров, чтобы видео могло воспроизводиться плавно и иметь меньший размер?
Я только хочу точку в правильном направлении. Спасибо!
КОД
1) Создание AVMutableComposition из актива и его настройка
func configureAssets(){
let options = [AVURLAssetPreferPreciseDurationAndTimingKey : "true"]
let videoAsset = AVURLAsset(url: Bundle.main.url(forResource: "Push", withExtension: "mp4")! , options : options)
let videoAssetSourceTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! as AVAssetTrack
let comp = AVMutableComposition()
let videoCompositionTrack = comp.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
try videoCompositionTrack.insertTimeRange(
CMTimeRangeMake(kCMTimeZero, videoAsset.duration),
of: videoAssetSourceTrack,
at: kCMTimeZero)
deleteSomeFrames(from: comp)
videoCompositionTrack.preferredTransform = videoAssetSourceTrack.preferredTransform
}catch { print(error) }
asset = comp }
2) Удаление каждого второго кадра.
func deleteSomeFrames(from asset : AVMutableComposition){
let fps = Int32(asset.tracks(withMediaType: AVMediaTypeVideo).first!.nominalFrameRate)
let sumTime = Int32(asset.duration.value) / asset.duration.timescale;
let totalFrames = sumTime * fps
let totalTime = Float(CMTimeGetSeconds(asset.duration))
let frameDuration = Double(totalTime / Float(totalFrames))
let frameTime = CMTime(seconds: frameDuration, preferredTimescale: 1000)
for frame in Swift.stride(from: 0, to: totalFrames, by: 2){
let timing = CMTimeMultiplyByFloat64(frameTime, Float64(frame))
print("Asset Duration = \(CMTimeGetSeconds(asset.duration))")
print("")
let timeRange = CMTimeRange(start: timing, duration : frameTime)
asset.removeTimeRange(timeRange)
}
print("duration after time removed = \(CMTimeGetSeconds(asset.duration))")
}
3) Сохранение файла
func createFileFromAsset(_ asset: AVAsset){
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsDirectory.appendingPathComponent("rendered-vid.mp4")
if let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality){
exportSession.outputURL = filePath
exportSession.shouldOptimizeForNetworkUse = true
exportSession.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration)
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.exportAsynchronously {
print("finished: \(filePath) : \(exportSession.status.rawValue) ")
if exportSession.status.rawValue == 4{
print("Export failed -> Reason: \(exportSession.error!.localizedDescription))")
print(exportSession.error!)
}
}}}
4) Наконец, обновите ViewController, чтобы воспроизвести новую композицию!
override func viewDidLoad() {
super.viewDidLoad()
// Create the AVPlayer and play the composition
assetConfig.configureAssets()
let snapshot : AVComposition = assetConfig.asset as! AVComposition
let playerItem = AVPlayerItem(asset : snapshot)
player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = CGRect(x : 0, y : 0, width : self.view.frame.width , height : self.view.frame.height)
self.view.layer.addSublayer(playerLayer)
player?.play()
}
AVMutableComposition
? - person Dave Weston   schedule 06.03.2017AVMutableComposition
. Я обновил вопрос с некоторым кодом. Большое спасибо! - person   schedule 06.03.2017