diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..ac4287b70
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,156 @@
+name: Build
+on: push
+
+jobs:
+  macos:
+    name: Build for macOS
+    runs-on: macos-10.15
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Setup Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: '3.7'
+
+      - name: Check Python install
+        run: |
+          which python3
+          python3 --version
+          which pip3
+          pip3 --version
+
+      - name: Install Python dependencies
+        run: |
+          pip3 install -U setuptools wheel pip
+          pip3 install twisted[tls] appnope requests certifi
+          pip3 install shiboken2==5.13.1 pyside2==5.13.1
+          pip3 install py2app
+
+      - name: Check Python dependencies
+        run: |
+          python3 -c "from PySide2 import __version__; print(__version__)"
+          python3 -c "from PySide2.QtCore import __version__; print(__version__)"
+          python3 -c "from PySide2.QtCore import QLibraryInfo; print(QLibraryInfo.location(QLibraryInfo.LibrariesPath))"
+          python3 -c "import ssl; print(ssl)"
+          python3 -c "from py2app.recipes import pyside2"
+          echo $DYLD_LIBRARY_PATH
+          echo $DYLD_FRAMEWORK_PATH
+          python3 -c 'from distutils.sysconfig import get_config_var; print(get_config_var("LDLIBRARY"))'
+          ls -al /Users/runner/hostedtoolcache/Python/3.7.9/x64/lib/*.dylib
+
+      - name: Build
+        run: |
+          python3 ci/pyside2_linker.py
+          export LIBPYTHON_FOLDER="$(python3 -c 'from distutils.sysconfig import get_config_var; print(get_config_var("LIBDIR"))')"
+          ln -s $LIBPYTHON_FOLDER/libpython3.7m.dylib $LIBPYTHON_FOLDER/libpython3.7.dylib
+          export DYLD_FRAMEWORK_PATH="$(python3 -c 'from PySide2.QtCore import QLibraryInfo; print(QLibraryInfo.location(QLibraryInfo.LibrariesPath))')"
+          export DYLD_LIBRARY_PATH="$(python3 -c 'import os.path, PySide2; print(os.path.dirname(PySide2.__file__))'):$(python3 -c 'import os.path, shiboken2; print(os.path.dirname(shiboken2.__file__))')"
+          python3 buildPy2app.py py2app
+
+      - name: Prepare for deployment
+        run: |
+          ls -al
+          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
+          echo "VER=$VER" >> $GITHUB_ENV
+          mkdir dist_actions
+          ci/macos-deploy.sh
+          ls -al dist_actions
+
+      - name: Deploy
+        uses: actions/upload-artifact@v2
+        with:
+          name: Syncplay_${{ env.VER }}.dmg
+          path: |
+            dist_actions/Syncplay_${{ env.VER }}.dmg
+
+  snapcraft:
+    name: Build Snap
+    runs-on: ubuntu-18.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Install Snapcraft with LXD
+        uses: samuelmeuli/action-snapcraft@v1
+        with:
+          use_lxd: true
+
+      - name: Build
+        run: sg lxd -c 'snapcraft --use-lxd'
+
+      - name: Prepare for deployment
+        run: |
+          ls -al
+          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
+          echo "VER=$VER" >> $GITHUB_ENV
+          mkdir dist_actions
+          mv syncplay_build_amd64.snap dist_actions/syncplay_${VER}_amd64.snap
+          ls -al dist_actions
+
+      - name: Deploy
+        uses: actions/upload-artifact@v2
+        with:
+          name: syncplay_${{ env.VER }}_amd64.snap
+          path: |
+            dist_actions/syncplay_${{ env.VER }}_amd64.snap
+
+  appimage:
+    name: Build AppImage
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Install dependencies
+        run: |
+          sudo apt-get install libxkbcommon-x11-0
+
+      - name: Build
+        run: ci/appimage-script.sh
+
+      - name: Prepare for deployment
+        run: |
+          ls -al
+          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
+          echo "VER=$VER" >> $GITHUB_ENV
+          mkdir dist_actions
+          ci/appimage-deploy.sh
+          ls -al dist_actions
+
+      - name: Deploy
+        uses: actions/upload-artifact@v2
+        with:
+          name: Syncplay-${{ env.VER }}-x86_64.AppImage
+          path: |
+            dist_actions/Syncplay-${{ env.VER }}-x86_64.AppImage
+
+  deb:
+    name: Build Debian package
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Build
+        run: ci/deb-script.sh
+
+      - name: Test
+        run: ci/deb-installation-test.sh
+
+      - name: Prepare for deployment
+        run: |
+          ls -al
+          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
+          echo "VER=$VER" >> $GITHUB_ENV
+          mkdir dist_actions
+          mv /tmp/syncplay.deb dist_actions/syncplay_${VER}.deb
+          ls -al dist_actions
+
+      - name: Deploy
+        uses: actions/upload-artifact@v2
+        with:
+          name: syncplay_${{ env.VER }}.deb
+          path: |
+            dist_actions/syncplay_${{ env.VER }}.deb
diff --git a/.gitignore b/.gitignore
index 298a39bf2..a4e09f9b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,6 @@ venv
 syncplay_setup.nsi
 dist.7z
 .*
-!.travis.yml
 !.appveyor.yml
+!.github
 __pycache__
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 98a03bfad..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-# These two are defaults, which get overriden by the jobs matrix
-language: minimal
-os: linux
-
-jobs:
-  include:
-    - language: objective-c
-      os: osx
-      osx_image: xcode8.3
-    - language: minimal
-      dist: xenial
-      os: linux
-      env: BUILD_DESTINATION=snapcraft
-    - language: minimal
-      dist: focal
-      os: linux
-      env: BUILD_DESTINATION=deb
-    - language: python
-      os: linux
-      dist: xenial
-      python: 3.6
-      env: BUILD_DESTINATION=appimage
-
-script:
-- if [ "$TRAVIS_OS_NAME" == "osx" ]; then python3 buildPy2app.py py2app ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "snapcraft" ]; then sudo snapcraft cleanbuild ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "appimage" ]; then travis/appimage-script.sh ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "deb" ]; then travis/deb-script.sh ; fi
-
-install:
-- if [ "$TRAVIS_OS_NAME" == "osx" ]; then travis/macos-install.sh ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "snapcraft" ]; then travis/snapcraft-install.sh ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "appimage" ]; then sudo apt-get install libxkbcommon-x11-0 ; fi
-
-after_success:
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "deb" ]; then travis/deb-installation-test.sh ; fi
-
-before_deploy:
-- ls -al
-- export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
-- python3 bintray_version.py
-- mkdir dist_bintray
-- if [ "$TRAVIS_OS_NAME" == "osx" ]; then travis/macos-deploy.sh ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "snapcraft" ]; then mv syncplay_build_amd64.snap dist_bintray/syncplay_${VER}_amd64.snap ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "appimage" ]; then travis/appimage-deploy.sh ; fi
-- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_DESTINATION" == "deb" ]; then mv /tmp/syncplay.deb dist_bintray/syncplay_${VER}.deb ; fi
-
-deploy:
-  skip_cleanup: true
-  on: master
-  provider: bintray
-  file: "bintray.json"
-  user: alby128
-  key:
-    secure: "I9J3lgHyDoLzuGkjjMuYIk3ZI7Lszn2AG1H6lxIU3SXYaBpbLK+BHXotW0IsSxK5idCK8uszeA2svVipepwtCc9xJYEAlEYLVBgO9BpgTdQid9XjvI1eLDG3+iw0ew+FwEqaYwYbFHfnnQhVzIwBq353kl9ksgDMXi1uREpUk/L3HfVOUV3rDF6mgOPwAUJHBc3d56IVX1yQunM7NwJuswFrBMESauAlzw/C1gWDAuWJ5iJfnFz/4RBDa3C1sZdFmNnkuQEI332HzoMialMGyEP5gE8l0dmXBtFHpE1acgEZ+l1hVz9OsI2/dyICkjYFRLWF2tmxAk4DDF3jTsIRRsxpQo25XGKfvd0FrbN8Zqw8Yb0a5/WPP2E2ERGGLDxqTfkybYPv35utbtHEd4IZTX0Yv/GnmSwFa39+a7RDNhgFJWDR8XUX4Srd9CBron+36KrS+zY2Nn0c36YBxyAocw8qQ/pXmS15sQxSq2pi+GASyhemN546Gz2jbc3W/Ybp85iQ9Py/7Q1wUyYQVvJqEPL0K+/ioDSr4bDWbtqBLpUPlOYOvR4MPGCpqrfjJslpPPKBN8lD0BV2LYZEW6Bip0e8CsrFhecD1atNyWClaPoC0aikH3jpFfQYJOyQ6zghqpHSC+/S3HuGV/P8WCVBpC3TTrk0/TacwZwch3yhK9A="
diff --git a/README.md b/README.md
index 2b299162b..b4b00de3e 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@
 -->
 
 # Syncplay
-[![Travis build Status](https://travis-ci.org/Syncplay/syncplay.svg?branch=master)](https://travis-ci.org/Syncplay/syncplay)
+![GitHub Actions build status](https://github.com/Syncplay/syncplay/workflows/Build/badge.svg)
 [![Appveyor build status](https://ci.appveyor.com/api/projects/status/github/Syncplay/syncplay)](https://ci.appveyor.com/project/Et0h/syncplay/branch/master)
 
 Solution to synchronize video playback across multiple instances of mpv, VLC, MPC-HC, MPC-BE and mplayer2 over the Internet.
diff --git a/bintray.json b/bintray.json
deleted file mode 100644
index fb2f5c5c3..000000000
--- a/bintray.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "package": {
-        "name": "Syncplay",
-        "repo": "Syncplay",
-        "subject": "syncplay"
-    },
-    "version": {
-        "name": "v1.6.0"
-    },
-    "files": [
-        {
-            "includePattern": "dist_bintray/(.*)",
-            "uploadPattern": "$1",
-            "matrixParams": {
-                "override": 1
-            }
-        }
-    ],
-    "publish": true
-}
diff --git a/bintray_version.py b/bintray_version.py
deleted file mode 100644
index dd7ae29c7..000000000
--- a/bintray_version.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python3
-
-import json
-from syncplay import version
-
-bintrayFileName = 'bintray.json'
-
-f = open(bintrayFileName, 'r')
-data = json.load(f)
-
-data['version']['name'] = 'v' + version
-
-g = open(bintrayFileName, 'w')
-json.dump(data, g, indent=4)
diff --git a/travis/appimage-deploy.sh b/ci/appimage-deploy.sh
similarity index 85%
rename from travis/appimage-deploy.sh
rename to ci/appimage-deploy.sh
index 129392209..8016f9c76 100755
--- a/travis/appimage-deploy.sh
+++ b/ci/appimage-deploy.sh
@@ -3,4 +3,4 @@
 wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage
 chmod a+x appimagelint-x86_64.AppImage
 ./appimagelint-x86_64.AppImage Syncplay*.AppImage
-mv Syncplay*.AppImage dist_bintray/
+mv Syncplay*.AppImage dist_actions/
diff --git a/travis/appimage-script.sh b/ci/appimage-script.sh
similarity index 100%
rename from travis/appimage-script.sh
rename to ci/appimage-script.sh
diff --git a/travis/deb-installation-test.sh b/ci/deb-installation-test.sh
similarity index 81%
rename from travis/deb-installation-test.sh
rename to ci/deb-installation-test.sh
index b438b56d4..9ffe8c2be 100755
--- a/travis/deb-installation-test.sh
+++ b/ci/deb-installation-test.sh
@@ -3,6 +3,7 @@
 set -x
 set -e
 
+sudo apt-get -qq update
 sudo apt install /tmp/syncplay.deb -y
 syncplay --no-gui
 sudo apt remove syncplay
diff --git a/travis/deb-script.sh b/ci/deb-script.sh
similarity index 100%
rename from travis/deb-script.sh
rename to ci/deb-script.sh
diff --git a/travis/macos-deploy.sh b/ci/macos-deploy.sh
similarity index 76%
rename from travis/macos-deploy.sh
rename to ci/macos-deploy.sh
index 08c74ba03..8478444eb 100755
--- a/travis/macos-deploy.sh
+++ b/ci/macos-deploy.sh
@@ -2,6 +2,9 @@
 
 set -ex
 
+python3 ci/macos_app_cleaner.py
+cp dist/Syncplay.app/Contents/Resources/qt.conf dist/Syncplay.app/Contents/MacOS/
+
 mkdir dist/Syncplay.app/Contents/Resources/English.lproj
 mkdir dist/Syncplay.app/Contents/Resources/en_AU.lproj
 mkdir dist/Syncplay.app/Contents/Resources/en_GB.lproj
@@ -10,6 +13,8 @@ mkdir dist/Syncplay.app/Contents/Resources/Italian.lproj
 mkdir dist/Syncplay.app/Contents/Resources/ru.lproj
 mkdir dist/Syncplay.app/Contents/Resources/Spanish.lproj
 mkdir dist/Syncplay.app/Contents/Resources/es_419.lproj
+
 pip3 install dmgbuild
 mv syncplay/resources/macOS_readme.pdf syncplay/resources/.macOS_readme.pdf
-dmgbuild -s appdmg.py "Syncplay" dist_bintray/Syncplay_${VER}.dmg
+
+dmgbuild -s appdmg.py "Syncplay" dist_actions/Syncplay_${VER}.dmg
diff --git a/travis/macos-install.sh b/ci/macos-install.sh
similarity index 100%
rename from travis/macos-install.sh
rename to ci/macos-install.sh
diff --git a/ci/macos_app_cleaner.py b/ci/macos_app_cleaner.py
new file mode 100644
index 000000000..4fc9fe37c
--- /dev/null
+++ b/ci/macos_app_cleaner.py
@@ -0,0 +1,20 @@
+import os
+import zipfile
+
+PATH = 'dist/Syncplay.app/Contents/Resources/lib'
+
+zin = zipfile.ZipFile(f'{PATH}/python37.zip', 'r')
+tbd = [path for path in zin.namelist() if 'PySide2/Qt/' in path]
+
+zout = zipfile.ZipFile(f'{PATH}/python37_new.zip', 'w', zipfile.ZIP_DEFLATED)
+
+for item in zin.namelist():
+    buffer = zin.read(item)
+    if item not in tbd:
+        zout.writestr(item, buffer)
+
+zout.close()
+zin.close()
+
+os.remove(f'{PATH}/python37.zip')
+os.rename(f'{PATH}/python37_new.zip', f'{PATH}/python37.zip')
diff --git a/ci/pyside2_linker.py b/ci/pyside2_linker.py
new file mode 100644
index 000000000..4d6f856d4
--- /dev/null
+++ b/ci/pyside2_linker.py
@@ -0,0 +1,24 @@
+import os
+from PySide2.QtCore import QLibraryInfo
+
+def make_symlink(source, target):
+    if os.path.islink(target):
+        os.unlink(target)
+
+    os.symlink(source, target)
+
+QT_LIB_PATH = QLibraryInfo.location(QLibraryInfo.LibrariesPath)
+
+frameworks = [elem for elem in os.listdir(QT_LIB_PATH) if '.framework' in elem]
+
+os.chdir(QT_LIB_PATH)
+
+for fr in frameworks:
+    fr_path = os.path.join(QT_LIB_PATH, fr)
+    fr_name = fr.split('.framework')[0]
+    os.chdir(fr_path)
+    if 'Versions'  in os.listdir('.'):
+        make_symlink(f'Versions/Current/{fr_name}', fr_name)
+        os.chdir(os.path.join(fr_path, 'Versions'))
+        make_symlink('5', 'Current')
+    os.chdir(QT_LIB_PATH)
diff --git a/snapcraft.yaml b/snapcraft.yaml
index 4464b60c8..0088292f6 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -1,7 +1,7 @@
 name: syncplay
 summary: Syncplay
 version: build
-version-script: cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}'
+adopt-info: syncplay
 summary: Client/server to synchronize media playback on many computers
 description: |
   Syncplay synchronises the position and play state of multiple media players
@@ -10,28 +10,55 @@ description: |
   media player then this will be replicated across all media players connected to
   the same server and in the same 'room' (viewing session). When a new person
   joins they will also be synchronised. Syncplay also includes text-based chat so
-  you can discuss a video as you watch it (or you could use third-party Voice over 
+  you can discuss a video as you watch it (or you could use third-party Voice over
   IP software to talk over a video).
 
 confinement: classic
 icon: syncplay/resources/syncplay.png
 grade: stable
-
-parts:
-  syncplay:
-    plugin: python
-    source: .
-    stage-packages:
-      - python3-pyside
-    after: [desktop-qt4]
+base: core18
 
 apps:
   syncplay:
-    command: bin/desktop-launch $SNAP/usr/bin/python3 $SNAP/bin/syncplay
-    desktop: lib/python3.5/site-packages/syncplay/resources/syncplay.desktop
+    command: python3 $SNAP/bin/syncplay
+    desktop: lib/python3.6/site-packages/syncplay/resources/syncplay.desktop
     environment:
-      DISABLE_WAYLAND: 1
+      LIBGL_DRIVERS_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/dri
 
   syncplay-server:
     command: bin/syncplay-server
-    desktop: lib/python3.5/site-packages/syncplay/resources/syncplay-server.desktop
+    desktop: lib/python3.6/site-packages/syncplay/resources/syncplay-server.desktop
+
+parts:
+  syncplay:
+    plugin: python
+    python-version: python3
+    source: .
+    stage-packages:
+      - libnss3
+      - libxcomposite1
+      - libxcursor1
+      - libxtst6
+      - libxrandr2
+      - libglu1-mesa
+      - libgles2-mesa
+      - fontconfig
+      - libxkbcommon0
+      - libxkbcommon-x11-0
+      - libxi6
+      - libegl1
+      - shared-mime-info
+      - libgdk-pixbuf2.0-0
+      - locales-all
+      - libxslt1.1
+      - xfonts-base
+      - xfonts-scalable
+    python-packages:
+      - pyside2
+    override-pull: |
+      snapcraftctl pull
+      snapcraftctl set-version $(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')
+
+layout:
+  /etc/fonts:
+    bind: $SNAP/pyside/etc/fonts
diff --git a/syncplay/ui/consoleUI.py b/syncplay/ui/consoleUI.py
index c9d44738c..1e964941c 100755
--- a/syncplay/ui/consoleUI.py
+++ b/syncplay/ui/consoleUI.py
@@ -197,7 +197,7 @@ def executeCommand(self, data):
             self._syncplayClient.ui.addFileToPlaylist(filename)
         elif command.group('command') in constants.COMMANDS_PLAYLIST:
             playlist = self._syncplayClient.playlist
-            playlist_elements = [f"\t{i+1}: {el}" for i, el in enumerate(playlist._playlist)]
+            playlist_elements = ["\t{}: {}".format(i+1, el) for i, el in enumerate(playlist._playlist)]
 
             if playlist_elements:
                 i = playlist._playlistIndex
diff --git a/travis/snapcraft-install.sh b/travis/snapcraft-install.sh
deleted file mode 100755
index f7c52de2d..000000000
--- a/travis/snapcraft-install.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-
-sudo groupadd --system lxd
-sudo usermod -a -G lxd $USER
-sudo apt-get -qq update
-sudo apt-get -y install snapd
-sudo snap install lxd
-sudo lxd.migrate -yes
-sudo lxd waitready
-sudo lxd init --auto --storage-backend dir
-sudo snap install snapcraft --classic