Initial commit

This commit is contained in:
Ruslan Bakiev
2026-03-06 09:43:52 +07:00
commit 549fd1da9d
250 changed files with 9114 additions and 0 deletions

134
orin/scripts/rtsp_server.py Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/env python3
"""
RTSP Server для стриминга с CSI камеры на Jetson Orin.
Использует GStreamer RTSP Server.
"""
import os
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GstRtspServer, GLib
# Инициализация GStreamer
Gst.init(None)
# Параметры из environment
WIDTH = os.environ.get('CAMERA_WIDTH', '1920')
HEIGHT = os.environ.get('CAMERA_HEIGHT', '1080')
FPS = os.environ.get('CAMERA_FPS', '30')
RTSP_PORT = os.environ.get('RTSP_PORT', '8554')
def create_pipeline():
"""
Создаёт GStreamer pipeline для CSI камеры.
Пробуем разные источники в порядке приоритета.
"""
# Вариант 1: nvarguscamerasrc (CSI камера на Jetson) с NVIDIA hardware encoder
# Используем nvv4l2h264enc для аппаратного кодирования без EGL
csi_pipeline = (
f'nvarguscamerasrc ! '
f'video/x-raw(memory:NVMM),width={WIDTH},height={HEIGHT},framerate={FPS}/1,format=NV12 ! '
f'nvv4l2h264enc bitrate=4000000 preset-level=1 insert-sps-pps=true ! '
f'h264parse ! '
f'rtph264pay name=pay0 pt=96'
)
# Вариант 2: v4l2src (USB камера) с NVIDIA hardware encoder
v4l2_pipeline = (
f'v4l2src device=/dev/video0 ! '
f'video/x-raw,width={WIDTH},height={HEIGHT},framerate={FPS}/1 ! '
f'nvvidconv ! video/x-raw(memory:NVMM),format=NV12 ! '
f'nvv4l2h264enc bitrate=4000000 preset-level=1 insert-sps-pps=true ! '
f'h264parse ! '
f'rtph264pay name=pay0 pt=96'
)
# Вариант 3: тестовый источник с software encoder (fallback)
test_pipeline = (
f'videotestsrc is-live=true ! '
f'video/x-raw,width={WIDTH},height={HEIGHT},framerate={FPS}/1 ! '
f'videoconvert ! '
f'x264enc tune=zerolatency bitrate=4000 speed-preset=ultrafast ! '
f'rtph264pay name=pay0 pt=96'
)
# Пробуем CSI камеру сначала
try:
test = Gst.parse_launch(csi_pipeline.replace('rtph264pay name=pay0 pt=96', 'fakesink'))
test.set_state(Gst.State.PLAYING)
# Даём время на инициализацию
import time
time.sleep(2)
state = test.get_state(Gst.CLOCK_TIME_NONE)
test.set_state(Gst.State.NULL)
if state[1] == Gst.State.PLAYING:
print("Using CSI camera (nvarguscamerasrc)")
return csi_pipeline
except Exception as e:
print(f"CSI camera not available: {e}")
# Пробуем USB камеру
if os.path.exists('/dev/video0'):
print("Using USB camera (v4l2src)")
return v4l2_pipeline
# Fallback на тестовый источник
print("No camera found, using test source")
return test_pipeline
class RTSPServer:
def __init__(self):
self.server = GstRtspServer.RTSPServer()
self.server.set_service(RTSP_PORT)
# Создаём factory для стрима
factory = GstRtspServer.RTSPMediaFactory()
pipeline = create_pipeline()
print(f"Pipeline: {pipeline}")
factory.set_launch(f'( {pipeline} )')
factory.set_shared(True)
# Добавляем mount point
mount_points = self.server.get_mount_points()
mount_points.add_factory('/stream', factory)
# Запускаем сервер
self.server.attach(None)
print(f"\n{'='*50}")
print(f"RTSP Server started!")
print(f"Stream URL: rtsp://<device-ip>:{RTSP_PORT}/stream")
print(f"{'='*50}\n")
def main():
import signal
import sys
server = RTSPServer()
loop = GLib.MainLoop()
def signal_handler(sig, frame):
print("Shutting down...")
loop.quit()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
print("RTSP server running. Waiting for connections...")
sys.stdout.flush()
try:
loop.run()
except Exception as e:
print(f"Error in main loop: {e}")
sys.exit(1)
if __name__ == '__main__':
main()