diff --git a/apps/proxy/ts_proxy/stream_manager.py b/apps/proxy/ts_proxy/stream_manager.py index da840f2d..cbaa0bc0 100644 --- a/apps/proxy/ts_proxy/stream_manager.py +++ b/apps/proxy/ts_proxy/stream_manager.py @@ -107,6 +107,10 @@ class StreamManager: # Add this flag for tracking transcoding process status 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 self.bytes_processed = 0 self.last_bytes_update = time.time() @@ -476,6 +480,21 @@ class StreamManager: # Build and start transcode command 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 if hasattr(self, 'stream_type') and self.stream_type == StreamType.UDP: # 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: 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.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: stream_type, parsed_data = parse_result # For FFmpeg, only parse during input phase diff --git a/core/fixtures/initial_data.json b/core/fixtures/initial_data.json index 49ecf080..889f0d24 100644 --- a/core/fixtures/initial_data.json +++ b/core/fixtures/initial_data.json @@ -23,7 +23,7 @@ "model": "core.streamprofile", "pk": 1, "fields": { - "name": "ffmpeg", + "name": "FFmpeg", "command": "ffmpeg", "parameters": "-i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", "is_active": true, @@ -34,7 +34,7 @@ "model": "core.streamprofile", "pk": 2, "fields": { - "name": "streamlink", + "name": "Streamlink", "command": "streamlink", "parameters": "{streamUrl} best --stdout", "is_active": true, @@ -45,7 +45,7 @@ "model": "core.streamprofile", "pk": 3, "fields": { - "name": "vlc", + "name": "VLC", "command": "cvlc", "parameters": "-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}", "is_active": true, diff --git a/core/migrations/0019_add_vlc_stream_profile.py b/core/migrations/0019_add_vlc_stream_profile.py index 5d794647..c3f72592 100644 --- a/core/migrations/0019_add_vlc_stream_profile.py +++ b/core/migrations/0019_add_vlc_stream_profile.py @@ -5,9 +5,9 @@ from django.db import migrations def add_vlc_profile(apps, schema_editor): StreamProfile = apps.get_model("core", "StreamProfile") UserAgent = apps.get_model("core", "UserAgent") - + # 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) try: tivimate_ua = UserAgent.objects.get(pk=1) @@ -17,9 +17,9 @@ def add_vlc_profile(apps, schema_editor): if not tivimate_ua: # No user agents exist, skip creating profile return - + StreamProfile.objects.create( - name="vlc", + name="VLC", command="cvlc", parameters="-vv -I dummy --no-video-title-show --http-user-agent {userAgent} {streamUrl} --sout #standard{access=file,mux=ts,dst=-}", is_active=True, @@ -29,7 +29,7 @@ def add_vlc_profile(apps, schema_editor): def remove_vlc_profile(apps, schema_editor): StreamProfile = apps.get_model("core", "StreamProfile") - StreamProfile.objects.filter(name="vlc").delete() + StreamProfile.objects.filter(name="VLC").delete() class Migration(migrations.Migration):