Skip to content

Commit

Permalink
Patch clipboard issue #43 (#73)
Browse files Browse the repository at this point in the history
* [DOCS] Cleanup docs and instructions

* Patch clipboard freeze issue (Issue #43)
  • Loading branch information
ehfd committed Jan 18, 2023
1 parent 56cf144 commit 1f2070b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 25 deletions.
10 changes: 5 additions & 5 deletions Dockerfile.example
Expand Up @@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

# Supported base images: ubuntu:20.04, ubuntu:18.04
# Supported base images: ubuntu:22.04, ubuntu:20.04, ubuntu:18.04
ARG UBUNTU_RELEASE=20.04
ARG GSTREAMER_BASE_IMAGE=ghcr.io/selkies-project/selkies-gstreamer/gstreamer
ARG GSTREAMER_BASE_IMAGE_RELEASE=master
Expand All @@ -16,7 +16,7 @@ ARG UBUNTU_RELEASE

LABEL maintainer "https://github.com/danisla"

# Install Selkies GStreamer system dependencies
# Install Selkies-GStreamer system dependencies
RUN \
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
build-essential \
Expand Down Expand Up @@ -106,7 +106,7 @@ ARG PACKAGE_VERSION=0.0.0.dev0
COPY --from=selkies-build /opt/pypi/dist/${PYPI_PACKAGE}-${PACKAGE_VERSION}-py3-none-any.whl .
RUN pip3 install /opt/${PYPI_PACKAGE}-${PACKAGE_VERSION}-py3-none-any.whl

# Setup global bashrc to configure gstreamer environment
# Setup global bashrc to configure GStreamer environment
RUN echo 'export DISPLAY=:0' \
>> /etc/bash.bashrc && \
echo 'export GST_DEBUG=*:2' \
Expand All @@ -120,13 +120,13 @@ RUN echo 'export DISPLAY=:0' \
RUN echo "#!/bin/bash\n\
export DISPLAY=:0\n\
export GST_DEBUG=*:2\n\
export PULSE_SERVER=127.0.0.1:4713\n\
export GSTREAMER_PATH=/opt/gstreamer\n\
source /opt/gstreamer/gst-env\n\
Xvfb -screen :0 8192x4096x24 +extension RANDR +extension GLX +extension MIT-SHM -nolisten tcp -noreset -shmem 2>&1 >/tmp/Xvfb.log &\n\
until [[ -S /tmp/.X11-unix/X0 ]]; do sleep 1; done && echo 'X Server is ready'\n\
export PULSE_SERVER=tcp:127.0.0.1:4713\n\
sudo /usr/bin/pulseaudio -k >/dev/null 2>&1\n\
sudo /usr/bin/pulseaudio --daemonize --system --verbose --log-target=file:/tmp/pulseaudio.log --realtime=true --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'\n\
/usr/bin/pulseaudio --daemonize --verbose --log-target=file:/tmp/pulseaudio.log --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'\n\
[[ \${START_XFCE4:-true} == true ]] && rm -rf ~/.config/xfce4 && xfce4-session &\n\
export WEBRTC_ENCODER=\${WEBRTC_ENCODER:-x264enc}\n\
export WEBRTC_ENABLE_RESIZE=\${WEBRTC_ENABLE_RESIZE:-true}\n\
Expand Down
32 changes: 16 additions & 16 deletions README.md
Expand Up @@ -46,7 +46,7 @@ docker run --name selkies -it --rm -p 8080:8080 ghcr.io/selkies-project/selkies-

Repositories [`selkies-vdi`](https://github.com/selkies-project/selkies-vdi) or [`selkies-examples`](https://github.com/selkies-project/selkies-examples) from the [Selkies Project](https://github.com/selkies-project) provide containerized virtual desktop infrastructure (VDI) templates.

[`docker-nvidia-glx-desktop`](https://github.com/ehfd/docker-nvidia-glx-desktop) and [`docker-nvidia-egl-desktop`](https://github.com/ehfd/docker-nvidia-egl-desktop) are expandable ready-to-go zero-configuration batteries-included containerized remote desktop implementations of `selkies-gstreamer` supporting hardware acceleration on NVIDIA and other GPUs.
[`docker-nvidia-glx-desktop`](https://github.com/selkies-project/docker-nvidia-glx-desktop) and [`docker-nvidia-egl-desktop`](https://github.com/selkies-project/docker-nvidia-egl-desktop) are expandable ready-to-go zero-configuration batteries-included containerized remote desktop implementations of `selkies-gstreamer` supporting hardware acceleration on NVIDIA and other GPUs.

### Install the packaged version on a standalone machine or cloud instance

Expand Down Expand Up @@ -102,30 +102,30 @@ export GST_DEBUG=*:2
# Initialize the GStreamer environment after setting GSTREAMER_PATH to the path of your GStreamer directory
export GSTREAMER_PATH=/opt/gstreamer
source /opt/gstreamer/gst-env
# Start a virtual X server, skip this line if an X server already exists or you are already using a display
# Start a virtual X11 server, skip this line if an X server already exists or you are already using a display
Xvfb -screen :0 8192x4096x24 +extension RANDR +extension GLX +extension MIT-SHM -nolisten tcp -noreset -shmem 2>&1 >/tmp/Xvfb.log &
# Ensure the X server is ready
until [[ -S /tmp/.X11-unix/X0 ]]; do sleep 1; done && echo 'X Server is ready'
# Initialize PulseAudio, omit the below lines if PulseAudio server is already running
export PULSE_SERVER=127.0.0.1:4713
# Initialize PulseAudio, omit the below lines if a PulseAudio server is already running
export PULSE_SERVER=tcp:127.0.0.1:4713
sudo /usr/bin/pulseaudio -k >/dev/null 2>&1
sudo /usr/bin/pulseaudio --daemonize --system --verbose --log-target=file:/tmp/pulseaudio.log --realtime=true --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'
/usr/bin/pulseaudio --daemonize --verbose --log-target=file:/tmp/pulseaudio.log --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'
# Replace this line with your desktop environment session or skip this line if already running, use VirtualGL `vglrun` here if needed
[[ "${START_XFCE4:-true}" == "true" ]] && rm -rf ~/.config/xfce4 && xfce4-session &
# Write Progressive Web App (PWA) config.
export PWA_APP_NAME="Selkies WebRTC"
export PWA_APP_SHORT_NAME="selkies"
export PWA_START_URL="/index.html"
sed -i \
sudo sed -i \
-e "s|PWA_APP_NAME|${PWA_APP_NAME}|g" \
-e "s|PWA_APP_SHORT_NAME|${PWA_APP_SHORT_NAME}|g" \
-e "s|PWA_START_URL|${PWA_START_URL}|g" \
/opt/gst-web/manifest.json
sed -i \
sudo sed -i \
-e "s|PWA_CACHE|${PWA_APP_SHORT_NAME}-webrtc-pwa|g" \
/opt/gst-web/sw.js
# Choose your video encoder
export WEBRTC_ENCODER=x264enc
export WEBRTC_ENCODER=${WEBRTC_ENCODER:-x264enc}
# Do not enable resize if there is a physical display
export WEBRTC_ENABLE_RESIZE=${WEBRTC_ENABLE_RESIZE:-false}
# Replace to your resolution if using without resize, skip if there is a physical display
Expand Down Expand Up @@ -201,30 +201,30 @@ export GST_DEBUG=*:2
# Initialize the GStreamer environment after setting GSTREAMER_PATH to the path of your GStreamer directory
export GSTREAMER_PATH=/opt/gstreamer
source /opt/gstreamer/gst-env
# Start a virtual X server, skip this line if an X server already exists or you are already using a display
# Start a virtual X11 server, skip this line if an X server already exists or you are already using a display
Xvfb -screen :0 8192x4096x24 +extension RANDR +extension GLX +extension MIT-SHM -nolisten tcp -noreset -shmem 2>&1 >/tmp/Xvfb.log &
# Ensure the X server is ready
until [[ -S /tmp/.X11-unix/X0 ]]; do sleep 1; done && echo 'X Server is ready'
# Initialize PulseAudio, omit the below lines if PulseAudio server is already running
export PULSE_SERVER=127.0.0.1:4713
# Initialize PulseAudio, omit the below lines if a PulseAudio server is already running
export PULSE_SERVER=tcp:127.0.0.1:4713
sudo /usr/bin/pulseaudio -k >/dev/null 2>&1
sudo /usr/bin/pulseaudio --daemonize --system --verbose --log-target=file:/tmp/pulseaudio.log --realtime=true --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'
/usr/bin/pulseaudio --daemonize --verbose --log-target=file:/tmp/pulseaudio.log --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'
# Replace this line with your desktop environment session or skip this line if already running, use VirtualGL `vglrun` here if needed
[[ "${START_XFCE4:-true}" == "true" ]] && rm -rf ~/.config/xfce4 && xfce4-session &
# Write Progressive Web App (PWA) config.
export PWA_APP_NAME="Selkies WebRTC"
export PWA_APP_SHORT_NAME="selkies"
export PWA_START_URL="/index.html"
sed -i \
sudo sed -i \
-e "s|PWA_APP_NAME|${PWA_APP_NAME}|g" \
-e "s|PWA_APP_SHORT_NAME|${PWA_APP_SHORT_NAME}|g" \
-e "s|PWA_START_URL|${PWA_START_URL}|g" \
/opt/gst-web/manifest.json
sed -i \
sudo sed -i \
-e "s|PWA_CACHE|${PWA_APP_SHORT_NAME}-webrtc-pwa|g" \
/opt/gst-web/sw.js
# Choose your video encoder
export WEBRTC_ENCODER=x264enc
export WEBRTC_ENCODER=${WEBRTC_ENCODER:-x264enc}
# Do not enable resize if there is a physical display
export WEBRTC_ENABLE_RESIZE=${WEBRTC_ENABLE_RESIZE:-false}
# Replace to your resolution if using without resize, skip if there is a physical display
Expand Down Expand Up @@ -287,7 +287,7 @@ This table specifies the currently supported transport protocol components.
|---|---|---|---|---|---|
| [`webrtcbin`](https://gstreamer.freedesktop.org/documentation/webrtc/index.html) | [WebRTC](https://webrtc.org) | All | All Major | Various | N/A |

## Using a TURN server
## (IMPORTANT) Using a TURN server

**You are at the right place if the HTML5 web interface loads and the signalling connection works, but the WebRTC connection fails and therefore the remote desktop does not start.**

Expand Down
16 changes: 12 additions & 4 deletions src/selkies_gstreamer/gstwebrtc_app.py
Expand Up @@ -755,8 +755,16 @@ def set_pointer_visible(self, visible):
"pipeline", {"status": "Set pointer visibility to: %d" % visible})

def send_clipboard_data(self, data):
self.__send_data_channel_message(
"clipboard", {"content": base64.b64encode(data.encode()).decode("utf-8")})
# TODO: WebRTC DataChannel accepts a maximum length of 65489 (= 65535 - 46 for '{"type": "clipboard", "data": {"content": ""}}'), remove this restriction after implementing DataChannel chunking
CLIPBOARD_RESTRICTION = 65488
clipboard_message = base64.b64encode(data.encode()).decode("utf-8")
clipboard_length = len(clipboard_message)
logger.debug("clipboard base64 encoded message length: %d" % clipboard_length)
if clipboard_length <= CLIPBOARD_RESTRICTION:
self.__send_data_channel_message(
"clipboard", {"content": clipboard_message})
else:
logger.warning("clipboard may not be sent to the client because the base64 message length {} is {} above the maximum length of {}".format(clipboard_length, clipboard_length - CLIPBOARD_RESTRICTION, CLIPBOARD_RESTRICTION))

def send_cursor_data(self, data):
self.last_cursor_sent = data
Expand Down Expand Up @@ -883,7 +891,7 @@ def __send_data_channel_message(self, msg_type, data):

msg = {
"type": msg_type,
"data": data,
"data": data
}
self.data_channel.emit("send-string", json.dumps(msg))

Expand Down Expand Up @@ -916,7 +924,7 @@ def __on_offer_created(self, promise, _, __):
logger.warning("injecting modified rtx-time to SDP")
sdp_text = re.sub(r'rtx-time=\d+', r'rtx-time=125', sdp_text)
# Firefox needs profile-level-id=42e01f in the offer, but webrtcbin does not add this.
# Remove when fixed in webrtcbin.
# TODO: Remove when fixed in webrtcbin.
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1106
if '264' in self.encoder:
if 'profile-level-id' not in sdp_text:
Expand Down

0 comments on commit 1f2070b

Please sign in to comment.