Как передать Float в шкале времени CMTimeMake Int32

Я работаю над CMTimeMake, чтобы добавить эффект замедленного и ускоренного движения к видео. Где мы должны разделить на масштаб видео для быстрого эффекта и умножить на масштаб видео для медленного эффекта.

Вот:

let videoScaleFactor = Int64(2)

// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(videoAsset.duration.value / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(videoAsset.duration.value * videoScaleFactor, videoAsset.duration.timescale)

Теперь, согласно моему требованию, есть один ползунок (от 0,1 до 2,0), где пользователь будет выбирать конкретное значение масштаба видео для медленного и быстрого эффекта. Это значение входит в число с плавающей запятой.

Моя проблема заключается в том, что когда я передаю значение с плавающей запятой, например 0,8, в приведенном выше коде, тогда:

let videoScaleFactor = Int64(0.8) // это возвращает мне 0

Как я могу вернуть точное значение 0,8 в это? Пожалуйста, посоветуй мне.


person user2786    schedule 03.08.2018    source источник
comment
Не используйте Int64 для videoScaleFactor, используйте Float.   -  person Larme    schedule 03.08.2018
comment
Я могу использовать, но когда я использую Float, это дает мне ошибку, как будто это должно быть Int64.   -  person user2786    schedule 03.08.2018
comment
Поскольку CMTimeMake(_:_:) ожидает Int64, то Int32. Что вам нужно сделать CMTimeMake(Int64(videoAsset.duration.value / videoScaleFactor), ...) и т. д., где videoScaleFactor — это Float. Другими словами, используйте Float/Double или другие для вычисления, но затем конвертируйте в Int64.   -  person Larme    schedule 03.08.2018
comment
когда я пытаюсь сделать так: let videoScaleFactor = Float(0.12) let scaledVideoDuration = (mode == .Faster)? CMTimeMake(Int64(videoAsset.duration.value/videoScaleFactor), videoAsset.duration.timescale) : CMTimeMake(Int64(videoAsset.duration.value * videoScaleFactor), videoAsset.duration.timescale) затем возникает ошибка: бинарный оператор '/' не может быть применяется к операндам типа «CMTimeValue» (он же «Int64») и «Float»   -  person user2786    schedule 03.08.2018
comment
Можно ли передать напрямую мое значение Float?   -  person user2786    schedule 03.08.2018
comment
Думаю, это потому, что videoAsset.duration.value - это Int64. Затем сделайте CMTimeMake(Int64(Float(videoAsset.duration.value) / videoScaleFactor),...   -  person Larme    schedule 03.08.2018
comment
Давайте продолжим обсуждение в чате.   -  person user2786    schedule 03.08.2018


Ответы (1)


Вы написали:

let videoScaleFactor = Int64(0.8) // this returns me 0

Это нормально, потому что по определению не может иметь десятичного значения. Итак, 0,8 => 0.

Вместо этого используйте Float (или Double) в зависимости от необходимой точности.

Итак, давайте попробуем:

let videoScaleFactor = Float(0.8)

// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(videoAsset.duration.value / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(videoAsset.duration.value * videoScaleFactor, videoAsset.duration.timescale)

Это поднимает другую проблему:

Двоичный оператор «/» не может применяться к операндам типа «CMTimeValue» (он же «Int64») и «Float».

Действительно, в Swift вы не можете манипулировать различными типами Int/Float и т.д.

Итак, чтобы исправить это:

let videoScaleFactor = Float(0.8)

// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(Float(videoAsset.duration.value) / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(Float(videoAsset.duration.value) * videoScaleFactor, videoAsset.duration.timescale)

Теперь вы умножаете/делите Float на другие Float

Но

func CMTimeMake(_ value: Int64, _ timescale: Int32) -> CMTime

Таким образом, CMTimeMake(_:_:) ожидает значение Int64, поэтому вы получаете ошибку, потому что Float(videoAsset.duration.value) / videoScaleFactor (для первого) возвращает Float, а методу требуется Int64.

Так что просто сделай

let videoScaleFactor = Float(0.8)

// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(Int64(Float(videoAsset.duration.value) / videoScaleFactor), videoAsset.duration.timescale) : CMTimeMake(Int64(Float(videoAsset.duration.value) * videoScaleFactor), videoAsset.duration.timescale)

Теперь это должно сработать.

Но я не могу уйти с этим кодом. Ваша строка довольно длинная, и ее трудно прочитать. Фактически, вы просто изменяете параметр value файла CMTimeMake(_:_:).

Факторизуем:

let videoScaleFactor = Float(0.8)

// Get the scaled video duration
let scaledVideoDuration = CMTimeMake((mode == .Faster) ? Int64(Float(videoAsset.duration.value) / videoScaleFactor) : Int64(Float(videoAsset.duration.value) * videoScaleFactor), videoAsset.duration.timescale)

Теперь это личное, я бы предпочел (ничего плохого в явной дополнительной строке):

let videoScaleFactor = Float(0.8) 
let value = (mode == .Faster) ? Float(videoAsset.duration.value) / videoScaleFactor : Float(videoAsset.duration.value) * videoScaleFactor 
let scaledVideoDuration = CMTimeMake(Int64(value), videoAsset.duration.timescale)
person Larme    schedule 03.08.2018