Edit reStream.sh and README

This commit is contained in:
Rien Maertens 2020-12-31 14:57:33 +01:00
parent 4c27256fef
commit a0248760bd
No known key found for this signature in database
GPG Key ID: AE66CE42F1AF9DEF
4 changed files with 31 additions and 78 deletions

View File

@ -10,8 +10,14 @@ reMarkable screen sharing over SSH.
## Installation
1. Clone this repository: `git clone https://github.com/rien/reStream`.
2. (Optional but recommended) [Install lz4 on your host and reMarkable](#sub-second-latency).
2. Install `lz4` on your host with your usual package manager. On Ubuntu,
`apt install liblz4-tool` will do the trick.
3. [Set up an SSH key and add it to the ssh-agent](https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent), then add your key to the reMarkable with `ssh-copy-id root@10.11.99.1`.
4. Copy the `restream` executable to the reMarkable and make it executable.
```
# scp restream.arm.static root@10.11.99.1:/home/root/restream
# ssh root@10.11.99.1 'chmod +x /home/root/restream'
```
## Usage
@ -27,7 +33,7 @@ reMarkable screen sharing over SSH.
- `-s --source`: the ssh destination of the reMarkable (default: `root@10.11.99.1`)
- `-o --output`: path of the output where the video should be recorded, as understood by `ffmpeg`; if this is `-`, the video is displayed in a new window and not recorded anywhere (default: `-`)
- `-f --format`: when recording to an output, this option is used to force the encoding format; if this is `-`, `ffmpeg`s auto format detection based on the file extension is used (default: `-`).
- `-w --webcam`: record to a video4linux2 web cam device. By default the first found web cam is taken, this can be overwritten with `-o`. The video is scaled to 1280x720 to ensure compatibility with MS Teams, Skype for business and other programs which need this specific format.
- `-w --webcam`: record to a video4linux2 web cam device. By default the first found web cam is taken, this can be overwritten with `-o`. The video is scaled to 1280x720 to ensure compatibility with MS Teams, Skype for business and other programs which need this specific format. See [video4linux loopback](#video4linux-loopback) for installation instructions.
- `-m --measure`: use `pv` to measure how much data throughput you have (good to experiment with parameters to speed up the pipeline)
- `-t --title`: set a custom window title for the video stream. The default title is "reStream". This option is disabled when using `-o --output`
@ -41,24 +47,7 @@ On your **host** machine:
- ssh
- Video4Linux loopback kernel module if you want to use `--webcam`
On your **reMarkable** nothing is needed, unless you want...
### Sub-second latency
To achieve sub-second latency, you'll need [lz4](https://github.com/lz4/lz4)
on your host and on your reMarkable.
You can install `lz4` on your host with your usual package manager. On Ubuntu,
`apt install liblz4-tool` will do the trick.
On your **reMarkable** you'll need a binary of `lz4` build for the arm platform,
you can do this yourself by [installing the reMarkable toolchain](https://remarkablewiki.com/devel/qt_creator#toolchain)
and compiling `lz4` from source with the toolchain enabled, or you can use the
statically linked binary I have already built and put in this repo.
Copy the `lz4` program to your reMarkable with
`scp lz4.arm.static root@10.11.99.1:/home/root/lz4`, make it executable with
`ssh root@10.11.99.1 'chmod +x /home/root/lz4'` and you're ready to go.
On your **reMarkable** you need the `restream` binary (see [installation instructions](#installation)).
### Video4Linux Loopback
@ -89,3 +78,7 @@ The result should contain a line with "platform:v4l2loopback".
Steps you can try if the script isn't working:
- [Set up an SSH key](#installation)
- Update `ffmpeg` to version 4.
## Development
If you want to play with the `restream` code, you will have to [install Rust](https://www.rust-lang.org/learn/get-started) and [setup the reMarkable toolchain](https://github.com/canselcik/libremarkable#setting-up-the-toolchain) to do cross-platform development.

Binary file not shown.

View File

@ -92,42 +92,14 @@ case "$rm_version" in
"reMarkable 1.0")
width=1408
height=1872
bytes_per_pixel=2
pixel_format="rgb565le"
# calculate how much bytes the window is
window_bytes="$((width * height * bytes_per_pixel))"
# read the first $window_bytes of the framebuffer
head_fb0="dd if=/dev/fb0 count=1 bs=$window_bytes 2>/dev/null"
transpose=0
;;
"reMarkable 2.0")
pixel_format="gray8"
width=1872
height=1404
bytes_per_pixel=1
# calculate how much bytes the window is
window_bytes="$((width * height * bytes_per_pixel))"
# find xochitl's process
pid="$(ssh_cmd pidof xochitl)"
echo "xochitl's PID: $pid"
# find framebuffer location in memory
# it is actually the map allocated _after_ the fb0 mmap
read_address="grep -C1 '/dev/fb0' /proc/$pid/maps | tail -n1 | sed 's/-.*$//'"
skip_bytes_hex="$(ssh_cmd "$read_address")"
skip_bytes="$((0x$skip_bytes_hex + 8))"
echo "framebuffer is at 0x$skip_bytes_hex"
# carve the framebuffer out of the process memory
page_size=4096
window_start_blocks="$((skip_bytes / page_size))"
window_offset="$((skip_bytes % page_size))"
window_length_blocks="$((window_bytes / page_size + 1))"
# Using dd with bs=1 is too slow, so we first carve out the pages our desired
# bytes are located in, and then we trim the resulting data with what we need.
head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | head -c $window_bytes"
transpose=1
;;
*)
echo "Unsupported reMarkable version: $rm_version."
@ -137,33 +109,23 @@ case "$rm_version" in
esac
# technical parameters
loop_wait="true"
loglevel="info"
decompress="lz4 -d"
fallback_to_gzip() {
echo "Falling back to gzip, your experience may not be optimal."
echo "Go to https://github.com/rien/reStream/#sub-second-latency for a better experience."
compress="gzip"
decompress="gzip -d"
sleep 2
}
# check if lz4 is present on remarkable
if ssh_cmd "[ -f /opt/bin/lz4 ]"; then
compress="/opt/bin/lz4"
elif ssh_cmd "[ -f ~/lz4 ]"; then
compress="\$HOME/lz4"
# check if lz4 is present on the host
if ! lz4 -V >/dev/null; then
echo "Your host does not have lz4."
echo "Please install it using the instruction in the README:"
echo "https://github.com/rien/reStream/#installation"
exit 1
fi
# gracefully degrade to gzip if is not present on remarkable or host
if [ -z "$compress" ]; then
echo "Your remarkable does not have lz4."
fallback_to_gzip
elif ! lz4 -V >/dev/null; then
echo "Your host does not have lz4."
fallback_to_gzip
else
decompress="lz4 -d"
# check if restream binay is present on remarkable
if ssh_cmd "[ ! -f ~/restream ]"; then
echo "The restream binary is not installed on your reMarkable."
echo "Please install it using the instruction in the README:"
echo "https://github.com/rien/reStream/#installation"
exit 1
fi
# use pv to measure throughput if desired, else we just pipe through cat
@ -186,7 +148,8 @@ video_filters=""
set --
# rotate 90 degrees if landscape=true
$landscape && video_filters="$video_filters,transpose=1"
$landscape && transpose="$((transpose + 1))"
[ $transpose != 0 ] && video_filters="$video_filters,transpose=$transpose"
# Scale and add padding if we are targeting a webcam because a lot of services
# expect a size of exactly 1280x720 (tested in Firefox, MS Teams, and Skype for
@ -200,9 +163,6 @@ fi
# set each frame presentation time to the time it is received
video_filters="$video_filters,setpts=(RTCTIME - RTCSTART) / (TB * 1000000)"
# loop that keeps on reading and compressing, to be executed remotely
read_loop="while $head_fb0; do $loop_wait; done | $compress"
set -- "$@" -vf "${video_filters#,}"
if [ "$output_path" = - ]; then
@ -222,7 +182,7 @@ fi
set -e # stop if an error occurs
# shellcheck disable=SC2086
ssh_cmd "$read_loop" \
ssh_cmd "./restream" \
| $decompress \
| $host_passthrough \
| "$output_cmd" \

BIN
restream.arm.static Executable file

Binary file not shown.