2017-01-20 13 views
2

scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime) метод работает очень хорошо, если один хочет, чтобы применить эффект замедленного движения на видео.ScaleTimeRange только часть видео

Но я заметил, что он работает только в том случае, если применяется ко всему видео. Если произвольное значение времени, например, CMTimeRangeMake(_ start: 2, duration: 3), метод, похоже, не работает вообще. то есть когда mp4 видео экспортируется он не имеет желаемый эффект медленного движения (от 0:00:02 - 0:00:05)

Q 1) Есть ли способ, чтобы применить этот метод к scaleTimeRange только часть видео? Если да, то как это можно сделать?

Q2) Если нет, то как это влияние замедленного движения может быть применено только к части видео? Есть ли другой путь?

КОД:

var asset: AVAsset? 


func setupAsset(){ 

let videoAsset = AVURLAsset(url: Bundle.main.url(forResource: "Sample", withExtension: "mp4")!) 

let comp = AVMutableComposition() 

let videoAssetSourceTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! as AVAssetTrack 


let videoCompositionTrack = comp.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) 


do { 

    try videoCompositionTrack.insertTimeRange(
     CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(9 , 600)), 
     of: videoAssetSourceTrack, 
     at: kCMTimeZero) 


    let videoScaleFactor = Int64(3.0) 
    let videoDuration: CMTime = videoAsset.duration 



    let tstStartTime = CMTime(value: 2, timescale: videoDuration.timescale) 
    let tstDuration = CMTime(value: 1 , timescale: videoDuration.timescale) 

    //1. Applies slow motion correctly (to entire video) 

    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(kCMTimeZero , videoDuration), toDuration: CMTimeMake(videoDuration.value * videoScaleFactor, videoDuration.timescale)) 

    //2. Replace with 1 , the exported video plays as is with no slow motion effect 

    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(kCMTimeZero , tstDuration), toDuration: CMTimeMake(tstDuration.value * videoScaleFactor, videoDuration.timescale)) 

    // 3. Replace with 1, unexpected behaviour : video only displays first frame for CMTimeMakes's value then proceeds to play video normally. 
    videoCompositionTrack.scaleTimeRange(CMTimeRangeMake(tstStartTime , tstDuration), toDuration: CMTimeMake(tstDuration.value * videoScaleFactor, videoDuration.timescale)) 



    videoCompositionTrack.preferredTransform = videoAssetSourceTrack.preferredTransform 



}catch { print(error) } 

asset = comp 
} 
+0

Что именно является isue «метод, кажется, не работает»? – shallowThought

+0

Видео сохраняется успешно, однако эффекта замедленного движения нет. Экспортированный файл mp4 идентичен файлу источника mp4 с той же частотой кадров. –

+0

Что такое 'CMTime's value? Можете ли вы разместить соответствующий код, пожалуйста? – shallowThought

ответ

1

Я думаю, что это работает «правильно», но часть видео, вы замедляя гораздо, гораздо меньше, чем вы ожидаете.

CMTime очень необычная структура данных, так что это может быть очень запутанным, чтобы обернуть голову вокруг него. Какова стоимость videoDuration.timescale, что вы используете для построения tstStartTime и tstDuration переменных? Чем больше значение шкалы времени, тем меньше доля времени, которая представлена ​​значением CMTime.

Например, если временная шкала равна 4, то CMTime(value: 2, timescale: 4) представляет 2/4 секунд или половину секунды.

Для получения дополнительной информации обратитесь к документации по CMTime: https://developer.apple.com/reference/coremedia/1669288-cmtime

+0

Значение 'videoDuration.timescale' 600. У меня есть небольшое представление о том, что делает' timeScale', но я видел код, где это значение '90000', и это очень странно, потому что я не знаю почему такая высокая ценность необходима. Это из образца приложения StopNGo яблока 'frameDuration = CMTimeMakeWithSeconds = CMTimeMake (1,0/5/0, 90000)' // 5fps - принимая пять снимков будет равна 1 сек видео. –

+0

Я не уверен в конкретных причинах, почему они выбрали временную шкалу из 90000 для этого образца, но причина, почему CMTime работает так, как это делает для того, чтобы чрезвычайно высокой точности в широком диапазоне, без ошибки округления. Вот сообщение в блоге, которое пытается объяснить его более подробно: https://warrenmoore.net/understanding-cmtime –

+1

Спасибо, что указали на проблему. Мое предположение заключалось в том, что «scaleTimeRange» можно было использовать только для всего видео, а не для сегмента, но, возможно, мне нужно углубить свое понимание «CMTime». –