Data Streams
Prerequisites
- A working PostmarketOS installation
- Have read through PostmarketOS General Tips
- Ability to login over
SSH
Project examples
Installation
A data stream server consists out of the webserver nginx
and the nginx-mod-rtmp
module. To eventually stream the data to our server, we use a command line utility for audio and video called ffmpeg
nginx
Start with updating and upgrading Alpine Linux
sudo apk update && sudo apk upgrade -U
Followed by installing nginx
sudo apk add nginx
Firewall
PostmarketOS has a very strict firewall as stated in the PostmarketOS General Tips. If we want to eventually make our stream accessible locally, we need to disable the firewall. Run the following command to temporary disable the firewall.
sudo rc-service nftables stop
When we reboot the phone, the firewall will be enabled again. So in order to completely disable the firewall you can run the following command
sudo rc-update del nftables
Setting up a simple webpage
To eventually show our stream, we need to create a simple webpage. You can do this by changing the configuration of nginx. This is done by editing the nginx.conf
file on the phone. In this tutorial we will be spending quite some time editing the nginx.conf
file.
The following steps are almost an exact copy of the Alpine Linux wiki.
Create a new user and group named 'www' for nginx
sudo adduser -D -g 'www' www
Create a directory for storing our html files
sudo mkdir -p /var/www/html sudo chown -R www:www /var/lib/nginx sudo chown -R www:www /var/www
We may want to make backup of the original nginx.conf
file before writing our own.
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig
Lets create a new nginx.conf
file and add the following lines to display a simple HTML
page which we will create later.
user www; # <-- the user we created worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx/nginx.pid; include /etc/nginx/modules/*.conf; include /etc/nginx/conf.d/*.conf; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; access_log /var/log/nginx/access.log; keepalive_timeout 3000; server { listen 80; root /var/www/html; # <-- the location of our HTML files index index.html index.htm; # <-- the name of the HTML file that the browser will load server_name localhost; client_max_body_size 32m; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/lib/nginx/html; } } }
Now we can finally create our HTML
page! We will be saving this page in the /var/www/html/
directory, because we specified that as our root
directory in the nginx.conf
file.
Open a new file...
sudo nano /var/www/html/index.html
...and paste the following content:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Data Streams</title> </head> <body> Woop!! </body> </html>
Now, after restarting nginx
, your webpage should be visible by typing the phone's IP address in your browser! To restart nginx:
sudo rc-service nginx restart
NOTE: If you want to know more about creating webpages, there are some great quick start guides on HTML
and CSS
nginx-mod-rtmp
sudo apk add nginx-mod-rtmp
After installing the nginx-mod-rtmp
we need to add a configuration block to the nginx
configuration file that tells nginx
where the stream will be available. Open the configuration file found at /etc/nginx/nginx.conf
and add the following contents to the end of the file.
rtmp { server { listen 1935; chunk_size 4096; allow publish 127.0.0.1; deny publish all; application live { live on; record off; dash on; dash_path /var/www/html/stream/dash; } } }
We also need to add the following at the end of the http
block in the nginx.conf
file. This will allow us to stream in the MPEG-DASH
format, which we can show on webpages.
server { listen 8088; location /dash { types { application/dash+xml mpd; video/mp4 mp4; audio/mp4 m4a; video/mp4 m4v; } root /var/www/html/stream; add_header Access-Control-Allow-Origin *; add_header Cache-Control no-cache; } }
Make sure to create the root
folder which we will use for streaming
sudo mkdir /var/www/html/stream
And restart nginx
to make sure everything is working
sudo rc-service nginx restart
ffmpeg
To stream an audio or video file to our rtmp
server, we need to install ffmpeg
.
sudo apk add ffmpeg
After installing we are almost ready to start streaming
Usage
Uploading files
If you've followed along with installing PostmarketOS, you've enabled the SSH daemon
. This also allows us to upload files to your phone over SFTP
. Open your favorite (S)FTP
client (ex.: filezilla or cyberduck) and enter the ip address and username of your PostmarketOS installation. An example:
server: 192.168.2.130 port: 22 username: user password: 147147
After connecting to your phone, you should be able to upload files. As an example, we're uploading a file named video.mp4
to the home
folder of the user named user
.
Streaming video files
Running the following ffmpeg
command will stream video.mp4
to our rtmp
server.
ffmpeg -stream_loop -1 -re -i video.mp4 -c:v copy -f flv rtmp://localhost/live/stream
However, we can not actually see the video we are streaming. For that we need to edit our webpage
Video stream webpage
The following code snippet is a simple webpage for showing a video stream. It uses the JavaScript library dashjs to display the stream. You can replace the code in /var/www/html/index.html
with the code below to see your video when your run the ffmpeg command.
Open /var/www/html/index.html
...
sudo nano /var/www/html/index.html
...and replace with the following
- (make sure that you replace the
const url ip
with your own!)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Data Streams</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.7.1/dash.all.min.js"></script> <style> .video-container { max-width: 800px; margin: 20px auto; } video { width: 100%; } </style> </head> <body> <div class="video-container"> <video id="videoPlayer" controls></video> </div> <script> (() => { const url = "http://10.13.37.160:8088/dash/stream.mpd"; const player = dashjs.MediaPlayer().create(); player.initialize(document.querySelector("#videoPlayer"), url, true); player.on("error", (e) => { console.error("Error playing stream:", e); }); })(); </script> </body> </html>
And restart nginx
sudo rc-service nginx restart
Run the ffmpeg command and visit your webpage by entering your phone's IP address in the browser bar. You should see your video playing!
References
Useful Links
FFmpeg guide
FFmpeg effects|filters|aesthetics|
Fun Stuff to experiment with
- Maptastic: Javascript/CSS projection mapping utility. Put your internets on things!
Inspirational?
- Smartphone Powered Laptop
- Guide: Running Blender (or anything else) via X11 over SSH
- (Did not work with Oneplus 6 due X11/Wayland bugs)