Как увеличить или убедиться в максимальном размере входного кадра AVAssetWriter?

Я пытаюсь записать кадры в видео с помощью AVAssetWriter. Я написал коды, как показано ниже:

// Initial AVAssetWriter
// Write mp4 file
let assetWriter = try AVAssetWriter(outputURL: targetUrl, fileType: .mp4)
let width = size.width * 2
// set options for written video
let videoSettings: [String : Any] = [
    AVVideoCodecKey: AVVideoCodecType.h264,
    AVVideoWidthKey: width,
    AVVideoHeightKey: size.height
]
guard assetWriter.canApply(outputSettings: videoSettings, forMediaType: AVMediaType.video) else {
    fatalError("Error applying output settings")
}
// Initial AVAssetWriterInput
let assetWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)

// set arritbutes
let sourcePixelBufferAttributes: [String : Any] = [
    kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]

// Initial AVAssetWriterInputPixelBufferAdaptor
let inputPixelBufferAdaptor = 
    AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: assetWriterInput,
                                         sourcePixelBufferAttributes: sourcePixelBufferAttributes)
if assetWriter.canAdd(assetWriterInput) == true {
    assetWriter.add(assetWriterInput)
    assetWriter.startWriting()
    assetWriter.startSession(atSourceTime: .zero)
} else {
    print("Cannot add asset writer input.")
}

if let error = assetWriter.error {
    print("assetWrite status=\(assetWriter.status), error=\(error)")
}

Но если использовать мой iPhone 14 Pro, он покажет print("assetWrite status=\(assetWriter.status), error=\(error)") шоу:

assetWrite status=AVAssetWriterStatus(rawValue: 3), error=Error 
Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" 
UserInfo = {NSLocalizedFailureReason=An unknown error occurred (-12902), 
NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x30189cb10 
{Error Domain=NSOSStatusErrorDomain Code=-12902 "(null)"}}

size = CGSize(width: 2200, height: 2200) то есть width = size.width * 2 = 4400 Если бы я написал:

let videoSettings: [String : Any] = [
    AVVideoCodecKey: AVVideoCodecType.h264,
    AVVideoWidthKey: 4090, // width,
    AVVideoHeightKey: size.height
]

Ошибка не возникнет. Если установлено значение 4100 или больше, также возникнет ошибка.

Можно ли как-нибудь решить эту проблему, используя значение 4400 или больше в качестве ключа ширины?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
132
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это проблема с памятью, попробуйте использовать autoreleasepool

let pxBuffer = autoreleasepool {return self.newPixelBufferFrom(cgImage: image.cgImage!)}

Приведенный выше код еще не генерирует пиксельный буфер, поэтому я не уверен, как сделать то, что вы написали.

timyau 06.05.2024 07:17
Ответ принят как подходящий

Понимание сообщения об ошибке имеет решающее значение: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo = {NSLocalizedFailureReason=An unknown error occurred (-12902), -12902 (это kVTParameterErr) обычно означает, что ваши параметры, переданные в AssertWriter (VideoToolbox под капотом), неверны.

Итак, проверьте логи из консоли, вы сможете лучше понять:

Первый H264StartSession говорит о том, что ваше разрешение находится в пределах допустимого диапазона кодера H.264 [4400,2208], немного больше, чем стандартное разрешение 4k 4096x2160 в H.264 Level 5.1.

Однако это не обязательно означает, что последующие модули поддерживают это разрешение. Стандарт H.264 технически поддерживает разрешения до 8192x4320 (уровень 6.2), но многие устройства и реализации программного обеспечения не поддерживают эти более высокие уровни. Наиболее часто поддерживаемое максимальное разрешение для H.264 — 4096x2160 (уровень 5.1). Модуль FigExportCommon, который, как я полагаю, представляет собой аппаратно-ускоренную систему экспорта мультимедиа в iOS, реализованную с помощью VideoToolbox, не принимает размеры, превышающие 4096x4096. Интересно, я вижу, что у NV также есть это ограничение:

Nvidia RTX3060 — это архитектура Ampere с NVENC 7-го поколения для кодирования H.264 и H.265. Максимальные возможности кодирования H.264 достигаются при разрешении 4096x4096. Если в Resolve установлено использование аппаратного кодировщика Nvidia, оно не сможет кодировать с более высоким разрешением, чем это. Это 8192x8192 для H.265.

Я создал демо-проект здесь, вы можете поэкспериментировать с ним и увидеть, что если ваш размер больше 4096x4096, произойдет kVTParameterErr.

Если вам действительно нужен такой размер, как 4400x2200, рассмотрите возможность изменения AVVideoCodecKey на AVVideoCodecType.hevc, это работает. Я думаю, что в 2024 году HEVC (H.265) также будет широко поддерживаться.

Другие вопросы по теме