Skip to content

Commit

Permalink
Merge pull request #13 from erdnaxe/galene-0.6-support
Browse files Browse the repository at this point in the history
Galene 0.6 support and cleanup
  • Loading branch information
erdnaxe authored Oct 8, 2022
2 parents a7f18d4 + 2bef3bf commit 2f664b1
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 279 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,22 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9]
python-version: ["3.8", "3.9", "3.10"]

steps:
- uses: actions/checkout@v2
- name: Install APT dependencies
run: |
sudo apt-get install -y gir1.2-gst-plugins-bad-1.0 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-nice gobject-introspection libgirepository1.0-dev
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- uses: actions/checkout@v3
- name: Lint
run: tox -e linters
- name: Test
run: tox -e tests
51 changes: 0 additions & 51 deletions .gitlab-ci.yml

This file was deleted.

12 changes: 0 additions & 12 deletions CONTRIBUTING.md

This file was deleted.

4 changes: 2 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Include documentation
recursive-include docs *.png *.conf Vagrantfile*

# Include metadata files
include .gitlab-ci.yml CONTRIBUTING.md
# Include entrypoint
include galene-stream.py
83 changes: 23 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,47 @@ Gateway to send streams such as RTMP or SRT to
[Galène videoconference server](https://galene.org/).
It is based on Gstreamer and implements the Galène protocol.

Tested on Debian Bullseye, Ubuntu 20.04, Ubuntu 20.10, ArchLinux and NixOS 20.09.

**This project is still not production ready, and you might experience
jittering and crashes.**

![Streaming from OBS to Galène, video background from KaMy Video Stock](./docs/demo.png)

## User guide
## Installation

Real-time video conversion requires resources. If many users are going to use
this gateway simultaneously, you should scale your machine resources
accordingly.

### Installation on Debian/Ubuntu

```bash
sudo apt install python3-pip python3-gi python3-gi-cairo python3-websockets gir1.2-gst-plugins-bad-1.0 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-nice
pip3 install --user galene-stream
```

### Installation on ArchLinux

```bash
sudo pacman -S python-setuptools python-pip python-websockets python-gobject gobject-introspection gst-python gst-plugins-base gst-plugins-bad gst-plugins-ugly gst-libav
pip install --user galene-stream
```
Installation works on Ubuntu 20.10 and Debian Bullseye or any later version.

### Installation from source code using Python Virtualenv
For Windows users, we recommend to use
[Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install).

Start by cloning the source code,
### Dependencies

```bash
git clone https://github.com/erdnaxe/galene-stream
cd galene-stream
```
# On Debian/Ubuntu-based distributions
sudo apt install python3-gi python3-gi-cairo python3-websockets gir1.2-gst-plugins-bad-1.0 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-nice

Then create a Python VirtualEnv and install galene-stream inside,
# On ArchLinux-based distributions
sudo pacman -S python-setuptools python-pip python-websockets python-gobject gobject-introspection gst-python gst-plugins-base gst-plugins-bad gst-plugins-ugly gst-libav

```bash
python -m venv venv --system-site-packages
source venv/bin/activate
pip install -e .
# On NixOS
nix-shell -p gobject-introspection -p gst_all_1.gst-libav -p gst_all_1.gst-plugins-bad -p gst_all_1.gst-plugins-base -p gst_all_1.gst-plugins-good -p gst_all_1.gst-plugins-ugly -p libnice -p python3 -p python3Packages.gst-python -p python3Packages.pygobject3 -p python3Packages.websockets
```

### Installation on Windows

*Running the gateway on Windows is not tested and not recommended.*

Go to <http://www.msys2.org/> and follow the instructions to set up a MSYS2
environment. Then run `C:\msys64\mingw64.exe`, you should have a terminal
window. Then execute,

```bash
# Update MSYS2
pacman -Suy

# Install Python3 and GStreamer
pacman -S mingw-w64-x86_64-python mingw-w64-x86_64-gcc mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-gobject mingw-w64-x86_64-gst-python mingw-w64-x86_64-gst-plugins-base mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad mingw-w64-x86_64-gst-plugins-ugly mingw-w64-x86_64-gst-libav
pip install galene-stream

python -m galene_stream --help
```
Then you should be able to either run `./galene-stream.py` in this repository,
or install it using pip.

### Configuration for UDP streaming

Launch the gateway using:

```
galene-stream --input "udp://localhost:8888" --output "wss://galene.example.com/ws" --group test --username bot
galene-stream --input "udp://127.0.0.1:8888" --output "wss://galene.example.com/ws" --group test --username bot
```

Then you can stream to `udp://localhost:8888` with no stream key.
Then you can stream to `udp://127.0.0.1:8888` with no stream key.

### Configuration for RTMP streaming

Expand All @@ -96,7 +65,7 @@ nginx -c nginx.conf -p $PWD
You may launch the gateway after the NGINX server using:

```
galene-stream --input "rtmp://localhost:1935/live/test" --output "wss://galene.example.com/ws" --group test --username bot
galene-stream --input "rtmp://127.0.0.1:1935/live/test" --output "wss://galene.example.com/ws" --group test --username bot
```

Then you can stream to `rtmp://127.0.0.1:1935/live` with stream key `test`.
Expand All @@ -113,10 +82,10 @@ On Windows and MacOS, OBS comes with his own FFMpeg that will work.
Launch the gateway using:

```
galene-stream --input "srt://localhost:9710?mode=listener" --output "wss://galene.example.com/ws" --group test --username bot
galene-stream --input "srt://127.0.0.1:9710?mode=listener" --output "wss://galene.example.com/ws" --group test --username bot
```

Then you can stream to `srt://localhost:9710` with no stream key.
Then you can stream to `srt://127.0.0.1:9710` with no stream key.

More information on [OBS Wiki, Streaming With SRT Or RIST Protocols](https://obsproject.com/wiki/Streaming-With-SRT-Or-RIST-Protocols).

Expand All @@ -130,7 +99,8 @@ galene-stream --input "file://source.webm" --output "wss://galene.example.com/ws

## Contributing

See [contributing guidelines](./CONTRIBUTING.md).
We welcome contributions that stays in the scope of this project.
Please format your code using `black` and test it using `pytest`.

### Collecting statistics about GStreamer WebRTC element

Expand Down Expand Up @@ -159,18 +129,11 @@ For example, `export GST_DEBUG_DUMP_DOT_DIR=.`.
Then you can use GraphViz to generate an image from the dot file:
`dot -Tpng pipeline.dot > pipeline.png`.

## Authors
## License

This gateway is currently developed by members from
[Crans](https://www.crans.org/)
This gateway is developed by former members of [Crans](https://www.crans.org/)
and [Aurore](https://auro.re/) network organizations to build a self-hosted
free and open-source streaming server.

Main contributors:

- Alexandre Iooss

## License
free and open-source streaming server based on [Galène](https://galene.org/).

We believe in open source software.
This project is licensed under [MIT](./LICENSE.txt).
12 changes: 12 additions & 0 deletions galene-stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python3
# Copyright (C) 2022 Alexandre Iooss
# SPDX-License-Identifier: MIT

"""
Entrypoint for Python module
"""

from galene_stream.cli import main

if __name__ == "__main__":
main()
100 changes: 3 additions & 97 deletions galene_stream/__main__.py
Original file line number Diff line number Diff line change
@@ -1,105 +1,11 @@
# Copyright (C) 2021 Alexandre Iooss
# Copyright (C) 2021-2022 Alexandre Iooss
# SPDX-License-Identifier: MIT

"""
Main script for Galène stream gateway.
Entrypoint for Python module
"""

import argparse
import asyncio
import logging
import sys

from galene_stream.galene import GaleneClient


def start(opt: argparse.Namespace):
"""Init Galène client and start gateway
:param opt: program options
:type opt: argparse.Namespace
"""
client = GaleneClient(
opt.input, opt.output, opt.bitrate, opt.group, opt.username, opt.password
)

# Connect and run main even loop
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(client.connect())
try:
event_loop.run_until_complete(client.loop(event_loop))
event_loop.run_until_complete(client.close())
except KeyboardInterrupt:
event_loop.run_until_complete(client.close())
sys.exit(1)


def main():
"""Entrypoint."""
# Arguments parser
parser = argparse.ArgumentParser(
prog="galene-stream",
description="Galène stream gateway.",
)
parser.add_argument(
"--debug",
action="store_true",
default=False,
help="debug mode: show debug messages",
)
parser.add_argument(
"-i",
"--input",
required=True,
help=(
'URI to use as GStreamer "uridecodebin" module input, '
'e.g. "rtmp://localhost:1935/live/test"'
),
)
parser.add_argument(
"-o",
"--output",
required=True,
help='Galène server to connect to, e.g. "wss://galene.example.com/ws"',
)
parser.add_argument(
"-b",
"--bitrate",
default=1048576,
help="VP8 encoder bitrate in bit/s, you should adapt this to your network, default to 1048576",
)
parser.add_argument(
"-g",
"--group",
required=True,
help="Join this group",
)
parser.add_argument(
"-u",
"--username",
required=True,
help="Group username",
)
parser.add_argument(
"-p",
"--password",
help="Group password",
)
options = parser.parse_args()

# Configure logging
level = logging.DEBUG if options.debug else logging.INFO
logging.addLevelName(logging.INFO, "\033[1;36mINFO\033[1;0m")
logging.addLevelName(logging.WARNING, "\033[1;33mWARNING\033[1;0m")
logging.addLevelName(logging.ERROR, "\033[1;91mERROR\033[1;0m")
logging.addLevelName(logging.DEBUG, "\033[1;30mDEBUG")
logging.basicConfig(
level=level,
format="\033[90m%(asctime)s\033[1;0m [%(name)s] %(levelname)s %(message)s\033[1;0m",
)

start(options)

from .cli import main

if __name__ == "__main__":
main()
Loading

0 comments on commit 2f664b1

Please sign in to comment.