Feat: attach codec used in the input file to the streamdetails (#1921)
authorMaxim Raznatovski <nda.mr43@gmail.com>
Thu, 30 Jan 2025 13:51:07 +0000 (14:51 +0100)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2025 13:51:07 +0000 (14:51 +0100)
feat: attach codec used in the input file to the streamdetails

music_assistant/controllers/player_queues.py
music_assistant/helpers/audio.py
music_assistant/helpers/ffmpeg.py

index 04c46e2487272843d4e280c6daaae10619146fc5..045d106f5098b10ff30ce1a6a5fd09bf2672af69 100644 (file)
@@ -23,6 +23,7 @@ from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption
 from music_assistant_models.enums import (
     CacheCategory,
     ConfigEntryType,
+    ContentType,
     EventType,
     MediaType,
     PlayerState,
@@ -108,6 +109,7 @@ class CompareState(TypedDict):
     elapsed_time: int
     stream_title: str | None
     content_type: str | None
+    codec_type: ContentType | None
     output_formats: list[str] | None
 
 
@@ -992,6 +994,9 @@ class PlayerQueuesController(CoreController):
             content_type=queue.current_item.streamdetails.audio_format.output_format_str
             if queue.current_item and queue.current_item.streamdetails
             else None,
+            codec_type=queue.current_item.streamdetails.audio_format.codec_type
+            if queue.current_item and queue.current_item.streamdetails
+            else None,
             output_formats=output_formats,
         )
         changed_keys = get_changed_keys(prev_state, new_state)
index 662cafa0aa2fb084459045544fd85b7042dd4df4..9786d2aeea1d3d7ecef04a2a0239d2af223fe333 100644 (file)
@@ -410,6 +410,11 @@ async def get_media_stream(
                 bytes_sent += len(chunk)
                 continue
 
+            if chunk_number == 0:
+                # At this point ffmpeg has started and should now know the codec used
+                # for encoding the audio.
+                streamdetails.audio_format.codec_type = ffmpeg_proc.input_format.codec_type
+
             chunk_number += 1
             # determine buffer size dynamically
             if chunk_number < 5 and strip_silence_begin:
index 6402f530870804bc9aa3dd49c14e2eb390c249f1..f7164dfff6cc7b4f4dc9d3144274c1429b4feccb 100644 (file)
@@ -59,6 +59,7 @@ class FFMpeg(AsyncProcess):
         self.log_history: deque[str] = deque(maxlen=100)
         self._stdin_task: asyncio.Task | None = None
         self._logger_task: asyncio.Task | None = None
+        self._input_codec_parsed = False
         super().__init__(
             ffmpeg_args,
             stdin=True if isinstance(audio_input, str | AsyncGenerator) else audio_input,
@@ -117,15 +118,19 @@ class FFMpeg(AsyncProcess):
 
             # if streamdetails contenttype is unknown, try parse it from the ffmpeg log
             if line.startswith("Stream #") and ": Audio: " in line:
-                if self.input_format.content_type == ContentType.UNKNOWN:
+                if not self._input_codec_parsed:
                     content_type_raw = line.split(": Audio: ")[1].split(" ")[0]
+                    content_type_raw = content_type_raw.split(",")[0]
                     content_type = ContentType.try_parse(content_type_raw)
                     self.logger.debug(
                         "Detected (input) content type: %s (%s)",
                         content_type,
                         content_type_raw,
                     )
-                    self.input_format.content_type = content_type
+                    if self.input_format.content_type == ContentType.UNKNOWN:
+                        self.input_format.content_type = content_type
+                    self.input_format.codec_type = content_type
+                    self._input_codec_parsed = True
             del line
 
     async def _feed_stdin(self) -> None: