Skip to content

Instantly share code, notes, and snippets.

@wtip
Last active August 16, 2021 16:32
Show Gist options
  • Save wtip/3057c777d2887919af2f1d3872c21405 to your computer and use it in GitHub Desktop.
Save wtip/3057c777d2887919af2f1d3872c21405 to your computer and use it in GitHub Desktop.
picamera, gstreamer and rtsp-simple-server scripts and config
from picamera import PiCamera
import shlex, subprocess, os
camera = PiCamera()
# max resolution is (3280, 2464) for full FoV at 15FPS
camera.resolution = (1640, 1232)
# zoom (x, y, w, h) proportion of the image to include in the output
# use the following to crop 4:3 full FoV res when using 16:9 resize res to achieve full width sensor FoV
#camera.zoom = (0.0, 0.1, 1.0, 0.75)
camera.framerate = 30
#camera.rotation = 180
# High Quality Stream
HQcmd = "gst-launch-1.0 fdsrc ! h264parse ! rtspclientsink location=rtsp://myuser:mypass@localhost:8554/hqstream debug=false"
HQcmd = shlex.split(HQcmd)
gstreamerHQ = subprocess.Popen(HQcmd, stdin=subprocess.PIPE)
# Low Quality Stream
LQcmd = "gst-launch-1.0 fdsrc ! h264parse ! rtspclientsink location=rtsp://myuser:mypass@localhost:8554/lqstream debug=false"
LQcmd = shlex.split(LQcmd)
gstreamerLQ = subprocess.Popen(LQcmd, stdin=subprocess.PIPE)
try:
camera.start_recording(gstreamerHQ.stdin, splitter_port=1, format='h264', profile='high', intra_period=30, quality=30, sei=True, sps_timing=True)
camera.start_recording(gstreamerLQ.stdin, splitter_port=2, format='h264', profile='high', intra_period=30, quality=30, sei=True, sps_timing=True, resize=(640, 480))
while True:
camera.wait_recording(timeout=1, splitter_port=1)
camera.wait_recording(timeout=1, splitter_port=2)
camera.capture('/dev/shm/camera-tmp.jpg', use_video_port=True, resize=(800, 600))
os.rename('/dev/shm/camera-tmp.jpg', '/dev/shm/camera.jpg') # make image replacement atomic operation
except KeyboardInterrupt:
camera.stop_recording(splitter_port=1)
camera.stop_recording(splitter_port=2)
gstreamerHQ.stdin.close()
gstreamerLQ.stdin.close()
gstreamerHQ.wait()
gstreamerLQ.wait()
###############################################
# General parameters
# sets the verbosity of the program; available values are "warn", "info", "debug".
logLevel: info
# destinations of log messages; available values are "stdout", "file" and "syslog".
logDestinations: [stdout]
# if "file" is in logDestinations, this is the file which will receive the logs.
logFile: rtsp-simple-server.log
# timeout of read operations.
readTimeout: 10s
# timeout of write operations.
writeTimeout: 10s
# number of read buffers.
# a higher number allows a higher throughput,
# a lower number allows to save RAM.
readBufferCount: 512
# enable Prometheus-compatible metrics.
metrics: no
# address of the metrics listener.
metricsAddress: :9998
# enable pprof-compatible endpoint to monitor performances.
pprof: no
# address of the pprof listener.
pprofAddress: :9999
# command to run when a client connects to the server.
# this is terminated with SIGINT when a client disconnects from the server.
# the server port is available in the RTSP_PORT variable.
runOnConnect:
# the restart parameter allows to restart the command if it exits suddenly.
runOnConnectRestart: no
###############################################
# RTSP parameters
# disable support for the RTSP protocol.
rtspDisable: no
# supported RTSP stream protocols.
# UDP is the most performant, but can cause problems if there's a NAT between
# server and clients, and doesn't support encryption.
# UDP-multicast allows to save bandwidth when clients are all in the same LAN.
# TCP is the most versatile, and does support encryption.
# The handshake is always performed with TCP.
protocols: [udp, multicast, tcp]
# encrypt handshake and TCP streams with TLS (RTSPS).
# available values are "no", "strict", "optional".
encryption: no
# address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
rtspAddress: :8554
# address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional".
rtspsAddress: :8555
# address of the UDP/RTP listener. This is needed only when "udp" is in protocols.
rtpAddress: :8000
# address of the UDP/RTCP listener. This is needed only when "udp" is in protocols.
rtcpAddress: :8001
# IP range of all UDP-multicast listeners. This is needed only when "multicast" is in protocols.
multicastIPRange: 224.1.0.0/16
# port of all UDP-multicast/RTP listeners. This is needed only when "multicast" is in protocols.
multicastRTPPort: 8002
# port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in protocols.
multicastRTCPPort: 8003
# path to the server key. This is needed only when encryption is "strict" or "optional".
# this can be generated with:
# openssl genrsa -out server.key 2048
# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
serverKey: server.key
# path to the server certificate. This is needed only when encryption is "strict" or "optional".
serverCert: server.crt
# authentication methods.
authMethods: [basic, digest]
# read buffer size.
# this doesn't influence throughput and shouldn't be touched unless the server
# reports errors about the buffer size.
readBufferSize: 2048
###############################################
# RTMP parameters
# disable support for the RTMP protocol.
rtmpDisable: yes
# address of the RTMP listener.
rtmpAddress: :1935
###############################################
# HLS parameters
# disable support for the HLS protocol.
hlsDisable: yes
# address of the HLS listener.
hlsAddress: :8888
# number of HLS segments to generate.
# increasing segments allows more buffering,
# decreasing segments decrease latency.
hlsSegmentCount: 3
# minimum duration of each segment.
# the real segment duration is also influenced by the interval between IDR frames,
# since the server changes the segment duration to include at least one IDR frame in each.
hlsSegmentDuration: 1s
# value of the Access-Control-Allow-Origin header provided in every HTTP response.
# This allows to play the HLS stream from an external website.
hlsAllowOrigin: '*'
###############################################
# Path parameters
# these settings are path-dependent.
# it's possible to use regular expressions by using a tilde as prefix.
# for example, "~^(test1|test2)$" will match both "test1" and "test2".
# for example, "~^prefix" will match all paths that start with "prefix".
# the settings under the path "all" are applied to all paths that do not match
# another entry.
paths:
all:
publishUser: myuser
publishPass: mypass
hqstream:
runOnInit: python3 /root/picam_stream.py
runOnInitRestart: yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment