Подтвердить что ты не робот

Linux: видеозапись экрана на экране по сети и частота кадров VNC

Извините за стену текста - TL; DR:

  • Какова частота обмена VNC-соединением (в кадрах/сек) - точнее, кто это определяет: клиент или сервер?
  • Любые другие предложения для захвата экрана рабочего стола - но "правильно timecoded" /с неизменной частотой кадров (со стабильным периодом); и с возможностью получить его как несжатую (или без потерь) последовательность изображений?

Вкратце: у меня типичная проблема, с которой я столкнулся: иногда я разрабатываю аппаратное обеспечение и хочу записать видео, в котором отображаются обе команды, введенные на ПК ( "захват рабочего стола" ), и ответы аппаратного обеспечения ( "в реальном времени" видео'). Ниже приведен фрагмент введения, прежде чем я перейду к конкретным деталям.  
 

Введение/контекст

Моя стратегия, на данный момент, заключается в использовании видеокамеры для записи процесса тестирования оборудования (как "живое" видео) и одновременно выполнять захват рабочего стола. Видеокамера создает 29,97 (30) видео FPS MPEG-2.AVI; и я хочу получить захват рабочего стола как последовательность изображений PNG с той же частотой кадров, что и видео. Тогда идея была бы такой: если частота кадров двух видео одинакова; то я мог бы просто

  • выровнять время начала захвата рабочего стола, с точкой совпадения в "живом" видео
  • Настройте picture-in-picture, где помещена уменьшенная версия захвата рабочего стола - в качестве наложения - поверх "вживую" ' видео
    • (где часть экрана на "живом" видео, служит в качестве визуального источника синхронизации с наложением "захвата рабочего стола" ).
  • Экспорт "финального" комбинированного видео, сжатого для Интернета.

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

В конце концов, я также хочу добиться максимального качества при экспорте "финального" видео: "живое" видео уже сжато, когда оно находится вне камеры, что означает дополнительную деградацию, когда она проходит через Theora. ogv codec - вот почему я хотел бы сохранить оригинальные видео и использовать что-то вроде командной строки для генерации "финального" видео заново, если требуется другое сжатие/разрешение. Именно поэтому мне нравится иметь видеозапись "настольного захвата" в виде последовательности PNG (хотя я предполагаю, что любой несжатый формат будет делать): я принимаю меры для "настройки" рабочего стола, поэтому не так много градиентов и без потерь кодирования (например, PNG).  
 

Параметры захвата рабочего стола

В этом процессе много проблем в Ubuntu Lucid, которые я использую в настоящее время (и вы можете прочитать о некоторых моих испытаниях в 10.04: оверлей видео/составное редактирование с помощью Theora ogv - Форумы Ubuntu). Однако одной из важнейших проблем является предположение, что частота кадров двух входящих видео одинакова - на самом деле, обычно захват рабочего стола имеет меньшую частоту кадров; и еще хуже, очень часто кадры не синхронизированы.

Таким образом, для этого требуется хлопот перед видеоредактором и ручная резка и редактирование клипов менее чем на секунду на уровне кадра - требуя часов работы для того, что будет в конце 5 минут видео. С другой стороны, если два видеоролика ( "живой" и "захват" ) имеют одинаковую частоту кадров и синхронизацию: в принципе вам не понадобится больше нескольких минут для поиска начальной точки синхронизации в видеоредакторе - и остальная часть "объединенной" обработки видео может обрабатываться одной командной строкой. Поэтому в этом посте я хотел бы сосредоточиться на части захвата рабочего стола.

Насколько я могу судить, существует только несколько жизнеспособных (в отличие от 5 способов для создания вашего рабочего стола Linux) альтернативы для захвата рабочего стола в Linux/Ubuntu (заметьте, я обычно использую ноутбук в качестве цели для захвата рабочего стола):

  • Попросите ваш целевой компьютер (ноутбук) клонировать рабочий стол на его выходе VGA; использовать аппаратное обеспечение VGA-to-composite или VGA-to-S-video для получения видеосигнала от VGA; используйте карту видеозахвата на другом ПК, чтобы захватить видео.
  • Используйте recordMyDesktop на целевом ПК
  • Настройте VNC-сервер (vi no в Ubuntu или vncserver) на целевом ПК, подлежащем захвату; используйте программное обеспечение для захвата VNC (например, vncrec) на другом ПК для захвата/записи потока VNC (который впоследствии может быть преобразован в видео).
  • Используйте ffmpeg с опцией x11grab
  • * (используйте какой-либо инструмент на целевом ПК, который будет выполнять передачу DMA рамки рабочего стола напрямую - из рамки графической карты буферную память, в память сетевого адаптера)

Обратите внимание, что полезность вышеуказанных подходов ограничена моим контекстом использования: целевой компьютер, который я хочу захватить, обычно запускает программное обеспечение (используя тестируемое оборудование), которое перемещается вокруг массивных массивов данных; лучше всего сказать об описании такой системы, "едва стабильна":) Я бы предположил, что это похоже на проблемы, с которыми сталкиваются геймеры, желая получить видеозахват сложной игры. И как только я начинаю использовать что-то вроде recordMyDesktop, которое также использует довольно много ресурсов и хочет захватить на локальном жестком диске - я сразу получаю серьезные сбои ядра (часто без генерируемого vmcore).

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

