ErwanDL / hls-relay

HLS (HTTP Live Streaming) relay server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HLS Relay Server

This project is a Python server capable of intercepting, logging and forwarding requests made to an HLS stream through a media player (ex: VLC).

Installation

This project was developed and tested with Python >= 3.8

  • Create a virtual environment for this project :

    $ python -m venv <venv-name>
    
  • Activate your virtual environment, and install the required dependencies :

    $ pip install -r requirements.txt
    

The project uses black as a formatter, and flake8 as a linter.

Running tests

This project is tested with the unittest framework, included in the standard library.

You can run the tests by navigating to the project root and running :

$ python -m unittest -v

Be aware that the integration tests (under test/integration/) require an internet connection to function properly.

Running the server

You can run the server by navigating to the project root and running :

$ python -m hlsrelay <base-url>

For example:

$ python -m hlsrelay https://bitdash-a.akamaihd.net

You can then start VLC, click on "File > Open Network...", and then request http://localhost:8080/\<stream-file-uri>. For example, entering http://localhost:8080/content/sintel/hls/playlist.m3u8 will request the m3u8 file at https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8.

Project structure

The source code is located under hlsrelay/ :

  • __main__.py is the entry point of the app, it parses command line args and boots up the server.
  • server.py defines a create_app function for initializing an aiohttp server, given a base URL to the stream to intercept, and an optional output stream.
  • interceptor.py contains the main logic of the interceptor : logging and forwarding requests, detecting track switches and handling both relative and absolute URLs in m3u8 manifests.
  • request.py is a simple wrapper to perform HTTP requests while reusing the same persistent aiohttp.ClientSession.
  • config.py contains basic server configuration variables.

The test code is located under test/ :

  • Unit tests for the interceptor are located in test/unit/.
  • Integration tests, running a full-fledged server, are located in test/integration/. As these tests perform real HTTP requests to actual stream URLs, you need to have an internet connection to run them.

Additional comments on the methodology

  • To detect track switches (bitrate changes in the case of an adaptive bitrate stream), we chose to save the current master playlist (we use the Python m3u8 library to parse playlist files and detect adaptive bitrates) as an attribute of the StreamInterceptor. Then, if another playlist file is requested, and it was listed as a sub-playlist of the current master playlist, we log a track switch.
  • To be able to handle both absolute and relative URLs, we simply look for absolute URLs in playlist files (lines starting with http:// or https://), and replace the base URL with that of our server (http://localhost:8080).

About

HLS (HTTP Live Streaming) relay server


Languages

Language:Python 100.0%