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); } }