Resolves https://github.com/tiny-pilot/tinypilot/issues/1431 <s>Blocked on https://github.com/tiny-pilot/tinypilot/issues/1430</s> As part of our war on Ansible, this PR removes the entire TinyPilot Ansible role. We now only use Ansible to run the uStreamer Ansible role via the Ansible playbook (i.e., `install.yml`), instead of via the now deprecated TinyPilot Ansible role. Notes 1. Moved all the Ansible variables in `ansible-role/vars/main.yml` to the end of `ansible-role-ustreamer/vars/main.yml` 1. Moved the `ansible-role/molecule` directory to `ansible-role-ustreamer/molecule` - Molecule now directly tests `ansible-role-ustreamer` 1. Moved `ansible-role/docs/usb-gadget-driver.md` to `docs/usb-gadget-driver.md` (for lack of a better idea) 1. Deleted what was left of the `ansible-role` directory 1. Installed the TinyPilot Debian package directly from the bundler `install` script 1. In terms of documentation, I've either removed or reworded any docs that reference the TinyPilot Ansible role (i.e., `ansible-role` or `ansible-role-tinypilot`) You can test this PR on a physical device using the following command: ```bash curl \ --silent \ --show-error \ --location \ https://raw.githubusercontent.com/tiny-pilot/tinypilot/master/scripts/install-bundle | \ sudo bash -s -- \ https://output.circle-artifacts.com/output/job/d575393e-8ff8-4cb8-a596-504bb799c8b2/artifacts/0/bundler/dist/tinypilot-community-20230720T1336Z-1.9.0-64+dde6828.tgz ``` <a data-ca-tag href="https://codeapprove.com/pr/tiny-pilot/tinypilot/1509"><img src="https://codeapprove.com/external/github-tag-allbg.png" alt="Review on CodeApprove" /></a>
4.2 KiB
TinyPilot's Architecture
Overview
TinyPilot frontend
The TinyPilot frontend runs in the user's browser. It is responsible for:
- Presenting the target computer's video stream in the browser window
- Forwarding keyboard and mouse input to the TinyPilot backend
- Offering friendly interfaces for the user to change TinyPilot's settings
The TinyPilot frontend is a pure HTML/CSS/JS app. It has no build or compilation step and no framework like Vue, Angular, or React. It uses external libraries as little as possible.
The frontend makes heavy use of HTML Custom Elements. Modern browsers support these natively. TinyPilot's custom elements try to mirror the style of Vue's Single File Components.
TinyPilot's custom elements can be found in app/templates/custom-elements.
TinyPilot backend
The backend is a Flask application. It offers handles three types of requests:
- Page requests
- To serve a page like the main
/view, TinyPilot uses Flask to pre-render a template.
- To serve a page like the main
- REST requests
- When the frontend makes a request to the backend to query server state or perform some action (e.g.,
/api/shutdown), the backend handles it through REST handlers.
- When the frontend makes a request to the backend to query server state or perform some action (e.g.,
- WebSockets requests
- To handle requests for keystrokes or mouse movements, the backend needs something faster than regular HTTP REST requests, so it uses a WebSockets channel.
The backend is responsible for sending keyboard and mouse input to the target computer via its USB gadgets (see USB gadgets section, below).
USB gadgets
TinyPilot impersonates keyboard and mouse input using the Linux USB Gadget API.
To use the USB Gadget API, a device needs a USB port that operates in either device mode or supports USB OTG (which allows the port to switch between host mode and device mode). The Raspberry Pi 4B's USB-C port is the only port on the device capable of USB OTG, so this is the port that TinyPilot uses.
TinyPilot presents itself to the target computer as a USB Multifunction Composite Gadget (i.e., a USB hub) with a USB keyboard and mouse attached. This allows TinyPilot to send both keyboard and mouse input through a single USB connection.
nginx
nginx is a popular open-source web server and reverse proxy.
TinyPilot uses nginx to listen to incoming HTTP requests and proxy them to the correct internal component. It also serves all of TinyPilot's static resources (i.e., files that don't need to go through Flask for server-side processing).
uStreamer
uStreamer is a third-party video streaming tool. It is much faster than other options and generally delivers a stream on a local network with latency between 100-200ms.
Its workflow is:
- Capture video from an HDMI capture device
- Encode the video to MJPEG (if it's not already MJPEG) and apply any other video transformations
- Stream the video over an HTTP endpoint
Modern browsers support MJPEG natively, but it has a few drawbacks:
- It's bandwidth-hungry, as a 30 frames-per-second stream means sending 30 JPEG images per second
- Browser implementation tends to be buggy since it's not a common format
As of Feb. 2021, uStreamer's maintainer is working on a H264 option, expected to be available in Q1 or Q2 2021. This will likely alleviate issues around MJPEG.
Software Distribution (Installation, Updates)
The TinyPilot software is distributed as a single-file tarball bundle, which is meant to be installed in a Raspberry Pi environment. From a high level, a bundle contains:
- The code for the TinyPilot web service
- The procedures for configuring the target system (e.g., writing settings files or setting up services)
- Metadata (e.g., the TinyPilot version)
For more details, see the README of the bundler.