将CMTimeRange拆分为多个CMTimeRange块 [英] Split CMTimeRange into multiple CMTimeRange chunks

查看:199
本文介绍了将CMTimeRange拆分为多个CMTimeRange块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我有一个从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:

  1. 第一个CMTimeRange-开始时间:0,持续时间:15秒.
  2. 第二个CMTimeRange-开始时间:15,持续时间:15秒.
  3. 第三CMTimeRange-开始时间:30,持续时间:10秒. (left overs)
  1. First CMTimeRange - start time: 0, duration: 15 seconds.
  2. Second CMTimeRange - start time: 15, duration: 15 seconds.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