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-DASHformat, 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 ipwith 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)