Создание реального медленного видео, которое все медленное движение
Я создаю это приложение и снимаю видео со скоростью 120 и 240 кадров в секунду.
Когда я смотрю эти видео на своем Mac, я вижу эти маркеры под временной шкалой.
Эти маркеры являются редактируемыми и представляют область, которая находится в замедленном режиме. Таким образом, видео начинается с нормальной частотой кадров, входит в замедленное движение и в конце возвращается к нормальной частоте кадров. Я не ставлю эти маркеры там, iOS сделал. В таком случае мне интересно, есть ли способ удалить их и сделать видео полностью замедленным.
Я просто инициализирую AVAssetWriter
как обычно для видео без замедления.
Кроме того, я заметил, что эти "замедленные" видеоролики на самом деле не являются замедленными, но являются "рецептами" замедленного воспроизведения, которые просто воспроизводятся корректно на устройствах iOS и Mac с использованием QuickTime X. Даже QuickTime 7 не воспроизводит их правильно.
В любом случае, чтобы сделать эту вещь действительно медленным движением, которое можно воспроизвести на любом плеере, на любом компьютере?
2 ответа
Ваши "замедленные" видеофайлы на самом деле являются просто видеофайлами с высокой частотой кадров. iOS снижает скорость воспроизведения, чтобы показать лишние кадры в виде замедленной съемки. Проблема заключается в том, что другие проигрыватели воспроизводят со скоростью воспроизведения 1, поэтому, чтобы сделать эффект переносимым, вам нужно вместо этого изменить временные метки представления кадра.
Вы, вероятно, можете сделать это с AVMutableComposition
но я предпочитаю использовать более wysiwyg AVAssetReader
/AVAssetWriter
пара. Примерно так для каждого кадра во входном файле:
if let inSampleBuffer = readerOutput.copyNextSampleBuffer() {
let inTimeStamp = CMSampleBufferGetPresentationTimeStamp(inSampleBuffer)
let outTimeStamp = CMTimeMultiplyByFloat64(inTimeStamp, 30.0/240) // slow 240 fps down to 30fps (8x slowmo)
var outSampleBuffer: CMSampleBuffer?
var outTimingInfo = CMSampleTimingInfo(duration: kCMTimeInvalid, presentationTimeStamp: outTimeStamp, decodeTimeStamp: kCMTimeInvalid)
if CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, inSampleBuffer, 1, &outTimingInfo, &outSampleBuffer) == noErr {
writerInput.appendSampleBuffer(outSampleBuffer!)
}
} else {
// finished
}
это происходит из-за слишком высокой частоты кадров вашего видео. Таким образом, iOS автоматически добавит slowMo в ваше видео. Для тех, кто ищет решение AVComposition для этой проблемы, я нашел два (плохих) решения:
- Установка AVAssetExportSession на AVAssetExportPresetMediumQuality или меньше приведет к снижению частоты кадров, но качество также будет хуже. Нехорошо.
- Установка AVAssetExportSession.videoComposition для композиции видео с frameDuration, которая равна CMTimeMake(1, 30), но экспорт видео с этим занимает очень много времени, что тоже нехорошо. Я не знаю, почему это длилось так долго.
второй - лучшее решение на данный момент. Я опубликовал для этого пример кода:
let videoComposition = AVMutableVideoComposition(propertiesOf: mixComposition)
videoComposition.sourceTrackIDForFrameTiming = kCMPersistentTrackID_Invalid
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
// Changes FPS to 30
//export the video to as per your requirement conversion
if let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {
exportSession.videoComposition = videoComposition
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.mp4
/// try to export the file and handle the status cases
exportSession.exportAsynchronously(completionHandler: {