Enhance StreamManager for efficient log parsing and update VLC stream profile naming

This commit is contained in:
SergeantPanda 2025-12-23 15:07:25 -06:00
parent aa5db6c3f4
commit ff7298a93e
3 changed files with 46 additions and 11 deletions

View file

@ -107,6 +107,10 @@ class StreamManager:
# Add this flag for tracking transcoding process status # Add this flag for tracking transcoding process status
self.transcode_process_active = False self.transcode_process_active = False
# Track stream command for efficient log parser routing
self.stream_command = None
self.parser_type = None # Will be set when transcode process starts
# Add tracking for data throughput # Add tracking for data throughput
self.bytes_processed = 0 self.bytes_processed = 0
self.last_bytes_update = time.time() self.last_bytes_update = time.time()
@ -476,6 +480,21 @@ class StreamManager:
# Build and start transcode command # Build and start transcode command
self.transcode_cmd = stream_profile.build_command(self.url, self.user_agent) self.transcode_cmd = stream_profile.build_command(self.url, self.user_agent)
# Store stream command for efficient log parser routing
self.stream_command = stream_profile.command
# Map actual commands to parser types for direct routing
command_to_parser = {
'ffmpeg': 'ffmpeg',
'cvlc': 'vlc',
'vlc': 'vlc',
'streamlink': 'streamlink'
}
self.parser_type = command_to_parser.get(self.stream_command.lower())
if self.parser_type:
logger.debug(f"Using {self.parser_type} parser for log parsing (command: {self.stream_command})")
else:
logger.debug(f"Unknown stream command '{self.stream_command}', will use auto-detection for log parsing")
# For UDP streams, remove any user_agent parameters from the command # For UDP streams, remove any user_agent parameters from the command
if hasattr(self, 'stream_type') and self.stream_type == StreamType.UDP: if hasattr(self, 'stream_type') and self.stream_type == StreamType.UDP:
# Filter out any arguments that contain the user_agent value or related headers # Filter out any arguments that contain the user_agent value or related headers
@ -645,11 +664,27 @@ class StreamManager:
if content_lower.startswith('output #') or 'encoder' in content_lower: if content_lower.startswith('output #') or 'encoder' in content_lower:
self.ffmpeg_input_phase = False self.ffmpeg_input_phase = False
# Try to auto-parse with any available parser # Route to appropriate parser based on known command type
from .services.log_parsers import LogParserFactory from .services.log_parsers import LogParserFactory
from .services.channel_service import ChannelService from .services.channel_service import ChannelService
parse_result = LogParserFactory.auto_parse(content) parse_result = None
# If we know the parser type, use direct routing for efficiency
if self.parser_type:
# Get the appropriate parser and check what it can parse
parser = LogParserFactory._parsers.get(self.parser_type)
if parser:
stream_type = parser.can_parse(content)
if stream_type:
# Parser can handle this line, parse it directly
parsed_data = LogParserFactory.parse(stream_type, content)
if parsed_data:
parse_result = (stream_type, parsed_data)
else:
# Unknown command type - use auto-detection as fallback
parse_result = LogParserFactory.auto_parse(content)
if parse_result: if parse_result:
stream_type, parsed_data = parse_result stream_type, parsed_data = parse_result
# For FFmpeg, only parse during input phase # For FFmpeg, only parse during input phase

View file

@ -23,7 +23,7 @@
"model": "core.streamprofile", "model": "core.streamprofile",
"pk": 1, "pk": 1,
"fields": { "fields": {
"name": "ffmpeg", "name": "FFmpeg",
"command": "ffmpeg", "command": "ffmpeg",
"parameters": "-i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", "parameters": "-i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1",
"is_active": true, "is_active": true,
@ -34,7 +34,7 @@
"model": "core.streamprofile", "model": "core.streamprofile",
"pk": 2, "pk": 2,
"fields": { "fields": {
"name": "streamlink", "name": "Streamlink",
"command": "streamlink", "command": "streamlink",
"parameters": "{streamUrl} best --stdout", "parameters": "{streamUrl} best --stdout",
"is_active": true, "is_active": true,
@ -45,7 +45,7 @@
"model": "core.streamprofile", "model": "core.streamprofile",
"pk": 3, "pk": 3,
"fields": { "fields": {
"name": "vlc", "name": "VLC",
"command": "cvlc", "command": "cvlc",
"parameters": "-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}", "parameters": "-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}",
"is_active": true, "is_active": true,

View file

@ -7,7 +7,7 @@ def add_vlc_profile(apps, schema_editor):
UserAgent = apps.get_model("core", "UserAgent") UserAgent = apps.get_model("core", "UserAgent")
# Check if VLC profile already exists # Check if VLC profile already exists
if not StreamProfile.objects.filter(name="vlc").exists(): if not StreamProfile.objects.filter(name="VLC").exists():
# Get the TiviMate user agent (should be pk=1) # Get the TiviMate user agent (should be pk=1)
try: try:
tivimate_ua = UserAgent.objects.get(pk=1) tivimate_ua = UserAgent.objects.get(pk=1)
@ -19,7 +19,7 @@ def add_vlc_profile(apps, schema_editor):
return return
StreamProfile.objects.create( StreamProfile.objects.create(
name="vlc", name="VLC",
command="cvlc", command="cvlc",
parameters="-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}", parameters="-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}",
is_active=True, is_active=True,
@ -29,7 +29,7 @@ def add_vlc_profile(apps, schema_editor):
def remove_vlc_profile(apps, schema_editor): def remove_vlc_profile(apps, schema_editor):
StreamProfile = apps.get_model("core", "StreamProfile") StreamProfile = apps.get_model("core", "StreamProfile")
StreamProfile.objects.filter(name="vlc").delete() StreamProfile.objects.filter(name="VLC").delete()
class Migration(migrations.Migration): class Migration(migrations.Migration):