This project is designed to turn almost any PC into a living room TV-Style Streamer, controlled with an airmouse and wireless keyboard, for accessing streaming services, websites, news, weather, and time.
Note
The minimum hardware requirements for the TV Streamer have not been determined yet.
Note
It is highly recommended to pair the TV Streamer with both an airmouse and a wireless keyboard. The current airmouse browser navigation is not guaranteed to work with every website, so the wireless keyboard acts as a fallback device to control the websites/streaming services.
Almost any computer can be used for the TV Streamer, including Mini PCs, Dell Optiplex systems, and old laptops.
You only need to install the ISO, connect it to your TV, and use an airmouse for control.
Warning
I am not sponsored by or affiliated with any vendors. while I have tested the models listed below, I cannot guarantee the reliability, safety, or trustworthiness of any linked vendors, so please research before purchasing. most airmouses share similar layouts and the TV Streamer works with any model that provides the standard keys.
The following models have been tested and confirmed to work:
EASYTONE - Airmouse
WeChip W1 - Airmouse
MagiDeal - Wireless Keyboard
Vendor links:
https://www.aliexpress.com/item/1005005245440379.html
https://www.amazon.com/dp/B08DFDNZCV?ref=ppx_yo2ov_dt_b_fed_asin_title
https://www.aliexpress.com/item/1005010274597702.html
Note
The long-term goal of this project is to base the TV Streamer on a fork of my Easy Arch distribution, which can be modified and used as a base. However, due to current issues with that project, Manjaro is being used as the base for now. I am not familiar with how to fully setup and automate custom Manjaro builds, so much of the setup must currently be done manually until the project is migrated and automated.
-
Download the Manjaro Cinnamon ISO
Head over to the official Manjaro website and download the Cinnamon edition:
-
Create a Bootable USB
Use one of the following tools to write the ISO to a USB drive:
- balenaEtcher (Windows/macOS/Linux)
- Rufus (Windows only)
- Or use the
ddcommand (Linux/macOS):
sudo dd if=manjaro-cinnamon-25.0.3-250609-linux612.iso of=/dev/sdX bs=4M status=progress && sync⚠️ Replace/dev/sdXwith your actual USB device (this will erase the disk).⚠️ Replacemanjaro-cinnamon-25.0.3-250609-linux612.isowith the name of the downloaded ISO. -
Boot from USB
Reboot your machine and use your BIOS/UEFI boot menu to boot from the USB drive.
When the boot options appear, pressBoot with open-source drivers. -
Live Environment and Installation
After booting, the ISO will load into a live session. When the Manjaro Hello window appears, begin the installation by clicking
Launch Installer, located at the bottom center under the INSTALLATION text label.Select your preferred language, region, timezone (time is displayed on the home page), and keyboard layout.
Check
Erase disk, uncheckEncrypt system, and clickNext.For What is your name?, What name do you want to use to log in?, and What is the name of this computer?, write:
tv-streamerFor password, write:
passCheck
Log in automatically, checkUse the same password for the administrator account., and clickNext.Select
No Office Suite., clickNext, clickInstall, and clickInstall Now.When Manjaro Cinnamon completes the installation check
Restart now, and clickDone. -
First Boot After Installation
In the Manjaro Hello window, uncheck
Launch at start, and close the window. In the Save history window, clickNo, and close the window.
Warning
Do not share your API key with anyone!
-
First Manual Step
Generate a YouTube Data API v3 key (follow Google documentation or follow or lookup a YouTube tutorial video).
https://console.developers.google.com
https://developers.google.com/youtube/registering_an_application
https://www.youtube.com/watch?v=XEZYadc2o-8
Once you have your API key, run the following to make it available to the system:
⚠️ Replace API_GOES_HERE with your YouTube Data API v3 key.echo 'export YT_DATA_API_KEY="API_GOES_HERE"' >> ~/.bashrcReload shell:
source ~/.bashrc -
Run the Setup Script
Click the terminal icon in the bottom left corner of the panel.
Git clone this repository:
git clone https://github.com/devbyte1328/personal-tv-streamer-isoNavigate into the setup directory:
cd personal-tv-streamer-iso/setup/Set permissions for setup.sh:
sudo chmod +x setup.shRun setup.sh with sudo and your YouTube API key:
sudo YT_DATA_API_KEY="$YT_DATA_API_KEY" ./setup.sh -
Manual Setup
Configure Firewall Settings: In the Terminal, run Firewall with sudo:
sudo gufwCheck Status.
Configure Power Management Settings:
Click Menu, search for and press Power Management, set
Turn off ScreentoNever, and setPower ButtontoShut Down.Configure Sleep Mode Settings:
Click Menu, search for and press Screensaver, set
Delay before startng the screensavertoNever, and uncheckLock the computer after the screensaver starts.Configure Startup Applications:
Click Menu, search for and press Startup Applications, uncheck
Blueman Applet, uncheckClipit, uncheckManjaro Hello, and uncheckMSM Notifier.Configure Notifications:
Click Menu, search for and press Notifications, uncheck
Enable notifications.Configure Sound Settings:
Click Menu, search for and press Sound, click on the
HDMIdevice (or whatever you connected your TV Streamer to).Configure Display Settings:
Click Menu, search for and press Display, set
Resolutionto1920 x 1080(16:9), and setRefresh Rateto30.00 Hz.Configure Mouse Settings: Click Menu, search for and press Mouse and Touchpad, set
Sizeto max (or adujst to your screen).Configure Librewolf Settings:
Click Menu, search for and press Librewolf.
Visit the URL:
about:addonsCheck
Loading Spinner (disabled), clickEnableon the pop up, and clickOk.Visit the Tampermonkey Addon URL:
https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/Click
Add to Firefox, clickContinue to Installation, When install completes, clickAdd, checkPin extention to toolbar, clickOK, click on the Tampermonkey icon at the top right corner, clickDashboard, click⊞(create new script icon) → Copy and paste the content from /home/tv-streamer/personal-tv-streamer-iso/setup/Tampermonkey.js, save with CTRL+S or clickFileandSave.Click the hamburger icon (top right corner), click
Settings, "General", scroll to or search for Translations under the General section, and uncheckEnable fullpage translations.Scroll to or search for DRM under the General section, and check
Play DRM-controlled content.Scroll to or search for Zoom under the General section, and set
Default Zoomto120%or adujst based on your screen.Scroll to or search for Delete cookies under the Privacy & Security section, and uncheck
Delete cookies and site data when Librewolf is closed.Visit the URL:
about:configSearch for and set to
0:media.autoplay.defaultSearch for and set to
false:media.autoplay.block-webaudioSearch for and set to
false:media.block-autoplay-until-in-foregroundSearch for and set to
true:media.autoplay.enabledSearch for and set to
true:toolkit.legacyUserProfileCustomizations.stylesheetsSearch for and set to
1:browser.link.open_newwindowSearch for and set to
false:browser.sessionstore.resume_from_crashSearch for and set to
false:browser.sessionstore.restore_on_demandSearch for and set to
0:browser.sessionstore.max_resumed_crashesConfigure Weather and Forecast:
Here is the content of /home/tv-streamer/personal-tv-streamer-iso/database/locations.txt:
LocaleString: "en-US" Timezone: "America/New_York" WeatherLocation1: "New York" WeatherLocation2: "Dallas"The weather and forecast API is provided for free by https://open-meteo.com/, to find the available parameters supported by Open-Meteo visit the following wikipedia page:
https://en.wikipedia.org/wiki/List_of_tz_database_time_zonesModify locations.txt to your target timezone and location.
-
Reboot
Reboot to finalize changes:
sudo reboot
It’s possible to service TV Streamers remotely by setting up an update server and configuring the client to check the server for available updates on every boot.
When running the Python script main.py for the first time, the files /database/clientinfo and /database/serverinfo are created.
Here is the content of clientinfo:
Version: 0.2.0+None.1
Modify None to name the TV-Streamer, the name is sent to the server for device specific updates.
Here is the content of serverinfo:
IP: 0.0.0.0
PORT: 8764
Modify IP to match the target server's IP address.
Warning
Do not skip the next part! If you do, you risk exposing your TV Streamers to remote code executions.
Warning
Do not share your encryption key with anyone!
There is an encryption key in main.py and update-server/server.py that looks like this (don't worry the key is for demonstration/error avoidance purposes):
SHARED_KEY = b'UM_pZBDsFnObCNvGijuUAiLexwfgPOv3ATMHvxjAa-Q='
Generate the secret encryption key by running update-server/gen-key.py, then update SHARED_KEY in main.py and update-server/server.py with the new encryption key.
The server files are located in the update-server/ directory. Inside the update-server/payload/ directory there is the template folder None, inside the template folder there are two important files that are used for updating client/s: clientinfo and update-com.sh.
When you have files and commands you want to service your client/s, you have to copy and paste the None directory into the same directory, rename the new directory to the client TV-Streamer name, place your new files inside, add your new commands to update-com.sh, and increment the Build value (the last number) in update-server/payload/<TARGET-CLIENT>/clientinfo by 1.
You can then run server.py to service client/s once they boot up and click Update.
Server logs show every time client/s boot up:
[2026-01-15 19:07:43.605954] [123.456.789.00:1682] [CONNECT] opened
[2026-01-15 19:07:43.617052] [123.456.789.00:1682] [HANDSHAKE] shared key validated
[2026-01-15 19:07:43.622175] [123.456.789.00:1682] [RECEIVED] {"UpdateCheck": [{"Version": "0.2.0+FamilyMember.1"}]}
If the client Build value is lower than the Build value in update-server/payload/<TARGET-CLIENT>/clientinfo the server sends UpdateCheck with the boolean set to True:
[2026-01-15 19:07:43.622290] [123.456.789.00:1682] [RESPONDED] UpdateCheck=True
[2026-01-15 19:07:43.632548] [123.456.789.00:1682] [DISCONNECT] closed
When client receives UpdateCheck=True, an update button, highlighted with a bright yellow indicator, appears under the Apps page. Upon pressing Update, the server receives the request and initiates the transfer of new files and commands to the client:
[2026-01-15 19:08:01.102433] [123.456.789.00:1682] [CONNECT] opened
[2026-01-15 19:08:01.108221] [123.456.789.00:1682] [HANDSHAKE] shared key validated
[2026-01-15 19:08:01.114902] [123.456.789.00:1682] [RECEIVED] {"UpdateRequest": [{"Version": "0.2.0+FamilyMember.1"}]}
[2026-01-15 19:08:01.201883] [123.456.789.00:1682] [RESPONDED] UpdateRequest files=8
[2026-01-15 19:08:01.214557] [123.456.789.00:1682] [DISCONNECT] closed
During file transfer, the TV Streamer client covers the screen with a loading spinner to indicate that an update is in progress. Once the file transfer is complete, the TV Streamer moves the new files into the /home/tv-streamer/personal-tv-streamer-iso/ directory, executes update-com.sh, deletes update-com.sh, and reboots.
The first command in update-com.sh updates the Build value to avoid repeating the same update request.
Logs are saved at update-server/logs.txt.
-
Open-Meteo Weather API (https://open-meteo.com/) - Provides weather and forecast data.
-
Network Time Protocol (NTP) - System time is synchronized via the operating system’s configured NTP sources (probably pool.ntp.org or Manjaro/Arch Linux regional time servers).
-
Assets & Icons (https://github.com/devbyte1328/personal-tv-streamer-iso/blob/main/static/assets/asset-origins.txt) - many icons used in the App page are sourced and modified from third-party creators, some of them require attributions as part of their license.
-
Tampermonkey (https://www.tampermonkey.net/) - The current airmouse browser navigation is powered by the Tampermonkey (created by Jan Biniok) browser extension, please consider visiting and contributing to the Tampermonkey project.







