- Python 100%
| packaging | ||
| tests | ||
| .gitignore | ||
| browser.py | ||
| main.py | ||
| native.py | ||
| protocol.py | ||
| README.md | ||
| requirements.txt | ||
| video.py | ||
NanoKVM Native
Нативный клиент для NanoKVM Lite на Linux, без браузера. Qt получает Direct H.264
через /api/stream/h264/direct и отправляет HID-пакеты через /api/ws.
Для декодирования используется PyAV/FFmpeg.
Запуск
Установка deb-пакета
Готовый автономный пакет находится в dist/nanokvm-native_0.3.0_amd64.deb.
Он предназначен для Ubuntu 24.04 / Linux Mint 22, x86-64.
Python, Qt и PyAV/FFmpeg включены в пакет; системные зависимости устанавливает APT:
sudo apt install ./dist/nanokvm-native_0.3.0_amd64.deb
На другой машине скопируйте файл и укажите его расположение после apt install.
Запуск — через меню приложений NanoKVM Native или командой nanokvm-native.
В распространяемом пакете адрес заменён на http://nanokvm.local, пользователь
на admin, пароль пустой при первом запуске. Введите адрес и учётные данные своего устройства.
Локальные значения в исходниках при сборке не меняются.
Проверка установки без подключения к устройству:
QT_QPA_PLATFORM=offscreen nanokvm-native --self-test
Удаление: sudo apt remove nanokvm-native.
Запуск из исходников
В этой директории зависимости уже установлены:
.venv/bin/python main.py
Для установки заново:
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python main.py
Нужен системный openssl для совместимого с NanoKVM шифрования пароля.
Введите адрес устройства, имя пользователя и пароль. По умолчанию используется
http://192.168.2.207 при запуске из исходников. Полученная сессия не сохраняется на диск. Проверка
сертификатов HTTPS включена; самоподписанный сертификат нужно добавить в доверенные.
HTTP, как и у штатной страницы, не защищает сессию от перехвата в сети.
После успешного входа последние адрес и логин сохраняются в настройках
пользователя (~/.config/NanoKVM/Native.conf) и подставляются при следующем запуске.
Галочка «Сохранить пароль в системном хранилище» сохраняет пароль через
системный keyring, отдельно от файла настроек. Галочка восстанавливается вместе
с паролем. Если снять её и успешно подключиться, ранее сохранённый пароль удаляется.
При смене адреса или логина поле пароля очищается, чтобы не отправить сохранённый
пароль другому устройству. При ошибке входа или отмене диалога настройки не меняются.
В deb включена библиотека keyring; APT устанавливает GNOME Keyring. Для сохранения пароля нужен работающий Secret Service в пользовательском сеансе; система может попросить разблокировать хранилище. Если оно недоступно, приложение сообщает об ошибке и не записывает пароль в открытом виде. Настройки каждого пользователя отдельные и в распространяемый пакет не попадают.
После подключения приложение открывается на весь экран и захватывает клавиатуру. В окне подключения радиокнопки позволяют показывать или скрывать локальный курсор над видео. При скрытии остаётся только курсор удалённой машины в кадре; в окне входа и на кнопках приложения локальный курсор остаётся видимым. Ctrl+Shift+Esc освобождает клавиатуру и возвращает обычное окно. Кнопка «Захватить клавиатуру» возвращает управление. При потере фокуса или соединения нажатые клавиши и кнопки сбрасываются. После обрыва нажмите «Подключиться» и войдите снова.
Локальный курсор движется сразу. Абсолютные координаты мыши учитывают чёрные поля вокруг видео; движения объединяются каждые 20 мс (до 50 сообщений/с), чтобы уменьшить вероятность очереди USB HID на устройстве. При накоплении сетевых данных сохраняется последняя позиция.
H.264 декодируется в отдельном потоке: обработчики ввода не ждут декодирования.
Для отображения хранится только последний готовый кадр. Очередь декодирования
ограничена восемью пакетами, чтобы принять короткие пачки TCP без потери
зависимых кадров; при перегрузке клиент пропускает зависимые кадры
и запрашивает новый ключевой кадр. Параметр flow не используется: некоторые
версии сервера могут пропускать опорные кадры при заполнении окна, оставляя
артефакты в последующих кадрах H.264. Повреждённые кадры не отображаются;
клиент запрашивает восстановление с ключевого кадра. Готовые пакеты подтверждаются
после декодирования. При отсутствии кадров 10 секунд клиент освобождает захват
и сообщает об ошибке. Готовый кадр передаётся интерфейсу сразу по сигналу,
без ожидания таймера; уведомления объединяются, чтобы не накапливать устаревшие кадры.
Аппаратный декодер выбирается автоматически: VAAPI при доступном
/dev/dri/renderD* либо CUDA при наличии /dev/nvidia0, если соответствующий
режим поддерживает установленная сборка FFmpeg/PyAV. При ошибке инициализации
используется программное декодирование; при ошибке аппаратного декодирования
клиент запрашивает ключевой кадр и переходит на программный декодер.
Наличие видеокарты само по себе не гарантирует поддержку в сборке PyAV.
Клавиатура использует физические позиции Linux XKB, поэтому локальная русская раскладка не мешает передавать клавиши. Раскладку текста выбирает удалённая ОС. Поддержаны правые/левые модификаторы, F1–F12, навигация и цифровая клавиатура. На Wayland оконный менеджер может запретить полный захват системных сочетаний; для полного захвата используйте сеанс X11. Ctrl+Shift+Esc зарезервировано клиентом.
При входе клиент переключает устройство в H.264, 1920×1080, 5 Мбит/с, 60 кадров/с.
GOP установлен в 10: полное обновление ключевым кадром происходит чаще,
что сокращает время восстановления изображения при повреждении потока.
60 кадров/с — запрашиваемое значение; реальная частота зависит от NanoKVM и нагрузки.
Для H.264 параметр quality API обозначает битрейт (5000 кбит/с), а не качество JPEG.
Настройки общие для всех подключённых пользователей
и автоматически не восстанавливаются после выхода.
Требуется прошивка с Direct H.264; автоматического возврата к MJPEG нет.
Задержка захвата HDMI, прошивки и сети остаётся.
На устройстве необходимо сравнить результат со старым клиентом:
.venv/bin/python browser.py
Первая версия рассчитана на управление полным HDMI-кадром. Настроенные на устройстве области управления для обрезанного видео и нескольких мониторов, WebRTC, звук, питание, буфер обмена и дополнительные меню не реализованы.
Проверки
.venv/bin/python -m unittest discover -s tests -v
Проверяются сохранение настроек и пароля через тестовый keyring, удаление пароля, отсутствие пароля в файле настроек, HID, шифрование пароля, авторизация, настройки H.264, передача cookies и клавиш, выход из захвата и обрыв связи. Сгенерированный настоящий H.264-поток проверяет декодирование, смену разрешения, отображение последнего кадра, ограничение очереди и обмен подтверждениями через локальный WebSocket. Проверяется также программный fallback при ошибке инициализации GPU. Тесты GUI используют offscreen: они не доказывают захват системных сочетаний реальным оконным менеджером и скорость работы реального NanoKVM.
Протокол: официальные исходники Sipeed
(web/src/pages/desktop/screen/direct.worker.ts, server/service/stream/direct,
web/src/lib/websocket.ts, web/src/lib/mouse.ts, server/utils/encrypt.go).
Повторная сборка deb
На Ubuntu 24.04 / Mint 22, x86-64:
.venv/bin/python -m pip install 'pyinstaller>=6.16,<7'
.venv/bin/python packaging/build_deb.py
Сборка использует текущие установленные зависимости проекта, добавляет ярлык меню и уведомления о лицензиях зависимостей. Она проверяет, что в замороженном Python-коде остались только обезличенные настройки подключения. Профили браузера, тесты, виртуальное окружение целиком и локальные учётные данные в пакет не включаются. Пакет не содержит установочных скриптов и не скачивает Python-зависимости при установке.
Вставка текста с локальной машины
Скопируйте текст на хосте, освободите клавиатуру через Ctrl+Shift+Esc и нажмите «Вставить текст». Диалог показывает текст из локального буфера обмена; его можно отредактировать. Укажите текущую раскладку удалённой машины (English US или русская ЙЦУКЕН) и настроенное в удалённой ОС сочетание переключения: Alt+Shift, Ctrl+Shift или Win+Space. Выбор раскладки описывает её текущее состояние, сам по себе её не переключает. Выключите Caps Lock на удалённой машине.
После подтверждения текст вводится нажатиями HID в активное удалённое поле. Клиент переключает EN/RU по мере ввода и в конце возвращает исходную раскладку. Нужны ровно две включённые раскладки EN/RU; автоматически узнать состояние раскладки через HID нельзя. После ручного переключения проверьте выбор в диалоге. Поддерживаются латиница, кириллица, ASCII-пунктуация, пробел, Tab и перенос строки. Неподдерживаемые символы отклоняются до начала ввода. Максимум — 100 000 символов. Текст не сохраняется приложением на диск.
Во время вставки обычный ввод клавиатуры и мыши блокируется; Ctrl+Shift+Esc, потеря фокуса или соединения останавливают вставку и сбрасывают нажатые клавиши. При остановке уже введённый текст остаётся, раскладка может отличаться от исходной. Enter и Tab отправляются как реальные клавиши: они могут отправить форму, выполнить команду или перевести фокус. Скорость ввода ограничена для USB HID, но получение каждого символа удалённой ОС подтвердить невозможно.
Специальные символы в Windows
Для вставки —, «», →, × и других печатных символов Unicode из основной
многоязычной плоскости включите «Windows: специальные символы через Alt+Unicode»
в диалоге вставки. Режим требует предварительной настройки удалённой Windows:
выполните в её командной строке под тем пользователем, которому вводите текст:
reg add "HKCU\Control Panel\Input Method" /v EnableHexNumpad /t REG_SZ /d 1 /f
Затем выйдите из учётной записи Windows и войдите снова. Клиент не меняет реестр самостоятельно. Для специальных символов он временно выбирает EN и передаёт левый Alt + плюс цифрового блока + шестнадцатеричный код символа, затем отпускает Alt. В конце вставки исходная раскладка восстанавливается, как при обычном вводе.
Поддержка зависит от целевого приложения: сначала проверьте короткий текст в Блокноте. Некоторые приложения перехватывают сочетания с Alt. Эмодзи за пределами U+FFFF и непечатаемые управляющие символы не поддерживаются. При остановке посреди Alt-кода Windows может ввести символ по незавершённому коду. При выключенном режиме прежняя проверка неподдерживаемых символов сохраняется.
При вставке между HID-пакетами выдерживается минимум 50 мс. После отпускания последнего символа перед сменой раскладки и после самого переключения выдерживается 300 мс, чтобы пробелы на границах EN/RU не сливались с сочетанием переключения.