将CMTimeRange拆分为多个CMTimeRange块 [英] Split CMTimeRange into multiple CMTimeRange chunks
问题描述
让我们假设我有一个从start time
零构造的CMTimeRange
,并且
duration
40秒.
Lets assume I have a CMTimeRange
constructed from start time
zero, and
duration
of 40 seconds.
我想用 X 秒分隔符将此CMTimeRange
分成多个块.因此,块的total duration
将与原始持续时间相同,并且每个startTime
都将反映前一个块的endTime
.最后一块将是剩余秒数的模量.
I want to split this CMTimeRange
into multiple chunks by a X seconds divider. So the total duration
of the chunks will be the same duration
as the original duration, and each startTime
will reflect the endTime
of of the previous chunk. The last chunk will be the modulus of the left over seconds.
例如,对于 40 秒的视频和每个块 15 秒的分频器:
For example, for video of 40 seconds, and divider of 15 seconds per chunk:
- 第一个
CMTimeRange
-开始时间:0,持续时间:15秒. - 第二个
CMTimeRange
-开始时间:15,持续时间:15秒. - 第三
CMTimeRange
-开始时间:30,持续时间:10秒.(left overs)
- First
CMTimeRange
- start time: 0, duration: 15 seconds. - Second
CMTimeRange
- start time: 15, duration: 15 seconds. - Third
CMTimeRange
- start time: 30, duration: 10 seconds.(left overs)
我尝试过的事情:
我尝试在总持续时间上使用CMTimeSubtract
,然后以递归方式再次使用结果,直到CMTime无效为止,但这似乎不起作用.
I tried using CMTimeSubtract
on the total duration and use the result again, in recursive way untill the CMTime in invalid, But it doesn't seems to work.
我们将不胜感激任何帮助.
最好的问候,投资回报率
推荐答案
从range.start
开始,创建给定长度的范围
直到达到range.end
:
Starting at range.start
, create ranges of the given length
until range.end
is reached:
func splitIntoChunks(range: CMTimeRange, length: CMTime) -> [CMTimeRange] {
var chunks: [CMTimeRange] = []
var from = range.start
while from < range.end {
chunks.append(CMTimeRange(start: from, duration: length).intersection(range))
from = from + length
}
return chunks
}
intersection
在这里用于将最后一个块修剪到原始范围.
intersection
is used here to prune the last chunk to the original range.
替代解决方案:
func splitIntoChunks(range: CMTimeRange, length: CMTime) -> [CMTimeRange] {
return stride(from: range.start.seconds, to: range.end.seconds, by: length.seconds).map {
CMTimeRange(start: CMTime(seconds: $0, preferredTimescale: length.timescale), duration: length)
.intersection(range)
}
}
具有自定义扩展名,使CMTime
采用 Strideable
协议
With a custom extension to make CMTime
adopt the Strideable
protocol
extension CMTime: Strideable {
public func distance(to other: CMTime) -> TimeInterval {
return other - self
}
public func advanced(by n: TimeInterval) -> CMTime {
return self + n
}
}
这可以进一步简化为
func splitIntoChunks(range: CMTimeRange, length: CMTime) -> [CMTimeRange] {
return stride(from: range.start, to: range.end, by: length.seconds).map {
CMTimeRange(start: $0, duration: length) .intersection(range)
}
}
无论如何,您可能要添加支票
In any case, you'll might want to add a check
precondition(length.seconds > 0, "length must be positive")
功能,以便在开发过程中检测到无效调用.
to your function, in order to detect invalid calls during development.
这篇关于将CMTimeRange拆分为多个CMTimeRange块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!