123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using FFmpeg.AutoGen;
- using FNZCM2.Abstractions.Models.Metadata;
- using MimeDetective;
- namespace FNZCM2.Abstractions.Utility;
- public static class FileMetaReader
- {
- private static readonly ContentInspector Inspector;
- static FileMetaReader() => Inspector = new ContentInspectorBuilder { Definitions = MimeDetective.Definitions.Default.All() }.Build();
- public static FileMetaEntry? Read(string path, long fileId, out string err)
- {
- var fileType = FileType.Unknown;
- AudioInfo? audio = null;
- PictureInfo? pic = null;
- int? bitRate = null;
- int? dur = null;
- MetaInfo meta = null;
- List<AVCodecID> codecs = new();
- var ir = Inspector.Inspect(path);
- var irm = ir.ByMimeType().FirstOrDefault();
- if (irm == null)
- {
- }
- else if (irm.MimeType.StartsWith("audio/", StringComparison.InvariantCultureIgnoreCase)) fileType = FileType.Audio;
- else if (irm.MimeType.StartsWith("video/", StringComparison.InvariantCultureIgnoreCase)) fileType = FileType.Video;
- else if (irm.MimeType.StartsWith("image/", StringComparison.InvariantCultureIgnoreCase)) fileType = FileType.Picture;
- else if (irm.MimeType.StartsWith("text/", StringComparison.InvariantCultureIgnoreCase)) fileType = FileType.Text;
- else if (irm.MimeType.Equals("application/pdf", StringComparison.InvariantCultureIgnoreCase)) fileType = FileType.Doc;
- var frr = FfMpegReader.Read(path, out err);
- if (fileType == FileType.Unknown && frr != null)
- {
- if (frr.Streams.Any(p => p.Type == AVMediaType.AVMEDIA_TYPE_VIDEO)
- && frr.Streams.Any(p => p.Type == AVMediaType.AVMEDIA_TYPE_AUDIO)) fileType = FileType.Video;
- }
- if (fileType is FileType.Unknown or FileType.Text or FileType.Doc)
- {
- err = null;
- return new FileMetaEntry
- {
- FileId = fileId,
- FileType = fileType,
- Audio = audio,
- Picture = pic,
- BitRate = bitRate,
- DurationMs = dur,
- Meta = meta,
- Codecs = codecs.ToArray(),
- };
- }
- if (frr == null)
- {
- return new FileMetaEntry
- {
- FileId = fileId,
- FileType = fileType,
- Audio = audio,
- Picture = pic,
- BitRate = bitRate,
- DurationMs = dur,
- Meta = meta,
- Codecs = codecs.ToArray(),
- };
- }
- switch (fileType)
- {
- case FileType.Picture:
- {
- var s = frr.Streams.FirstOrDefault(p => p.Type == AVMediaType.AVMEDIA_TYPE_VIDEO);
- pic = s?.PictureInfo;
- if (s != null) codecs.Add(s.Codec);
- }
- break;
- case FileType.Audio:
- {
- dur = frr.DurationMs;
- bitRate = frr.BitRate;
- var s = frr.Streams.FirstOrDefault(p => p.Type == AVMediaType.AVMEDIA_TYPE_AUDIO);
- audio = s?.AudioInfo;
- if (s != null) codecs.Add(s.Codec);
- }
- break;
- case FileType.Video:
- {
- dur = frr.DurationMs;
- bitRate = frr.BitRate;
- var sv = frr.Streams.FirstOrDefault(p => p.Type == AVMediaType.AVMEDIA_TYPE_VIDEO);
- pic = sv?.PictureInfo;
- if (sv != null) codecs.Add(sv.Codec);
- var sa = frr.Streams.FirstOrDefault(p => p.Type == AVMediaType.AVMEDIA_TYPE_AUDIO);
- audio = sa?.AudioInfo;
- if (sa != null) codecs.Add(sa.Codec);
- }
- break;
- }
- if (frr.MetaData?.Count > 0)
- {
- var other = new Dictionary<string, string>();
- string? a = null;
- string? b = null;
- string? c = null;
- int? d = null;
- int? g = null;
- string? e = null;
- string? t = null;
- string? p = null;
- string? v = null;
- string? q = null;
- string? r = null;
- string? l = null;
- int? n = null;
- int? o = null;
- foreach (var kv in frr.MetaData)
- {
- switch (kv.Key)
- {
- case "album": a = kv.Value; break;
- case "catalogid": c = kv.Value; break;
- case "composer": q = kv.Value; break;
- case "title": t = kv.Value; break;
- case "event": e = kv.Value; break;
- case "genre": l = kv.Value; break;
- case "album_artist":
- case "album artist":
- if (b != null) other[kv.Key] = kv.Value; else b = kv.Value;
- break;
- case "artist":
- case "performer":
- if (p != null) other[kv.Key] = kv.Value; else p = kv.Value;
- break;
- case "vocal":
- case "voice":
- if (v != null) other[kv.Key] = kv.Value; else v = kv.Value;
- break;
- case "date":
- if (DateTime.TryParseExact(kv.Value, "yyyy", null, DateTimeStyles.None, out var dtYear))
- {
- r = $"{dtYear.Year}-??-??";
- }
- else if (DateTime.TryParseExact(kv.Value, "yyyy.MM", null, DateTimeStyles.None, out var dtDotYm))
- {
- r = $"{dtDotYm.Year}-{dtDotYm.Month:00}-??";
- }
- else if (DateTime.TryParseExact(kv.Value, "yyyy.MM.dd", null, DateTimeStyles.None, out var dtDotYmd))
- {
- r = $"{dtDotYmd.Year}-{dtDotYmd.Month:00}-{dtDotYmd.Day:00}";
- }
- else if (DateTime.TryParseExact(kv.Value, "yyyy-MM-dd", null, DateTimeStyles.None, out var dtDaYmd))
- {
- r = $"{dtDaYmd.Year}-{dtDaYmd.Month:00}-{dtDaYmd.Day:00}";
- }
- else if (DateTime.TryParse(kv.Value, out var pd))
- {
- r = $"{pd.Year}-{pd.Month:00}-{pd.Day:00}";
- }
- else
- {
- other[kv.Key] = kv.Value;
- }
- break;
- case "disc":
- var parts = kv.Value.Split('/');
- if (parts.Length == 2 && int.TryParse(parts[0], out var d1) && int.TryParse(parts[1], out var d2))
- {
- n = d1; o = d2;
- }
- else if (int.TryParse(kv.Value, out var disc))
- d = disc;
- else
- goto default;
- break;
- case "disctotal":
- case "totaldiscs":
- if (int.TryParse(kv.Value, out var dt))
- g = dt;
- else
- goto default;
- break;
- case "tracktotal":
- case "totaltracks":
- if (int.TryParse(kv.Value, out var to))
- o = to;
- else
- goto default;
- break;
- case "track":
- if (int.TryParse(kv.Value, out var tn))
- n = tn;
- else
- goto default;
- break;
- case "discid": other[kv.Key] = kv.Value; break;
- case "comment": other[kv.Key] = kv.Value; break;
- case "origin": other[kv.Key] = kv.Value; break;
- case "originaltitle": other[kv.Key] = kv.Value; break;
- case "mastering": other[kv.Key] = kv.Value; break;
- case "replaygain_album_gain": other[kv.Key] = kv.Value; break;
- case "replaygain_album_peak": other[kv.Key] = kv.Value; break;
- case "replaygain_track_gain": other[kv.Key] = kv.Value; break;
- case "replaygain_track_peak": other[kv.Key] = kv.Value; break;
- case "engineer": other[kv.Key] = kv.Value; break;
- case "catalog": other[kv.Key] = kv.Value; break;
- case "remixer": other[kv.Key] = kv.Value; break;
- case "lyricist": other[kv.Key] = kv.Value; break;
- case "guitar": other[kv.Key] = kv.Value; break;
- case "encoder": other[kv.Key] = kv.Value; break;
- case "itunes_cddb_1": other[kv.Key] = kv.Value; break;
- case "synthesizer": other[kv.Key] = kv.Value; break;
- case "acoustic guitar": other[kv.Key] = kv.Value; break;
- case "midi guitar": other[kv.Key] = kv.Value; break;
- case "chorus": other[kv.Key] = kv.Value; break;
- case "bass": other[kv.Key] = kv.Value; break;
- case "drums": other[kv.Key] = kv.Value; break;
- case "viola": other[kv.Key] = kv.Value; break;
- case "violin": other[kv.Key] = kv.Value; break;
- case "isrc": other[kv.Key] = kv.Value; break;
- case "wind synthesizer": other[kv.Key] = kv.Value; break;
- case "saxophone": other[kv.Key] = kv.Value; break;
- case "piano": other[kv.Key] = kv.Value; break;
- case "arrange": other[kv.Key] = kv.Value; break;
- case "check": other[kv.Key] = kv.Value; break;
- case "retrievable": other[kv.Key] = kv.Value; break;
- case "source": other[kv.Key] = kv.Value; break;
- case "vpc": other[kv.Key] = kv.Value; break;
- default:
- if (kv.Key.StartsWith("cue_track") && kv.Key.EndsWith("_artist"))
- {
- other[kv.Key] = kv.Value;
- }
- else
- {
- other[kv.Key] = kv.Value;
- }
- break;
- }
- }
- meta = new()
- {
- Album = a,
- AlbumArtist = b,
- Catalog = c,
- Disc = d,
- DiscTotal = g,
- Event = e,
- Title = t,
- Artist = p,
- Vocal = v,
- Composer = q,
- Release = r,
- Track = n,
- TrackTotal = o,
- Other = other.AsReadOnly(),
- Genre = l,
- };
- }
- //throw new NotImplementedException();
- return new FileMetaEntry
- {
- FileId = fileId,
- FileType = fileType,
- Audio = audio,
- Picture = pic,
- BitRate = bitRate,
- DurationMs = dur,
- Meta = meta,
- Codecs = codecs.ToArray(),
- };
- }
- }
|