mirror of
https://github.com/koush/scrypted.git
synced 2026-02-17 04:02:14 +00:00
aiortc logging, detect ffmpeg input source format
This commit is contained in:
@@ -154,7 +154,6 @@ class ArloCamera(ScryptedDeviceBase, Camera, VideoCamera, Intercom, MotionSensor
|
||||
ffmpeg_params = json.loads(await scrypted_sdk.mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput.value))
|
||||
self.logger.debug(f"Received ffmpeg params: {ffmpeg_params}")
|
||||
|
||||
endpoint = ffmpeg_params.get("url")
|
||||
options = {}
|
||||
current_key = None
|
||||
for arg in ffmpeg_params["inputArguments"]:
|
||||
@@ -166,14 +165,9 @@ class ArloCamera(ScryptedDeviceBase, Camera, VideoCamera, Intercom, MotionSensor
|
||||
options[current_key] = ""
|
||||
continue
|
||||
options[current_key] = (options[current_key] + " " + arg).strip()
|
||||
if current_key == "i":
|
||||
endpoint = options[current_key]
|
||||
|
||||
self.logger.debug(f"Parsed ffmpeg params: {options}")
|
||||
|
||||
if endpoint is None:
|
||||
raise Exception("Malformed ffmpeg arguments, input endpoint not provided")
|
||||
|
||||
session_id, ice_servers = self.provider.arlo.StartPushToTalk(self.arlo_basestation, self.arlo_device)
|
||||
self.logger.debug(f"Received ice servers: {[ice['url'] for ice in ice_servers]}")
|
||||
|
||||
@@ -201,7 +195,7 @@ class ArloCamera(ScryptedDeviceBase, Camera, VideoCamera, Intercom, MotionSensor
|
||||
pc = self.pc = BackgroundRTCPeerConnection()
|
||||
self.sdp_answered = False
|
||||
|
||||
pc.add_rtsp_audio(endpoint, options)
|
||||
pc.add_audio(options)
|
||||
|
||||
offer = await pc.createOffer()
|
||||
self.logger.info(f"Arlo offer sdp:\n{offer.sdp}")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
class ScryptedDeviceLoggingWrapper(logging.Handler):
|
||||
@@ -40,4 +41,46 @@ class ScryptedDeviceLoggerMixin:
|
||||
def logger(self):
|
||||
if self._logger is None:
|
||||
self._logger = createScryptedLogger(self, self.logger_name)
|
||||
return self._logger
|
||||
return self._logger
|
||||
|
||||
aiortc_loggers = [
|
||||
"aiortc",
|
||||
"aiortc.rtcdatachannel",
|
||||
"aiortc.rtcdtlstransport",
|
||||
"aiortc.rtcicetransport",
|
||||
"aiortc.rtcpeerconnection",
|
||||
"aiortc.rtcrtpreceiver",
|
||||
"aiortc.rtcrtpsender",
|
||||
"aiortc.rtcrtptransceiver",
|
||||
"aiortc.rtcsctptransport",
|
||||
"aiortc.codecs.h264",
|
||||
"aiortc.contrib.media",
|
||||
"aiortc.contrib.signaling",
|
||||
]
|
||||
|
||||
def init_aiortc_logger(logger_name):
|
||||
# get logger instance used by aiortc
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
# output logger to stdout
|
||||
ch = logging.StreamHandler(sys.stdout)
|
||||
|
||||
# log formatting
|
||||
fmt = logging.Formatter("(arlo) %(levelname)s:%(name)s:%(asctime)s.%(msecs)03d %(message)s", "%H:%M:%S")
|
||||
ch.setFormatter(fmt)
|
||||
|
||||
# configure handler to logger
|
||||
logger.addHandler(ch)
|
||||
|
||||
if logger_name == "aiortc.rtcrtpsender":
|
||||
# rtcrtpsender is extremely noisy for DEBUG, so filter out all
|
||||
# the packet logs
|
||||
logger.addFilter(lambda record: 0 if ") > " in record.getMessage() else 1)
|
||||
|
||||
for log in aiortc_loggers:
|
||||
init_aiortc_logger(log)
|
||||
|
||||
def propagate_aiortc_logging_level(log_level):
|
||||
for log in aiortc_loggers:
|
||||
logging.getLogger(log).setLevel(log_level)
|
||||
@@ -12,7 +12,7 @@ from .arlo.arlo_async import change_stream_class
|
||||
from .arlo.logging import logger as arlo_lib_logger
|
||||
from .camera import ArloCamera
|
||||
from .doorbell import ArloDoorbell
|
||||
from .logging import ScryptedDeviceLoggerMixin
|
||||
from .logging import ScryptedDeviceLoggerMixin, propagate_aiortc_logging_level
|
||||
from .util import BackgroundTaskMixin
|
||||
from .rtcpeerconnection import logger as background_rtc_logger
|
||||
|
||||
@@ -161,6 +161,7 @@ class ArloProvider(ScryptedDeviceBase, Settings, DeviceProvider, DeviceDiscovery
|
||||
device.logger.setLevel(log_level)
|
||||
arlo_lib_logger.setLevel(log_level)
|
||||
background_rtc_logger.setLevel(log_level)
|
||||
propagate_aiortc_logging_level(log_level)
|
||||
|
||||
def propagate_transport(self):
|
||||
self.print(f"Setting plugin transport to {self.arlo_transport}")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from aiortc import RTCPeerConnection
|
||||
from aiortc.contrib.media import MediaPlayer
|
||||
import asyncio
|
||||
import inspect
|
||||
import threading
|
||||
import logging
|
||||
import queue
|
||||
@@ -108,17 +107,35 @@ class BackgroundRTCPeerConnection:
|
||||
async def close(self):
|
||||
await self.__run_background(self.pc.close(), await_result=False, stop_loop=True)
|
||||
|
||||
def add_rtsp_audio(self, endpoint, options):
|
||||
"""Adds an audio track to the RTCPeerConnection given a source RTSP url.
|
||||
def add_audio(self, options):
|
||||
"""Adds an audio track to the RTCPeerConnection given FFmpeg options.
|
||||
|
||||
This constructs a MediaPlayer in the background thread's asyncio loop,
|
||||
since MediaPlayer also utilizes coroutines and asyncio.
|
||||
|
||||
Note that this may block the background thread's event loop if the RTSP
|
||||
Note that this may block the background thread's event loop if the
|
||||
server is not yet ready.
|
||||
"""
|
||||
def add_rtsp_audio_background():
|
||||
media_player = MediaPlayer(endpoint, options=options)
|
||||
try:
|
||||
input = options["i"]
|
||||
format = options.get("f")
|
||||
if format is None and input.startswith("rtsp"):
|
||||
format = "rtsp"
|
||||
except:
|
||||
logger.error("error detecting what input file and format to use")
|
||||
raise
|
||||
|
||||
def add_audio_background():
|
||||
media_player = MediaPlayer(input, format=format, options=options)
|
||||
|
||||
# patch the player's stop function to close RTC if
|
||||
# the media ends before RTC is closed
|
||||
old_stop = media_player._stop
|
||||
def new_stop(*args, **kwargs):
|
||||
old_stop(*args, **kwargs)
|
||||
self.main_loop.call_soon_threadsafe(self.main_loop.create_task, self.close())
|
||||
media_player._stop = new_stop
|
||||
|
||||
self.pc.addTrack(media_player.audio)
|
||||
|
||||
self.background_loop.call_soon_threadsafe(add_rtsp_audio_background)
|
||||
self.background_loop.call_soon_threadsafe(add_audio_background)
|
||||
Reference in New Issue
Block a user