refactor(backend): return AudioTranscodeResult with status code and duration

This commit is contained in:
2026-07-14 13:49:28 +02:00
parent 8a637d71f0
commit f6ac22af32
4 changed files with 15 additions and 7 deletions
@@ -0,0 +1,4 @@
namespace Musify.Application.Contracts
{
public record AudioTranscodeResult(int StatusCode, TimeSpan Duration);
}
@@ -2,7 +2,7 @@ namespace Musify.Application.Contracts
{ {
public interface IAudioTranscoderService public interface IAudioTranscoderService
{ {
Task<TimeSpan> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken); Task<AudioTranscodeResult> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken);
Task<bool> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken); Task<bool> IsValidAudioFileAsync(string filePath, CancellationToken cancellationToken);
} }
@@ -38,21 +38,24 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
try try
{ {
TimeSpan duration; AudioTranscodeResult transcodeResult;
await using (var fileStream = File.OpenRead(sourceFilePath)) await using (var fileStream = File.OpenRead(sourceFilePath))
{ {
duration = await audioTranscoder.TranscodeToAudioFileAsync( transcodeResult = await audioTranscoder.TranscodeToAudioFileAsync(
fileStream, fileStream,
workingDirectory, workingDirectory,
executeContext.CancellationToken); executeContext.CancellationToken);
} }
if (transcodeResult.StatusCode != 0)
throw new InvalidOperationException($"ffmpeg transcoding failed with exit code {transcodeResult.StatusCode}.");
File.Delete(sourceFilePath); File.Delete(sourceFilePath);
var log = new TranscodeAudioLog(workingDirectory); var log = new TranscodeAudioLog(workingDirectory);
return executeContext.CompletedWithVariables(log, new Dictionary<string, object> return executeContext.CompletedWithVariables(log, new Dictionary<string, object>
{ {
[RoutingSlipVariableNames.Audio.DurationSeconds] = (int)Math.Round(duration.TotalSeconds) [RoutingSlipVariableNames.Audio.DurationSeconds] = (int)Math.Round(transcodeResult.Duration.TotalSeconds)
} ); } );
} }
catch (Exception exception) catch (Exception exception)
@@ -16,7 +16,7 @@ namespace Musify.Infrastructure.Services
[GeneratedRegex(@"Duration:\s*(\d+):(\d{2}):(\d{2}(?:\.\d+)?)", RegexOptions.IgnoreCase)] [GeneratedRegex(@"Duration:\s*(\d+):(\d{2}):(\d{2}(?:\.\d+)?)", RegexOptions.IgnoreCase)]
private static partial Regex DurationRegex(); private static partial Regex DurationRegex();
public async Task<TimeSpan> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken) public async Task<AudioTranscodeResult> TranscodeToAudioFileAsync(Stream audioStream, string destinationPath, CancellationToken cancellationToken)
{ {
try try
{ {
@@ -35,13 +35,14 @@ namespace Musify.Infrastructure.Services
{ {
logger.LogError("Audio transcoding failed with exit code {ExitCode}. Output: {StandardOutput}, Error: {StandardError}", logger.LogError("Audio transcoding failed with exit code {ExitCode}. Output: {StandardOutput}, Error: {StandardError}",
executionResult.ExitCode, executionResult.StandardOutput, executionResult.StandardError); executionResult.ExitCode, executionResult.StandardOutput, executionResult.StandardError);
throw new InvalidOperationException($"ffmpeg transcoding failed with exit code {executionResult.ExitCode}."); return new AudioTranscodeResult(executionResult.ExitCode, TimeSpan.Zero);
} }
logger.LogInformation("Audio transcoding completed for {DestinationPath}", destinationPath); logger.LogInformation("Audio transcoding completed for {DestinationPath}", destinationPath);
var outputPath = Path.Combine(destinationPath, audioTranscoderConfiguration.Ffmpeg.OutputFileName); var outputPath = Path.Combine(destinationPath, audioTranscoderConfiguration.Ffmpeg.OutputFileName);
return await GetAudioDurationAsync(outputPath, cancellationToken); var duration = await GetAudioDurationAsync(outputPath, cancellationToken);
return new AudioTranscodeResult(executionResult.ExitCode, duration);
} }
catch (TimeoutException timeoutException) catch (TimeoutException timeoutException)
{ {