57 lines
1.9 KiB
C#
57 lines
1.9 KiB
C#
using System.Globalization;
|
|
using System.Text.Json;
|
|
using Microsoft.Extensions.Options;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
|
|
namespace TeleWave.Infrastructure.Media;
|
|
|
|
/// <summary>
|
|
/// Замер длительности аудиофайла через ffprobe (format.duration). Используется при загрузке звука
|
|
/// блока заставки, чтобы длина заставки шла по длине звука.
|
|
/// </summary>
|
|
public sealed class FfprobeAudioProbe(IOptions<MediaOptions> mediaOptions) : IAudioProbe
|
|
{
|
|
private readonly MediaOptions _media = mediaOptions.Value;
|
|
|
|
public async Task<TimeSpan?> TryGetDurationAsync(
|
|
string absolutePath,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
if (!File.Exists(absolutePath))
|
|
return null;
|
|
|
|
try
|
|
{
|
|
var result = await ProcessRunner.RunAsync(
|
|
_media.FfprobePath,
|
|
["-v", "quiet", "-print_format", "json", "-show_format", absolutePath],
|
|
lowPriority: false,
|
|
cancellationToken
|
|
);
|
|
if (result.ExitCode != 0)
|
|
return null;
|
|
|
|
using var doc = JsonDocument.Parse(result.StdOut);
|
|
if (
|
|
doc.RootElement.TryGetProperty("format", out var format)
|
|
&& format.TryGetProperty("duration", out var durEl)
|
|
&& double.TryParse(
|
|
durEl.GetString(),
|
|
NumberStyles.Float,
|
|
CultureInfo.InvariantCulture,
|
|
out var seconds
|
|
)
|
|
&& seconds > 0
|
|
)
|
|
return TimeSpan.FromSeconds(seconds);
|
|
}
|
|
catch (Exception ex) when (ex is JsonException or InvalidOperationException)
|
|
{
|
|
// Не удалось разобрать вывод ffprobe — длину не знаем.
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|