Metadata-Version: 2.4
Name: rtsp
Version: 2.0.0
Summary: RTSP/RTMP client and server for Python.
Home-page: https://github.com/dactylroot/rtsp
Download-URL: https://github.com/dactylroot/rtsp/archive/2.0.0.tar.gz
Author: Cory Root
License: MIT
Keywords: rtsp rtmp image stream server numpy pillow
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Multimedia :: Video :: Capture
Classifier: Topic :: Multimedia :: Video :: Display
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pillow
Requires-Dist: numpy
Requires-Dist: av
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: download-url
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# RTSP


            /((((((\\\\
    =======((((((((((\\\\\
         ((           \\\\\\\
         ( (*    _/      \\\\\\\
           \    /  \      \\\\\\________________
            |  |   |      </    __             ((\\\\
            o_|   /        ____/ / _______       \ \\\\    \\\\\\\
                 |  ._    / __/ __(_-</ _ \       \ \\\\\\\\\\\\\\\\
                 | /     /_/  \__/___/ .__/       /    \\\\\\\     \\
         .______/\/     /           /_/           /         \\\
        / __.____/    _/         ________(       /\
       / / / ________/`---------'         \     /  \_
      / /  \ \                             \   \ \_  \
     ( <    \ \                             >  /    \ \
      \/      \\_                          / /       > )
               \_|                        / /       / /
                                        _//       _//
                                       /_|       /_|


A Pythonic RTSP client and microserver for video and computer vision work, from rapid prototyping to moderate-weight production. Pull frames from any RTSP stream or local capture device as Pillow images, preview streams in a window, or serve a frame buffer over RTSP with a single context manager. For multi-client distribution, pair it with a [MediaMTX](https://github.com/bluenviron/mediamtx) relay. For performance-intensive pipelines requiring high-throughput encoding or minimal latency, use OpenCV, GStreamer, or FFmpeg directly.

## Features

  * read most-recent RTSP frame as Pillow Image on demand
  * preview stream in a tkinter window. 'q' or ESC to quit.
  * URI shortcuts for rapid prototyping
    * integers (or numeric strings) open a local capture device, e.g. `rtsp.Client(0)`
    * bare host strings default to `rtsp://`, e.g. `rtsp.Client('192.168.1.1/stream')`
    * Raspberry Pi camera: enable the V4L2 driver (`dtoverlay=imx219` or similar in `/boot/config.txt`) and use `rtsp.Client(0)`
  * lightweight RTSP server
  * `rtmp://` and `rtmps://` URIs work with `Client` and `Source` using the same API as RTSP
  * enumerate local capture devices with `rtsp.list_devices()`
 
## Examples

### Client Use

Use RTSP access credentials in your connection string e.g.

    RTSP_URL = f"rtsp://{USERNAME}:{PASSWORD}@192.168.1.221:554/11"

One-off Retrieval

    import rtsp
    client = rtsp.Client(rtsp_server_uri = 'rtsp://...', verbose=True)
    client.read().show()
    client.close()

Stream Preview

    import rtsp
    with rtsp.Client(0) as client: # previews USB webcam 0
        client.preview()

Continuous Retrieval

    import rtsp

    with rtsp.Client(rtsp_server_uri = 'rtsp://...') as client:
        _image = client.read()

        while True:
            process_image(_image)
            _image = client.read(raw=True)

Resize Retrieval Image

    import rtsp

    RTSP_URL = "rtsp://..."
    client = rtsp.Client(rtsp_server_uri = RTSP_URL)

    width = 640
    height = 480

    client.read().resize([width, height]).show()
    client.close()

Rotate Retrieval Image

    import rtsp

    RTSP_URL = "rtsp://..."
    client = rtsp.Client(rtsp_server_uri = RTSP_URL)

    client.read().resize([client.read().size[0], client.read().size[0]]).rotate(90).resize([client.read().size[1], client.read().size[0]]).show()
    client.close()

Save Retrieval Image (With the TimeStamp Format and Set Number of Save Image)

    import rtsp
    import datetime

    RTSP_URL = "rtsp://..."
    IMAGE_COUNT = 10

    client = rtsp.Client(rtsp_server_uri = RTSP_URL)
    while client.isOpened() and IMAGE_COUNT > 0:
        client.read().save("./"+ str(datetime.datetime.now()) +".jpg")
        IMAGE_COUNT = IMAGE_COUNT - 1
    client.close()

### Source Use

Serve frames locally and preview them. `source.client_uri` gives the address
to connect to, and `verbose=True` logs the URI and fps on startup:

    import rtsp

    frames = ['frame1.jpg', 'frame2.jpg', 'frame3.jpg']

    with rtsp.Source('rtsp://0.0.0.0:8554/live', fps=1,
                     frame_buffer=frames, verbose=True) as source:
        with rtsp.Client(source.client_uri) as client:
            client.preview()   # blocks; press q or ESC to quit

Serve without a viewer. `serve_forever()` blocks and loops the buffer
indefinitely until Ctrl-C:

    import rtsp

    frames = ['frame1.jpg', 'frame2.jpg', 'frame3.jpg']

    with rtsp.Source('rtsp://0.0.0.0:8554/live', frame_buffer=frames) as source:
        source.serve_forever()   # blocks; Ctrl-C to stop

Multi-client stream via [MediaMTX](https://github.com/bluenviron/mediamtx) relay.
Also, frames can be added incrementally with `put()`:

    # Terminal: ./mediamtx          (listens on :8554 by default)

    import rtsp

    # serve=False pushes to the running MediaMTX relay.
    # Any number of Client() instances can then read from the same URI.
    with rtsp.Source('rtsp://localhost:8554/live', serve=False) as source:
        for frame in incoming_frames():
            source.put(frame)

    # Elsewhere, any number of concurrent readers:
    with rtsp.Client('rtsp://localhost:8554/live') as client:
        client.preview()

