Press "Enter" to skip to content

Cloud Workspace for Streaming on Twitch.tv

Last updated on December 30, 2020

I’ve been experimenting with streaming on Twitch.tv with the goal of making connections, and sharing what I’ve learned. I have an issue with my home internet bandwidth which makes this tricky. There’s no way I can stream 360p@30fps on this connection, and use the internet for researching.

I want to stream even though I have bad internet, so I created a workaround. Instead of streaming video from my home computer, I stream video from a Virtual Private Server (VPS) in a datacenter.

I have done a few streams using this setup. It is imperfect, but it works!

Most budget VPS don’t have a dedicated graphics card, so I did what I could do to reduce the CPU intensive work that the VPS must perform. Here is a rundown of the setup.

Cloud Streaming Workspace Software

Ubuntu GNU/Linux

Ubuntu is the basis for the cloud workspace. It is familiar to me and I don’t have to worry about license payments. I am running a minimal window manager and desktop environment, openbox and lxqt.

x2go

I use x2go to remotely control my Cloud Streaming Workspace as if I am there. I can see the VPS’s virtual screen, and send mouse and keyboard clicks.

Mumble

I use a mumble server on my cloud workspace, and a mumble client on my home computer to pipe my voice into the cloud workspace. I run another mumble client in the cloud workspace so my voice is captured by FFmpeg.

FFmpeg

FFmpeg streams audio and video straight to Twitch, using the audio and video that is being heard/displayed on the cloud workspace.

Provisioning

I don’t steam much, and I’m broke. Having a VPS running 24/7 which serves a purpose only every now and then doesn’t make much sense for me. Instead of running it non-stop, I instead opted for a workspace solution which I can create and destroy on-demand. That way, I’m paying the hourly rate for only the time I need it.

Here is a look at my Ansible playbook which provisions the VPS to be a cloud workspace.

---

- name: Provision VPS to be a cloud streaming box
  hosts: seedbox
  vars_files:
    - vars/secret.yml
  gather_facts: true
  handlers:
    - name: restart mumble
      systemd:
        state: restarted
        name: mumble-server.service

  tasks:

  - name: create user account
    user:
      state: present
      name: crispy
      password: "{{ secret_crispy_password }}"
      shell: /bin/bash
      groups: sudo
      append: yes

  - name: create home folder
    file:
      state: directory
      path: /home/crispy
      mode: '755'

  - name: create .ssh folder
    file:
      state: directory
      path: /home/crispy/.ssh
      owner: crispy
      group: crispy
      mode: '700'

  - name: copy SSH keys to workspace
    copy:
      src: "{{ item.src }}"
      dest: "{{ item.dest }}"
      owner: crispy
      group: crispy
      mode: "{{ item.mode }}"
      remote_src: no
    with_items:
      - { src: /home/chris/.ssh/kaito.pub, dest: /home/crispy/.ssh/authorized_keys, mode: '0644' }
      - { src: files/tkey.pub, dest: /home/crispy/.ssh/tkey.pub, mode: '0644' }
      - { src: files/tkey, dest: /home/crispy/.ssh/tkey, mode: '0600' }

  # - name: set up ssh-agent

  - name: add x2go ppa
    apt_repository:
      repo: 'ppa:x2go/stable'
      state: present

  - name: install programs
    apt:
      state: present
      pkg:
        - apt-transport-https
        - ca-certificates
        - curl
        - gnupg-agent
        - software-properties-common
        - ffmpeg
        - mumble-server
        - mumble
        - x2goserver
        - x2goserver-xsession
        - python3
        - python-is-python3
        - xterm
        - git
        - mg
        - xorg
        - openbox
        - lxqt
        - xz-utils
        - wormhole


  - name: install nvm
    shell: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
    args:
      creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"

  - name: configure git
    tags:
      - git
    copy:
      src: "{{ item.src }}"
      dest: "{{ item.dest }}"
      owner: crispy
      group: crispy
      mode: '644'
    with_items:
      - { src: files/.gitconfig, dest: /home/crispy/.gitconfig }
      - { src: files/.gitignore, dest: /home/crispy/.gitignore }


  - name: install atom editor
    apt:
      state: present
      deb: https://atom.io/download/deb


  - name: Install atom wordcount package
    tags:
      - atom
    command:
      cmd: /usr/bin/apm install wordcount
      creates: /home/crispy/.atom/packages/wordcount

  - name: download dotfiles
    tags: dotfiles
    git:
      repo: https://github.com/insanity54/dotfiles
      dest: /home/crispy/dotfiles

  - name: configure screen
    tags: dotfiles
    copy:
      src: /home/crispy/dotfiles/.screenrc
      dest: /home/crispy/.screenrc
      remote_src: yes


  - name: configure mumble server
    copy:
      src: files/mumble-server.ini
      dest: /etc/mumble-server.ini
      owner: root
      group: mumble-server
      mode: '640'
    notify: restart mumble

  - name: upload secrets file
    tags:
      - dostream
    copy:
      src: files/.secrets
      dest: /home/crispy/.secrets
      owner: crispy
      group: crispy
      mode: '600'

  - name: create ~/.local/bin dir
    file:
      state: directory
      path: /home/crispy/.local/bin
      mode: '755'

  - name: add ~/.local/bin to path for interactive non-login shells
    lineinfile:
      dest: /home/crispy/.bashrc
      state: present
      line: "export PATH=$PATH:/home/crispy/.local/bin"

  - name: add ~/.local/bin to path for interactive login shells
    lineinfile:
      dest: /home/crispy/.profile
      state: present
      line: "export PATH=$PATH:/home/crispy/.local/bin"

  - name: upload start-stream script
    copy:
      src: files/start-stream
      dest: /home/crispy/.local/bin/start-stream
      owner: crispy
      group: crispy
      mode: '755'

  - name: upload open-mumble script
    copy:
      src: files/open-mumble
      dest: /home/crispy/.local/bin/open-mumble
      owner: crispy
      group: crispy
      mode: '755'

This playbook…

  • Creates a non-root user account
  • Copies my SSH keys from my home computer to the workspace
  • Installs dependency software
  • Installs Node.js
  • Installs my preferred code editors
  • Installs my preferred Bash and Screen preferences
  • Installs Mumble server as a system daemon & configures it
  • Installs a script which handles the FFmpeg incantation for streaming to Twitch

Pretty cool, huh?

After this playbook runs, all I have to do to is…

  • Start Mumble client on my home computer & connect to the Mumble server on my cloud workstation.
  • Open x2go on my home computer, and connect it to my Cloud Workstation (via SSH)
  • Remotely control the cloud workstation, and execute the FFMpeg script.

After that, I’m streaming from the high-speed cloud via my low quality home internet!

Looking for VOCALOID trading cards?

Check out Sakura Blossom Trading Post

Leave a Reply

Your email address will not be published.