RetroClip: мгновенное воспроизведение для вашего Mac

  • Эта публикация - перевод статьи. Ее автор - James Howard. Оригинал доступен по ссылке ниже:

У нас есть новое приложение в Mac App Store. RetroClip позволяет мгновенно делать видеозахват экрана вашего Mac так же легко, как делать снимок экрана. Есть браузерная демо-версия, которую вы можете попробовать, если работаете на Mac или ПК (и вы действительно должны попробовать, потому что это супер круто).

У меня возникла идея написать RetroClip после игры в Fortnite Battle Royale и выиграть, а затем ничего не показывать для нее, кроме статического скриншота. [1] В игровых консолях текущего поколения есть функция, в которой вы можете нажать кнопку и захватить последнюю минуту или около того, и я хотел это для своего Mac. Основная идея заключается в том, что вы не знаете, когда хотите сохранить видеоклип, пока не произойдет что-то захватывающее, поэтому ему нужно работать задним числом - нехорошо, если вам нужно нажать кнопку, чтобы начать запись, потому что она уже слишком поздно.

В отличие от других утилит для захвата экрана для macOS, RetroClip не сохраняет на постоянно растущий файл царапин на диске, поскольку он записывает. Вместо этого он сохраняет видеофрагменты в кольцевой буфер фиксированного размера в основной памяти. Понятное дело, нам даже не нужно столько памяти, чтобы делать хорошую работу. Мы можем разместить 30 секунд видео высокой четкости около 40 МБ памяти. [2] Как только вы увидите что-то, что хотите сохранить, просто нажмите комбинацию клавиш RetroClip, и RetroClip записывает область памяти с видеоданными на диск, по существу мгновенно.

В любом случае, вы должны скачать его и попробовать. Даже если вы не используете его для игр, вы можете найти его полезным для захвата этих досадных отчетов об ошибках, где вы не можете воспроизвести его во второй раз. Пожалуйста, сообщите нам, что вы думаете, по электронной почте или в Twitter.

Технические примечания: Секреты RetroClip

Я играл в гольф RetroClip в свободное время в течение последних нескольких месяцев. На самом деле мне потребовалось всего несколько часов, чтобы запустить и запустить начальную версию приложения, но выработка максимальной производительности стала чем-то вроде одержимости. Дело не только в правах на хвастовство, но и в том, чтобы оставлять RetroClip постоянно, даже во время игр, просмотра видео, компиляции кода, написания сообщений в блогах и т. Д. Чем эффективнее RetroClip, тем больше остается для выполнения важных задач и экономии времени автономной работы.

Если вас интересует внутренняя работа RetroClip, читайте, потому что этот раздел для вас. Если нет, все в порядке, в любом случае нет причин знать это.

Скриншот

Захват экрана в macOS неизбежно начинается с Window Server. Window Server - это процесс в macOS, отвечающий за отслеживание окон и их содержимого и их компоновку, чтобы сделать изображение, которое вы видите на дисплее. 3Как приложение, мы можем попросить Window Server отправить нам содержимое экрана, поскольку они отображаются через API CGDisplayStream . Когда мы это сделаем, Window Server будет кормить нас, через IPC, IOSurfaces , которые являются указателями на общую графическую память текстуры, так же быстро, как либо они могут создавать их, либо так быстро, как мы можем их потреблять, в зависимости от того, что медленнее.

Как только мы получим указатели на данные текстуры, мы можем развернуться и передать это в аппаратный видеокодер H.264, который присутствует на большинстве Mac с помощью API VideoToolbox .

Все описанное до сих пор все отлично работает, и это очень оптимизированная область macOS, поскольку она используется в важных встроенных функциях, таких как AirPlay Mirroring. Для удобства, он даже завершен в API AVFoundation более высокого уровня, который работает очень хорошо (и это либо основа функциональности записи экрана QuickTime Player, либо их реализация существенно похожа).

Однако с небольшими усилиями можно оптимизировать ситуацию и сэкономить некоторое время процессора на этом пути. Мы не можем обойтись, обращаясь к Window Server за некоторыми работами от нашего имени, чтобы получить данные дисплея в первую очередь, и мы не можем обойтись, чтобы кодировать изображения H.264. [4] Но есть еще место, где можно сэкономить время: курсор мыши.

Курсор мыши является специальным. Он живет в оверлее, который в последний момент компонован поверх всего остального графическим процессором, прежде чем изображение будет показано на экране. Это действительно влияет на то, насколько чувствителен ваш компьютер. Если при перемещении мыши сервер окон должен был перекомпоновать всю сцену, а курсор мыши был заблокирован на vsync, вы можете на самом деле, утонченно чувствовать, что он лагги. Возможно, вы испытали этот эффект при игре в полноэкранные видеоигры, которые пытаются реализовать свой собственный рендеринг курсора. Вы также можете заметить этот эффект при включении Mirroring AirPlay, поскольку это, по-видимому, заставляет Window Server работать в режиме, в котором он будет компоновать курсор вместе со всем остальным, в отличие от использования наложения аппаратного курсора.

Поэтому, возвращаясь к API CGDisplayStream, обратите внимание, что мы можем попросить Window Server скомпоновать курсор для нас. Это прекрасно работает и создает правильную картинку, но отключает наложение аппаратного курсора, что будет медленно приводить вас в бешенство. Таким образом, чтобы избежать медленного спуска в безумие, лучший подход заключается в том, чтобы проинструктировать Window Server не включать курсор мыши в поток отображения и просто соединить его сам в свое время. И, фактически, это тот подход, который использует QuickTime Player и AVCaptureScreenInput. Однако я знаю способ сделать это быстрее.

Мой трюк заключается в том, чтобы заметить, что IOSURfaces, переданные моему приложению с Window Server, можно записать. Кажется, что оконный сервер вращается через небольшую часть из них, поэтому я не могу держаться за них более нескольких кадров, или я рискую отстать, но я могу быстро их изменить, и это намного быстрее, чем пытаясь их скопировать. Таким образом, я быстро Blit на маленькую текстуру царапины, чтобы скрыть пиксели в области, где находится курсор, затем я составлю курсор в исходную полноэкранную текстуру, полученную с Window Server. Если курсор мыши перемещается без обновления экрана (что может и должно произойти, когда Window Server использует накладку аппаратного курсора), я могу использовать эту текстуру царапины, которую я сохранил, чтобы отменить компоновку курсора, которую я сделал ранее, а затем у меня есть чистый холст, на котором можно перестроить курсор в новом месте.

Я думаю, что трюк с курсором мыши является основным источником моего преимущества по сравнению с QuickTime Player / AVCaptureScreenInput, а также, как правило, тщательным программированием, чтобы избежать ненужных копий, распределений и ограничений. На моей машине RetroClip обычно использует примерно одну пятую процессорного времени для захвата одного и того же контента со скоростью 60 кадров в секунду, как это делает AVCaptureScreenInput. Наконец, если нет курсора мыши, потому что вы играете в игру без нее, или вы смотрите видео, тогда мы можем пойти еще быстрее на кодовый путь и избежать всего макета для компоновки курсора.

Буферизация медиа

RetroClip хранит закодированные видеокадры H.264 в памяти, а не сразу записывает их на диск, как это делает QuickTime Player. Цель RetroClip для буферизации этого видео состоит в том, чтобы держать его в памяти настолько эффективно, насколько это возможно, и иметь стабильную память в течение нескольких дней или недель использования. Кроме того, когда пользователь запрашивает сохранение клипа, мы хотим сделать это как можно быстрее.

Мой первый проход состоял в том, чтобы просто поставить ссылки подсчитанных указателей на кадры, выводимые из видеокодера, в очередь. Это работает нормально, но у него есть два недостатка: во-первых, мы должны блокировать всякий раз, когда выполняем операцию сохранения, пока у нас не будет возможности дублировать очередь и увеличивать количество удержаний во всех буферах выборки внутри нее, а во-вторых, сохранять тысячи этих разноразмерных вещей, разбросанных вокруг, превращают кучу в швейцарский сыр через некоторое время.

Решение обеих этих проблем заключается в использовании круговой очереди для хранения кодированных видеоданных до конца без какой-либо фрагментации. По мере создания новых кадров мы пишем их во главе, и мы можем забыть о старых кадрах в хвосте, просто увеличивая указатель.

Майк Эш написал очень интересную серию статей об использовании трюков виртуальной памяти mach, чтобы избежать необходимости разбивать сегментированные объекты, которые разбиты по краю круговой очереди, и вы обязательно должны прочитать его, если вы еще этого не сделали, но я действительно надел Не нужно использовать этот трюк самостоятельно в RetroClip. Это связано с тем, что код, который записывает файл mp4, уже может легко обрабатывать разделенный кадр, если это необходимо.

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

То, что аккуратно, копия на самом деле не является копией, это просто некоторые новые записи в таблице страниц виртуальной памяти, указывающие на одну и ту же физическую память, содержащую видеоданные в качестве оригинала. Только когда новые кадры принимаются и записываются в оригинал, содержимое круговых буферов начинает расходиться, и ядро ​​обрабатывает поиск новой памяти для сохранения данных для нас прозрачно. И поскольку выполнение непрерывной записи 40 или 80 МБ из памяти на диск невероятно быстро в эти дни, намного быстрее, чем скорость поступающих данных от кодера H.264, на самом деле не так много копий для записи, что ядро ​​должно делать для нас, в лучшем случае, пара мегабайт.

RetroClip для Интернета

Как разработчики реального программного обеспечения для Mac, мы с Ником иногда беспокоимся о том, что мы игнорируем продвигающиеся возможности веб-браузеров в качестве платформ приложений. Что касается нашего первого продукта пару лет назад, читатель Hacker News уверенно писал:

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

Как уже было в 2018 году, мы знали, что нам нужно справляться со временем. Хотя сначала я просто хотел сделать видео, написать рекламный ролик и иметь ссылку на Mac App Store для нашего сайта, Ник быстро убедил меня, что я могу и должен делать лучше.

Итак, на прошлой неделе, не имея ничего другого, кроме последней версии Safari и моего надежного текстового редактора, я отправился в порт RetroClip в Интернете.

Моей первой задачей было выяснить, как сделать кодировку H.264 в веб-браузере. Использование аппаратного кодера явно не ограничивалось, но я решил, что для кодирования программного обеспечения в фоновом потоке должно быть достаточно. Я нашел несколько из проектов, направленных , на это делать, но я надеюсь сделать лучше , чем 25MB несжатого JavaScript.

Я не собирался писать свой собственный кодировщик H.264, но я подумал, может быть, если бы я получил x264,созданный как веб-сборка, с таким же небольшим дополнительным кодом клея, сколько необходимо для получения RGB-данных из браузера в видео H.264 в контейнере MP4 и обратно, это было бы достаточно хорошо. И, оказывается, это так . Он работает примерно до 850 КБ несжатой веб-сборки, и он будет кодировать масштабированные данные изображения в H.264 намного быстрее, чем в реальном времени (по крайней мере, на достойных компьютерах).

После того, как видеокодирование части головоломки было решено, я был уверен, что RetroClip для Интернета может стать реальностью. Все, что мне было нужно, это создать для Интернета Window Server, панель меню, некоторую иерархию представлений Cocoa, управление окнами, код обработки событий, NSVisualEffectView , NSUserNotificationCenter и картинку в медиаплеере для изображений , представленную в macOS Sierra, иметь все, что мне нужно для порта и запускать RetroClip в Интернете!

В конце концов, это было не слишком сложно. Элемент HTML Canvas в основном похож на CGContext, поэтому переопределение пользовательского интерфейса MacOS в Интернете происходит несколько естественным образом.

Разумеется, среда, в которой можно запускать только RetroClip, слишком самореферентна, чтобы практиковать ее вне маркетингового RetroClip для Mac , но я полагаю, что с помощью наземной работы, которую я уже сделал, у меня будет нога при переносе других приложений Cocoa в Интернет. Эй, он работал на 280 North несколько лет назад, и теперь, с появлением новых новых веб-технологий, возможно, придет время вернуться к этой идее. [5]

Заключение

Как вы можете сказать из-за этого слишком длинного сообщения в блоге, много работы пошло в RetroClip. Если вы клиент корабля, вам, вероятно, интересно, как это влияет на корабль. Ответ, мы все еще работаем над кораблем, и я написал RetroClip в своем свободное время и решил выпустить его , потому что это аккуратно.

Если вы еще не являетесь пользователем корабля, и вы используете GitHub и Mac, вы должны это проверить.


  1. Вы могли бы спросить, теперь, когда идея RetroClip проявляется в качестве приложения для доставки, где видео, которое я выиграл в Fortnite? Ну, ответ в том, что в Фортните очень сложно победить. Скачайте RetroClip и запишите свою собственную победу, если считаете, что это так просто. 😛  

  2. Фактическое использование памяти RPRVT в RetroClip будет выше 40 МБ, из-за системных фреймворков и распределения различных других пространств царапин, которые в основном зависят от вашего разрешения экрана, но небезосновательно видеть RPRVT 110 МБ или около того на сетчатке macbook pro для RetroClip.

  3. Если вы работаете на Window Server, я приношу свои извинения за грубое упрощение. 

  4. Альтернативы не H.264, кодирующие входящие IOSurfaces, включают в себя хранение их содержимого без сжатия (30 секунд несжатых 2880x1800 24-битных цветных изображений со скоростью 60 кадров в секунду составляет около 27 ГБ, поэтому удачи с этим), используя некоторую альтернативную схему сжатия на CPU или GPU ( который не собирается приближаться к аппаратным кодекам H264 с точки зрения использования ресурсов) или с использованием кодирования HEVC (что действительно многообещающе, но только самые новейшие Mac могут кодировать его на аппаратном обеспечении и поддерживать совместное использование видеороликов HEVC в Интернете на данный момент более ограничен, чем вездесущий MP4). 

  5. Я не серьезно.