Always cleanup smart fades tmp files (#3143)
authorMarvin Schenkel <marvinschenkel@gmail.com>
Fri, 13 Feb 2026 12:04:47 +0000 (13:04 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Feb 2026 12:04:47 +0000 (13:04 +0100)
* Always cleanup smart fades tmp files

* Cleanup

music_assistant/controllers/streams/smart_fades/fades.py

index 7c9715622e6b9bf51f56b7be297f2c0b4947cb31..88dc11111a6787844c5664fed510d665bf8e50bc 100644 (file)
@@ -75,6 +75,7 @@ class SmartFade(ABC):
         fadeout_filename = f"/tmp/{shortuuid.random(20)}.pcm"  # noqa: S108
         async with aiofiles.open(fadeout_filename, "wb") as outfile:
             await outfile.write(fade_out_part)
+
         args = [
             "ffmpeg",
             "-hide_banner",
@@ -132,14 +133,17 @@ class SmartFade(ABC):
         )
         self.logger.log(VERBOSE_LOG_LEVEL, "FFmpeg command args: %s", " ".join(args))
 
-        # Execute the enhanced smart fade with full buffer
-        _, raw_crossfade_output, stderr = await communicate(args, fade_in_part)
-        await remove_file(fadeout_filename)
-
-        if raw_crossfade_output:
-            return raw_crossfade_output
-        stderr_msg = stderr.decode() if stderr else "(no stderr output)"
-        raise RuntimeError(f"Smart crossfade failed. FFmpeg stderr: {stderr_msg}")
+        try:
+            # Execute the enhanced smart fade with full buffer
+            _, raw_crossfade_output, stderr = await communicate(args, fade_in_part)
+
+            if raw_crossfade_output:
+                return raw_crossfade_output
+            stderr_msg = stderr.decode() if stderr else "(no stderr output)"
+            raise RuntimeError(f"Smart crossfade failed. FFmpeg stderr: {stderr_msg}")
+        finally:
+            # Always cleanup temp file, even if ffmpeg fails
+            await remove_file(fadeout_filename)
 
     def __repr__(self) -> str:
         """Return string representation of SmartFade showing the filter chain."""