(подготовка рабочего стола)

Для всех описанных ниже методов я стараюсь "заранее подготовить" рабочий стол:

  • Удалить фоны рабочего стола и значки
  • Установите разрешение до 800x600 с помощью System/Preferences/Monitors (gnome-desktop-properties)
  • Изменить глубину цвета до 16 бит/с (используя xdpyinfo | grep "of root" для проверки)

..., чтобы минимизировать нагрузку на программное обеспечение для захвата рабочего стола. Обратите внимание, что изменение глубины цвета на Ubuntu требует изменений в xorg.conf; однако Нет xorg.conf(есть), найденный в /etc/X 11 (Ubuntu 10.04)" - поэтому вам может потребоваться запустить sudo Xorg -configure первый.

Чтобы поддерживать низкий уровень использования графического ресурса, я обычно отключил compiz - или, скорее, у меня было бы "System/Preferences/Appearance/Visual Effects" равным "None". Однако после того, как я попытался включить compiz, установив "Визуальные эффекты" на "Нормальный" (который не сохраняется), я могу заметить окна на ЖК-экране перерисовываются намного быстрее; поэтому я сохраняю его так же, как и для захвата рабочего стола. Я нахожу это немного странным: как больше эффектов может вызвать более быстрое обновление экрана? Он не похож на него из-за запатентованного драйвера (карта "Intel Corporation N10 Family Integrated Graphics Controller", и ни одна из опций проприетарного драйвера не указана Ubuntu при переключении на compiz) - хотя, возможно, все размытие и эффекты просто обманывают мои глаза:)).

Клонирование VGA

Ну, это самый дорогостоящий вариант (так как он требует дополнительной покупки не одного, а двух аппаратных средств: конвертера VGA и карты захвата видео); и в основном применимы к ноутбукам (которые имеют как экран + дополнительный VGA-выход), для настольных компьютеров также может потребоваться инвестировать в дополнительную графическую карту или оборудование для клонирования VGA).

Однако, это также единственный вариант, который не требует никакого дополнительного программного обеспечения целевого ПК (и, следовательно, использует 0% вычислительной мощности целевого ЦП), - а также единственный, который даст видео с истинным, неперехваченным частота кадров 30 кадров в секунду (как это выполняется отдельными аппаратными средствами), хотя с допущением, что смещение тактовых импульсов между отдельными аппаратными частями незначительно).

Собственно, поскольку у меня уже есть что-то вроде карты захвата, я уже инвестировал в конвертер VGA - в ожидании, что он в конечном итоге позволит мне создавать финальные "объединенные" видео всего за 5 минут поиска точки выравнивания и единственная командная строка; но я еще не видел, будет ли этот процесс работать по назначению. Я также блуждаю, насколько это возможно, чтобы захватить рабочий стол в виде несжатого видео @800x600, 30 кадров в секунду.

RecordMyDesktop

Хорошо, если вы запустите recordMyDesktop без каких-либо аргументов - сначала он начнет записывать (что-то похожее) данные необработанного изображения в папку типа /tmp/rMD-session-7247; и после того, как вы нажмете Ctrl-C, чтобы прервать его, он будет кодировать эти данные необработанного изображения в .ogv. Очевидно, что захват больших данных изображения на том же жестком диске, что и мое тестовое программное обеспечение (которое также перемещает большие объемы данных), обычно является причиной для instacrash:)

Следовательно, я старался сделать это настроить Samba для совместного использования диска в сети; то на целевом ПК я подключился бы к этому диску - и проинструктировал бы recordMyDesktop использовать этот сетевой диск (через gvfs) как его временные файлы:

recordmydesktop --workdir /home/user/.gvfs/test\ on\ 192.168.1.100/capture/ --no-sound --quick-subsampling --fps 30 --overwrite -o capture.ogv 

Обратите внимание, что, хотя эта команда будет использовать сетевое расположение для временных файлов (и, таким образом, позволяет recordMyDesktop работать параллельно с моим программным обеспечением) - как только вы нажмете Ctrl-C, он начнет кодирование и сохраняя capture.ogv непосредственно на локальном жестком диске цели (хотя в этот момент мне все равно))

Первый из моих nags с recordMyDesktop заключается в том, что вы не можете указывать ему сохранить временные файлы и избегать их кодирования, в конце: вы можете использовать Ctrl + Alt + p для паузы - или вы можете быстро нажать Ctrl-C после первого, чтобы вызвать его сбой; который затем оставит временные файлы (если вы не нажмете Ctrl-C достаточно быстро во второй раз, программа "Очистка кеша..." ). Затем вы можете запустить, скажем:

recordmydesktop --rescue /home/user/.gvfs/test\ on\ 192.168.1.100/capture/rMD-session-7247/

..., чтобы преобразовать необработанные временные данные. Однако, чаще всего, recordMyDesktop сам будет segfault в середине выполнения этого "спасения". Хотя причина, по которой я хочу сохранить временные файлы, состоит в том, чтобы иметь несжатый источник для монтажа изображения в картинке. Обратите внимание, что "--on-the-fly-encoding" вообще не будет использовать временные файлы - за счет использования большей вычислительной мощности процессора (что для меня снова является причиной сбоев.)

Тогда есть частота кадров - очевидно, вы можете установить требуемую частоту кадров, используя опцию '--fps N; однако это не гарантирует, что вы действительно получите эту частоту кадров; например, я бы получил:

recordmydesktop --fps 25
...
Saved 2983 frames in a total of 6023 requests
...

... для захвата с запущенным тестовым программным обеспечением; это означает, что фактически достигнутая скорость больше похожа на 25 * 2983/6032 = 12,3632 кадра в секунду!

Очевидно, что кадры отбрасываются - и в основном это выглядит как воспроизведение видео слишком быстро. Однако, если я опускаю запрошенные fps до 12, то в соответствии с сохраненными/полными отчетами я достигаю чего-то вроде 11 fps; и в этом случае воспроизведение видео не выглядит "ускоренным". И я до сих пор не пробовал выровнять такой захват с живым видео, поэтому я понятия не имею, были ли сохранены те кадры, которые действительно были сохранены, а также точную метку времени.

захват VNC

Захват VNC для меня состоит в запуске VNC-сервера на целевом ПК и запуске vncrec (twibright edition) на ПК-рекордере. Как сервер VNC, я использую vino, который является "Системой/Предпочтения/Удаленный рабочий стол (Предпочтения)". И, по-видимому, даже если конфигурация vino может быть не самой простой вещью для управления, vino, поскольку сервер кажется слишком не облагаемым налогом на "цель" ПК; поскольку я не испытывал сбоев, когда он работает параллельно с моим тестовым программным обеспечением.

С другой стороны, когда vncrec фиксируется на ПК "рекордера" , он также поднимает окно, показывающее рабочий стол "цель", как это видно в "реальном времени"; когда на "цели" появляются большие обновления (т.е. целые окна) - можно увидеть проблемы с частотой обновления/обновления на "рекордере". Но для небольших обновлений (т.е. Только курсора, движущегося на статическом фоне) все выглядит нормально.

Это заставляет задуматься об одном из моих основных вопросов с этим сообщением - что это такое, что задает частоту кадров в VNC-соединении?

Я не нашел четкого ответа на это, но из бит и частей информации (см. ссылки ниже), я понимаю, что:

  • Сервер VNC просто отправляет изменения (изменения экрана + клики и т.д.) настолько быстро, насколько это возможно, когда он их получает; ограниченная максимальной пропускной способностью сети, доступной для сервера.
  • Клиент VNC получает те события изменения, которые задерживаются и дрожат от сетевого подключения, и пытается восстановить поток "видео" рабочего стола, как можно быстрее

... что означает, что нельзя утверждать ничего в терминах стабильной периодической частоты кадров (как в видео).

Что касается vncrec как клиент, конечные видео, которые я получаю, обычно объявляются как 10 кадров в секунду, хотя кадры могут быть смещены/дрожат (что требует резки в видеоредакторах). Обратите внимание, что vncrec-twibright/READMEуказывает: "Частота выборки фильма по умолчанию равна 10 или переопределяется переменной среды VNCREC_MOVIE_FRAMERATE или 10, если не указано."; однако в man-странице также указывается: "VNCREC_MOVIE_FRAMERATE - задает частоту кадров выходного фильма. Эффект действует только в режиме -movie. По умолчанию 10. Попробуйте 24, когда ваш транскодер рвется с 10.". И если посмотреть на источник "vncrec/sockets.c", можно увидеть:

