Я адаптировал свой ответ здесь и игровой шаблон Apple Metal для создания этого образца , который демонстрирует, как записать видеофайл непосредственно из последовательности кадров, визуализированных Metal.
Так как весь рендеринг в металле обращается к текстуре, нетрудно адаптировать нормальный металлический код, чтобы он подходил для рендеринга в автономном режиме в виде файла фильма.Чтобы повторить основной процесс записи:
- Создайте
AVAssetWriter
, нацеленный на выбранный вами URL - Создайте
AVAssetWriterInput
типа .video
, чтобы вы могли писать видеокадры - Оберните
AVAssetWriterInputPixelBufferAdaptor
вокруг ввода, чтобы вы могли добавлять CVPixelBuffer
s в качестве кадров к видео - После того, как вы начнете запись, каждый кадр скопируйте пиксели из текстуры визуализированного кадра впиксельный буфер, полученный из пула буферов пикселя адаптера.
- Когда вы закончите, отметьте ввод как завершенный и завершите запись в средство записи ресурсов.
Что касается управления записью,поскольку вы не получаете ответные вызовы от MTKView
или CADisplayLink
, вам нужно сделать это самостоятельно.Базовый шаблон выглядит следующим образом:
for t in stride(from: 0, through: duration, by: frameDelta) {
draw(in: renderBuffer, depthTexture: depthBuffer, time: t) { (texture) in
recorder.writeFrame(forTexture: texture, time: t)
}
}
Если ваш код рендеринга и записи асинхронный и поточно-ориентированный, вы можете добавить его в фоновую очередь, чтобы обеспечить отзывчивость интерфейса.Вы также можете добавить обратный вызов прогресса для обновления пользовательского интерфейса, если рендеринг занимает много времени.
Обратите внимание, что, поскольку вы не работаете в режиме реального времени, вам необходимо убедиться, что любая анимация принимаетучитывайте текущее время кадра (или временной интервал между кадрами), чтобы все воспроизводилось с надлежащей скоростью при воспроизведении.В моем примере я делаю это, просто имея зависимость вращения куба от времени представления кадра.