aiortc logging, detect ffmpeg input source format

This commit is contained in:
Brett Jia
2023-01-11 22:12:30 -05:00
parent 6f8ffde343
commit b09dd2fcdc
4 changed files with 71 additions and 16 deletions

View File

@@ -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}")

View File

@@ -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)

View File

@@ -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}")

View File

@@ -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)