Случайные пустые рамки после экспорта актива - AVExportSession
На этот вопрос есть несколько ответов, но мое состояние немного отличается, и ни один из ответов не решает мою проблему.
Задача
Я пытаюсь добавить замедленную рампу к части моего видео (в форме буквы "U"), которую я успешно достиг с помощью следующего кода:
// Description : 1) For a given TimeRange , get the start and end frame.
// 2) Divide this TimeRange to 10 segment
// 3) Scale each segment with a CMTime that
// increments in each iteration of the for loop
func downWithRamp(track : AVMutableCompositionTrack){
let frameTime = CMTimeMake(1, Int32(track.nominalFrameRate))
let x1 : Double = 50
let x2 : Double = 150
let parts = (x2 - x1)/10
let x1Time = CMTimeMultiplyByFloat64(frameTime, x1)
let x2Time = CMTimeMultiplyByFloat64(frameTime, x2)
let tenthDuration = CMTimeMultiplyByFloat64(CMTimeSubtract(x2Time, x1Time) , 1/10)
var scaleFactor = 1.0
var timing = CMTimeMultiplyByFloat64(frameTime, Float64(x1))
for x in Swift.stride(from: x1, to: x2, by: parts ){
print("\(x)th Frame")
let factor = CMTimeMultiplyByFloat64( tenthDuration , 1/scaleFactor) //scale to this time
print("This range will be scaled by \(CMTimeGetSeconds(factor)) seconds")
let timeRange = CMTimeRange(start: timing, duration : tenthDuration)
print("TimeRange = \(CMTimeGetSeconds(timeRange.start)) - \(CMTimeGetSeconds(timeRange.end))secs ")
track.scaleTimeRange(timeRange , toDuration: factor)
if x < x1 + (x2 - x1)/2 {
scaleFactor = scaleFactor + 0.2 }
else { scaleFactor = scaleFactor - 0.2 }
timing = CMTimeAdd(timing, factor)
print()
}}
ПРОБЛЕМА: при воспроизведении ресурса AVPlayer показывает желаемый результат. Однако, когда я пытаюсь экспортировать видео, произвольный сегмент (масштабированный) кажется пустым.
Вот как я экспортирую видео
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsDirectory.appendingPathComponent("rendered-audio.mp4")
deleteFile(filePath)
if let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality){
// exportSession.canPerformMultiplePassesOverSourceMediaData = true
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!)
}
}
}
Некоторые решения предполагают, что проблема заключается в точном времени при использовании scaleTimeRange(..)
, но, насколько я могу судить, этот метод генерирует точные временные характеристики для каждого кадра. Даже регистрация не показывает несоответствия с синхронизацией.
Что может быть причиной этого ужасного препятствия. Любое предложение будет спасением жизни. Спасибо!