Skip to content

Latest commit

 

History

History
235 lines (163 loc) · 6.43 KB

File metadata and controls

235 lines (163 loc) · 6.43 KB

Python Janus Client

Janus WebRTC Server Python async client.

PyPI - License PyPI - Status PyPI - Downloads Code Coverage


Install

pip install janus-client

Requires Python >=3.8 <3.14


Description

Easily send and share WebRTC media through Janus WebRTC server.

This client is using aiortc for WebRTC communication and subsequently PyAV for media stack.

✅ Features ✅

  • Connect to Janus server using:
    • Websocket
    • HTTP
  • Authentication with shared static secret (API key) and/or stored token
  • Support Admin/Monitor API:
    • Generic requests
    • Configuration related requests
    • Token related requests
  • Support Janus plugins:
  • Simple interface
  • Minimum dependency
  • Extendable Janus transport

Examples

Simple Connect And Disconnect

import asyncio
from janus_client import JanusSession, JanusEchoTestPlugin, JanusVideoRoomPlugin

# Protocol will be derived from base_url
base_url = "wss://janusmy.josephgetmyip.com/janusbasews/janus"
# OR
base_url = "https://janusmy.josephgetmyip.com/janusbase/janus"

session = JanusSession(base_url=base_url)

plugin_handle = JanusEchoTestPlugin()

# Attach to Janus session
await plugin_handle.attach(session=session)

# Destroy plugin handle
await plugin_handle.destroy()

This will create a plugin handle and then destroy it.

Notice that we don't need to call connect or disconnect explicitly. It's managed internally.

Make Video Calls

import asyncio
from janus_client import JanusSession, JanusVideoCallPlugin
from aiortc.contrib.media import MediaPlayer, MediaRecorder
from aiortc import RTCConfiguration, RTCIceServer

async def main():
    # Create session
    session = JanusSession(
        base_url="wss://janusmy.josephgetmyip.com/janusbasews/janus",
    )

    # Create plugin (optionally with WebRTC configuration)
    config = RTCConfiguration(iceServers=[
        RTCIceServer(urls='stun:stun.l.google.com:19302')
    ])
    plugin_handle = JanusVideoCallPlugin(pc_config=config)

    # Attach to Janus session
    await plugin_handle.attach(session=session)

    # Prepare username and media stream
    username = "testusernamein"
    username_out = "testusernameout"

    player = MediaPlayer(
        "desktop",
        format="gdigrab",
        options={
            "video_size": "640x480",
            "framerate": "30",
            "offset_x": "20",
            "offset_y": "30",
        },
    )
    recorder = MediaRecorder("./videocall_record_out.mp4")

    # Register myself as testusernameout
    result = await plugin_handle.register(username=username_out)

    # Call testusernamein
    result = await plugin_handle.call(
        username=username, player=player, recorder=recorder
    )

    # Wait awhile then hangup
    await asyncio.sleep(30)

    result = await plugin_handle.hangup()

    # Destroy plugin
    await plugin_handle.destroy()

    # Destroy session
    await session.destroy()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

This example will register to the VideoCall plugin using username testusernameout. It will then call the user registered using the username testusernamein.

A portion of the screen will be captured and sent in the call media stream. The incoming media stream will be saved into videocall_record_out.mp4 file.

Documentation

Link here: https://josephlim94.github.io/python_janus_client/

Dev

Documentation Development

The project documentation is built with Material for MkDocs and deployed to GitHub Pages.

Setup

# Install development dependencies
hatch env create

# To serve the documentation locally with live reload
# Should be available at http://127.0.0.1:8000/
hatch run docs-serve

Building Documentation

To build the documentation for production:

hatch run docs-build

The built documentation will be in the site/ directory.

Important: The documentation build uses the --strict flag to catch warnings as errors. This ensures documentation quality and prevents deployment of documentation with issues.

For local development without strict mode:

hatch run mkdocs build
hatch run +py=3.8 mkdocs build  # to build in a specific python environment only, not all

Run unit tests

Use video url from https://gist.github.com/jsturgis/3b19447b304616f18657

Use following command to run unit tests and see all logs:

hatch test  # Run all tests on all environments
hatch test -- -s --log-cli-level=INFO --full-trace -- tests  # Run all tests with all logs on a default environment
hatch test .\tests\test_plugin.py::TestTransportHttp::test_plugin_echotest_create -- -s --log-cli-level=INFO --full-trace  # Run a specific test with all logs on a default environment
hatch test -i py=3.8 .\tests\test_plugin.py::TestTransportHttp::test_plugin_echotest_create -- -s --log-cli-level=INFO --full-trace  # Run a specific test with all logs on a specific environment

Generate code coverage:

# Not running it through all python environments because the webrtc connection might fail to setup.
# That is a server configuration issue which naturally comes with integration tests like these.
hatch test -i py=3.8 -c
hatch env run -e py3.8 coverage html

Build and publish

hatch -e py3.8 build --clean
hatch publish

Experiments

FFmpeg support for VideoRoom plugin has now been moved to experiments folder, together with GStreamer support.