Ios 仅部分视频的缩放范围

Ios 仅部分视频的缩放范围,ios,swift,avfoundation,avmutablecomposition,Ios,Swift,Avfoundation,Avmutablecomposition,scaleTimeRange(时间范围:CMTimeRange,toDuration duration:CMTime)方法非常适用于想要对视频应用慢动作效果的人 但我注意到,它只适用于整个视频的持续时间。如果传递了任意时间范围,例如CMTimeRangeMake(uu开始:2,持续时间:3),则该方法似乎根本不起作用。i、 e.导出mp4视频时,它没有所需的慢动作效果(从0:00:02到0:00:05) Q 1)是否有办法将此scaleTimeRange方法仅应用于视频的一部分?如果是,如何做到

scaleTimeRange(时间范围:CMTimeRange,toDuration duration:CMTime)
方法非常适用于想要对视频应用慢动作效果的人

但我注意到,它只适用于整个视频的持续时间。如果传递了任意时间范围,例如
CMTimeRangeMake(uu开始:2,持续时间:3)
,则该方法似乎根本不起作用。i、 e.导出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
}

我的猜测是,它工作“正确”,但视频中你正在放慢的部分比你预期的要小得多

CMTime
是一种非常不寻常的数据结构,因此,如果你对它一窍不通,可能会感到非常困惑。用于构造
tstStartTime
tstDuration
变量的
videoDuration.timescale
的值是多少?时间刻度值越大,由
CMTime
值表示的时间部分越小

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


有关更多信息,请参阅
CMTime

什么是isue“该方法似乎根本不起作用”?视频已成功保存,但没有慢动作效果。导出的mp4文件与源mp4文件相同,帧速率相同。什么是
CMTime
s值?你能发布相关代码吗?我更新了问题。请看一看。如果您这样做了,请共享代码或提示。
videoDuration.timescale
的值为600。我对
时间刻度
的作用有一点了解,但我见过值为
90000
的代码,这非常令人困惑,因为我不知道为什么需要这么高的值。这是来自苹果公司的StopNGo示例应用程序
frameDuration=CMTimeMakeWithSeconds=CMTimeMake(1.0/5/09000)
/5fps-拍摄五张照片将相当于一秒的视频。我不确定他们选择90000时间刻度的具体原因,但CMTime之所以能如此工作,是因为它能够在宽范围内实现极高的精度,而不会产生舍入误差。这里有一篇博文试图更深入地解释这个问题:谢谢你指出这个问题。我的假设是
scaleTimeRange
只能用于整个视频,而不能用于片段,但也许我需要加深对
CMTime
的理解。