【问题标题】:ScaleTimeRange of only a part of video仅部分视频的 ScaleTimeRange
【发布时间】:2017-01-20 10:36:30
【问题描述】:

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

但我注意到它只有在应用于整个视频时才有效。如果是任意时间范围,例如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
}

【问题讨论】:

  • 究竟是什么问题“该方法似乎根本不起作用”?
  • 视频保存成功,但没有慢动作效果。导出的 mp4 文件与源 mp4 文件相同,帧率相同。
  • CMTimes 的价值是什么?可以贴一下相关代码吗?
  • 我更新了问题。请看一看。
  • 如果你这样做了,请分享代码或提示。

标签: ios swift avfoundation avmutablecomposition


【解决方案1】:

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

CMTime 是一种非常不寻常的数据结构,因此您可能会感到非常困惑。您用来构造tstStartTimetstDuration 变量的videoDuration.timescale 的值是多少?时间刻度值越大,CMTime 值表示的时间部分就越小。

例如,如果时间刻度是 4,那么 CMTime(value: 2, timescale: 4) 代表 2/4 秒,或半秒。

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

【讨论】:

  • videoDuration.timescale 的值是 600。我对 timeScale 的作用有一点了解,但我看到它的值是 90000 的代码,这很令人困惑,因为我不知道为什么需要这么高的价值。这是来自苹果的 StopNGo 示例应用程序frameDuration = CMTimeMakeWithSeconds = CMTimeMake(1.0/5/0 , 90000) //5fps - 拍摄五张照片将等于 1 秒的视频。
  • 我不确定他们为该样本选择 90000 时间刻度的具体原因,但 CMTime 以它的方式工作的原因是在广泛的范围内实现极高的精度,没有舍入误差。这是一篇试图更深入地解释它的博客文章:warrenmoore.net/understanding-cmtime
  • 感谢您指出问题。我的假设是scaleTimeRange只能用于整个视频而不是片段,但也许我需要加深对CMTime的理解。
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2013-06-20
相关资源
最近更新 更多