仅部分视频的 ScaleTimeRange
ScaleTimeRange of only a part of video
如果要对视频应用慢动作效果,scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime)
方法非常有效。
但我注意到它只有应用于整个视频的持续时间才有效。如果是任意时间范围,例如a CMTimeRangeMake(_ start: 2, duration: 3)
passed ,这个方法似乎根本不起作用。即当导出 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
}
我的猜测是它正在工作 "correctly",但是您放慢速度的视频部分比您预期的要小得多。
CMTime
是一种非常不寻常的数据结构,因此绕过它可能会让您非常困惑。您用来构造 tstStartTime
和 tstDuration
变量的 videoDuration.timescale
的值是多少?该时间刻度值越大,由 CMTime
值表示的时间部分就越小。
例如时间刻度为4,则CMTime(value: 2, timescale: 4)
表示2/4
秒,即半秒。
有关详细信息,请参阅 CMTime
的文档:https://developer.apple.com/reference/coremedia/1669288-cmtime
如果要对视频应用慢动作效果,scaleTimeRange(timeRange: CMTimeRange, toDuration duration: CMTime)
方法非常有效。
但我注意到它只有应用于整个视频的持续时间才有效。如果是任意时间范围,例如a CMTimeRangeMake(_ start: 2, duration: 3)
passed ,这个方法似乎根本不起作用。即当导出 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
}
我的猜测是它正在工作 "correctly",但是您放慢速度的视频部分比您预期的要小得多。
CMTime
是一种非常不寻常的数据结构,因此绕过它可能会让您非常困惑。您用来构造 tstStartTime
和 tstDuration
变量的 videoDuration.timescale
的值是多少?该时间刻度值越大,由 CMTime
值表示的时间部分就越小。
例如时间刻度为4,则CMTime(value: 2, timescale: 4)
表示2/4
秒,即半秒。
有关详细信息,请参阅 CMTime
的文档:https://developer.apple.com/reference/coremedia/1669288-cmtime