void print_movie_frames_up_to_time(struct timeval tv)
{
  static double framerate;
  ....
  memcpy(out, bufoutptr, buffered);
  if (appData.record)
    {
      writeLogHeader (); /* Writes the timestamp */
      fwrite (bufoutptr, 1, buffered, vncLog);
    }

..., который показывает, что написаны некоторые временные метки, но независимо от того, происходят ли эти временные метки с "оригинального" целевого ПК или "рекордера" , я не могу сказать. EDIT: благодаря ответу @kanaka, я снова проверил vncrec/sockets.c и вижу, что это сама функция writeLogHeader вызывает gettimeofday; поэтому метки времени, которые он записывает, являются локальными, то есть они исходят от ПК "рекордера" (и, следовательно, эти временные метки не точно описывают, когда кадры возникли на "целевом" ПК).

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

Я также хотел бы заявить, что на моем "целевом" ноутбуке

Наконец, что касается VNC, могут возникнуть другие альтернативы - например, сервер (обещающий, но требующий некоторых время строить из источника и находится в "ранней экспериментальной версии" ); или (хотя это похоже на клиента/зрителя без параметров для записи).

ffmpeg с x11grab

Не играл с этим много, но я пробовал его в связи с netcat; это:

# 'target'
ffmpeg -f x11grab -b 8000k -r 30 -s 800x600 -i :0.0 -f rawvideo - | nc 192.168.1.100 5678
# 'recorder'
nc -l 0.0.0.0 5678 > raw.video  #

... захватывает файл, но ffplay не может правильно прочитать захваченный файл; в то время как:

# 'target'
ffmpeg -f x11grab -b 500k -r 30 -s 800x600 -i :0.0 -f yuv4mpegpipe -pix_fmt yuv444p - | nc 192.168.1.100 5678
# 'recorder'
nc -l 0.0.0.0 5678 | ffmpeg -i - /path/to/samplimg%03d.png

создает .png изображения - но с артефактами сжатия (результат сжатия, связанный с yuv4mpegpipe, я думаю).

Таким образом, мне не нравится ffmpeg + x11grab слишком много в настоящее время - но, возможно, я просто не знаю, как настроить его для моих нужд.

* (графическая карта → DMA → сеть)

Я, по общему признанию, не уверен, что что-то подобное существует - на самом деле, я бы парировал это не так. И я не эксперт здесь, но я размышляю:

если передача DMA-памяти может быть инициирована с графической карты (или ее буфера, которая поддерживает текущее растровое изображение на рабочем столе) в качестве источника, а сетевой адаптер в качестве адресата - тогда, в принципе, должно быть возможно получить несжатый захват рабочего стола с помощью правильная (и достойная) частота кадров. Разумеется, точкой в ​​использовании передачи DMA было бы избавить процессор от задачи копирования изображения рабочего стола на сетевой интерфейс (и, таким образом, уменьшить влияние программного обеспечения захвата на процессы, выполняемые на целевом ПК - особенно те, которые относятся к ОЗУ или жесткому диску).

Подобное предложение, конечно же, предполагает, что: имеются массивные массивы пропускной способности сети (для 800x600, 30 кадров в секунду не менее 800 * 600 * 3 * 30 = 43200000 бит/с = 42 Мбайт/с, что должно быть в порядке для локальные сети 100 МБ/с); много жесткого диска на другом ПК, который выполняет "запись", и, наконец, программное обеспечение, которое впоследствии может читать эти необработанные данные и генерировать последовательности изображений или видео на основе этого.

Требования к пропускной способности и жесткому диску, с которыми я мог бы жить - пока есть гарантия как для стабильной частоты кадров, так и для несжатых данных; поэтому я хотел бы услышать, если что-то подобное уже существует.

- - - - -  

Ну, я думаю, это было так же кратким, как я мог бы выразиться:) Любые предложения для инструментов - или процессов (процессов), которые могут возникнуть при захвате рабочего стола

в несжатом формате (в конечном счете конвертируемом в несжатую/без потерь PNG-последовательность изображений) и с правильной временной кодировкой, стабильной частотой кадров

..., который в конечном итоге поддается "легкой" обработке одиночной командной строки для создания видеоизображений "картинка-в-картинке" - будет с благодарностью!

Заранее благодарим за любые комментарии,
Ура!

Ссылки

4b9b3361

Ответ 1

Вы должны получить значок для такой длинной скважины, хотя вопрос.; -)

В ответ на ваш основной вопрос VNC использует RFB-протокол, который является протоколом буфера удаленных кадров (таким образом, сокращенным), а не потоковым видео-протоколом. Клиент VNC отправляет на сервер сообщение FrameBufferUpdateRequest, которое содержит область просмотра, которую интересует клиент, и инкрементный флаг. Если инкрементный флаг не установлен, сервер ответит сообщением FrameBufferUpdate, содержащим содержимое запрошенной области. Если установлен инкрементный флаг, сервер может ответить сообщением FrameBufferUpdate, которое содержит любые части запрошенной области, которые были изменены с момента последнего отправления клиентом этой области.

Определение того, как взаимодействуют запросы и обновления, не определено четко. Сервер не обязательно будет отвечать на каждый запрос обновлением, если ничего не изменилось. Если сервер имеет несколько запросов, поставленных в очередь от клиента, он также может отправлять одно обновление в ответ. Кроме того, клиент действительно должен иметь возможность реагировать на сообщение асинхронного обновления с сервера (не в ответ на запрос), иначе клиент будет выпадать из синхронизации (поскольку RFB не является фрейм-протоколом).

Часто клиенты просто реализуются для отправки инкрементных запросов на обновление для всего окна просмотра фрейма кадра с периодическим интервалом и обработки любых сообщений об обновлении сервера по мере их поступления (т.е. не делается попытка связать запросы и обновления вместе).

Здесь - описание сообщений FrameBufferUpdateRequest.