Edit reStream.sh and README
This commit is contained in:
parent
4c27256fef
commit
a0248760bd
33
README.md
33
README.md
@ -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.
|
||||
|
BIN
lz4.arm.static
BIN
lz4.arm.static
Binary file not shown.
76
reStream.sh
76
reStream.sh
@ -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
BIN
restream.arm.static
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user