ScaleTimeRange只是视频的一部分

时间:2017-01-20 10:36:30

标签: ios swift avfoundation avmutablecomposition

如果想要将慢动作效果应用于视频,scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime)方法效果很好。

但我注意到仅在应用于整个视频的持续时间时才有效。如果是任意timeRange,例如传递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
}

1 个答案:

答案 0 :(得分:1)

我的猜测是它正常工作"正确",但是你正在放慢速度的视频部分比你预期的要小得多。

CMTime是一种非常不寻常的数据结构,因此围绕它可能会非常混乱。您用于构建videoDuration.timescaletstStartTime变量的tstDuration的价值是多少?时间刻度值越大,CMTime值表示的时间部分越小。

例如,如果时间刻度为4,则CMTime(value: 2, timescale: 4)表示2/4秒或半秒。

有关详情,请参阅CMTime的文档:https://developer.apple.com/reference/coremedia/1669288-cmtime