using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
namespace FileFlows.AudioNodes;
///
/// Represents the JSON structure returned by ffprobe for an audio file.
///
public class FFprobeAudioInfo
{
///
/// Gets or sets the format information extracted from ffprobe.
///
public AudioFormatInfo Format { get; set; }
///
/// Parses JSON output from FFprobe
///
/// the json output from FFprobe
/// the AudioFormatInfo parsed
[RequiresUnreferencedCode("")]
public static Result Parse(string json)
{
try
{
var ffAudioFormatInfo = JsonSerializer.Deserialize(json,
new JsonSerializerOptions()
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
IgnoreNullValues = true,
PropertyNameCaseInsensitive = true
});
return ffAudioFormatInfo.Format;
}
catch (Exception ex)
{
return Result.Fail(ex.Message);
}
}
}
///
/// Represents the format information extracted from ffprobe for an audio file.
///
public class AudioFormatInfo
{
///
/// Gets or sets the filename of the audio file.
///
public string Filename { get; set; }
///
/// Gets or sets the number of streams in the audio file.
///
public int NbStreams { get; set; }
///
/// Gets or sets the number of programs in the audio file.
///
public int NbPrograms { get; set; }
///
/// Gets or sets the format name (e.g., flac).
///
public string FormatName { get; set; }
///
/// Gets or sets the long format name (e.g., raw FLAC).
///
public string FormatLongName { get; set; }
///
/// Gets or sets the duration of the audio file.
///
[JsonPropertyName("duration")]
[JsonConverter(typeof(FFprobeTimeSpanConverter))]
public TimeSpan Duration { get; set; }
///
/// Gets or sets the start time of the audio file.
///
[JsonPropertyName("start_time")]
[JsonConverter(typeof(FFprobeTimeSpanConverter))]
public TimeSpan StartTime { get; set; }
///
/// Gets or sets the size of the audio file.
///
[JsonPropertyName("size")]
[JsonConverter(typeof(LongConverter))]
public long Size { get; set; }
///
/// Gets or sets the bit rate of the audio file.
///
[JsonPropertyName("bit_rate")]
[JsonConverter(typeof(LongConverter))]
public long Bitrate { get; set; }
///
/// Gets or sets the probe score.
///
public int ProbeScore { get; set; }
///
/// Gets or sets the tags associated with the audio file.
///
public AudioTags Tags { get; set; }
}
///
/// Represents the tags associated with an audio file.
///
public class AudioTags
{
///
/// Gets or sets the title of the audio file.
///
public string Title { get; set; }
///
/// Gets or sets the artist of the audio file.
///
public string Artist { get; set; }
///
/// Gets or sets the album of the audio file.
///
public string Album { get; set; }
///
/// Gets or sets the track number of the audio file.
///
public string Track { get; set; }
///
/// Gets or sets the release date of the audio file.
///
public string Date { get; set; }
///
/// Gets or sets the genre of the audio file.
///
public string Genre { get; set; }
///
/// Gets or sets the total number of tracks in the album.
///
public string TotalTracks { get; set; }
///
/// Gets or sets the disc number of the audio file.
///
public string Disc { get; set; }
///
/// Gets or sets the total number of discs in the album.
///
public string TotalDiscs { get; set; }
}
///
/// Custom converter for TimeSpan to handle string representation.
///
public class FFprobeTimeSpanConverter : JsonConverter
{
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var stringValue = reader.GetString() ?? string.Empty;
if (double.TryParse(stringValue, out double seconds) == false)
return default;
return TimeSpan.FromSeconds(seconds);
}
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.TotalSeconds.ToString(CultureInfo.InvariantCulture));
}
}
///
/// Custom converter for long to handle string representation.
///
public class LongConverter : JsonConverter
{
public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
if (long.TryParse(reader.GetString(), out long result))
{
return result;
}
}
else if (reader.TokenType == JsonTokenType.Number)
{
return reader.GetInt64();
}
throw new JsonException($"Invalid long format: {reader.GetString()}");
}
public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
{
writer.WriteNumberValue(value);
}
}