Нужна помощь относительно CMTimeMakeWithSeconds

#ios #objective-c #avfoundation #cmtime

#iOS #objective-c #avfoundation #cmtime

Вопрос:

Я пытаюсь извлечь все кадры видео, преобразовать и сохранить их как отдельные изображения. Я использую этот код в руководстве по программированию AV Foundation.

код для получения нескольких изображений

 CMTime firstThird = CMTimeMakeWithSeconds(durationSeconds/3.0, 600);
CMTime secondThird = CMTimeMakeWithSeconds(durationSeconds*2.0/3.0, 600);
CMTime end = CMTimeMakeWithSeconds(durationSeconds, 600);
  

это жестко запрограммировано, но я хочу конвертировать видео целиком. Я знаю, что могу использовать цикл for, но что с этим делать durationsecond означает, как я могу использовать from begging to end, чтобы получить все кадры?

вот моя попытка

 for(float f=0.0; f<=durationSeconds; f  ) {
        [times addObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(durationSeconds, 600)]];
}
  

Ответ №1:

Каждый раз, когда вы собираетесь написать сотни строк почти идентичного кода, вероятно, наступает момент, когда вам нужно использовать какой-то цикл:

 for (int currentFrame = 0; currentFrame < durationSeconds;   currentFrame) {
    CMTime currentTime = CMTimeMakeWithSeconds(i, 600);
    // the rest of the code you need to create the image or whatever
}
  

Этот фрагмент будет захватывать один кадр в секунду. Если бы вы хотели получать 30 кадров в секунду, это выглядело бы примерно так:

 const CGFloat framesPerSecond = 30.0;

for (int currentFrame = 0; currentFrame < (durationSeconds * framesPerSecond);   currentFrame) {
    CMTime currentTime = CMTimeMakeWithSeconds(currentFrame/framesPerSecond, 600);
    // again, the code you need to create the image from this time
}
  

Просто установите значение framesPerSecond таким, сколько кадров в секунду вы хотите захватить.


В качестве оговорки, я не совсем знаком с этим материалом, поэтому <= здесь может быть уместно использовать условные выражения.


ДОПОЛНЕНИЕ: Опубликованный мной код будет использовать только временную метку, для которой будет использоваться изображение. Остальной код должен выглядеть примерно так:

 AVAsset *myAsset = // your asset here
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset];

NSError *error;
CMTime actualTime;

CGImageRef currentImage = [imageGenerator copyCGImageAtTime:currentTime 
                                                 actualTime:amp;actualTime 
                                                      error:amp;error];

if (!error) {
    [someMutableArray addObject:[[UIImage alloc] initWithCGImage:currentImage]];
}
  

Комментарии:

1. Я успешно выполнял цикл, генерировал изображения и сохранял изображения в хранилище, единственное, в чем я застрял, манипулируя формой durationsecond, требующей завершения. Есть ли какой-либо способ определить частоту кадров видео? чтобы точно получить все кадры.

2. Я не знаю, и я не уверен, что это можно точно определить. Скорость, с которой он был записан, и скорость, с которой он отображается, могут отличаться. Вам просто нужно определиться с качеством, с которым вы хотите снимать кадры.

3. как и в iPhone 5s, функция замедленной съемки позволяет снимать видео со скоростью 120 кадров в секунду.

4. Он захватывает видео со скоростью 120 кадров в секунду. Он не воспроизводит видео со скоростью 120 кадров в секунду. Если бы он воспроизводил видео с той же скоростью, с которой оно было записано, это не было бы замедленной съемкой, не так ли?

5. в коде есть небольшая проблема: я регистрирую текущий кадр / framesPerSecond, я получаю повторяющееся число от 0 до 6, что означает, что на самом деле только 6 кадров являются оригинальными, остальные повторяются 0, 1, 2…