using Bmp.Core.FFMpeg.CsCorePorts; using Bmp.Core.FFMpeg.CsCorePorts.FFMpegWrap; using Bmp.Core.Lite.Metadata; using Bmp.Core.Lite.Playback.Inputs; using NAudio.Wave; namespace Bmp.Core.Playback.Inputs { public class InputSourceProvider : InputSourceProviderLite { protected InputSourceProvider() { } public static AttachedPic[] GetPics(string urlOrPath) { AttachedPic[]? mappedEmbeddedPics = null; try { using var decoder = new FfmpegDecoder(ProcessUrlOrPathForFFMPEG(urlOrPath)); var fp = decoder.AttachedPics; mappedEmbeddedPics = fp?.Select(p => new AttachedPic { Tags = p.Meta, Data = p.Data.ToArray() }).ToArray(); } catch (Exception e) { //TODO: 消息机制 警告 无法从元数据获取图片 Console.WriteLine(e); } if (mappedEmbeddedPics?.Length > 1 == false) { foreach (var path in CoverFilePaths) { //TODO: DEBUG 尝试读取 旁边的 < 600KB var fi = FileCheckSize(path); if (fi.exists && fi.size < 600 * 1024) { var fc = ReadContent(new Uri(new Uri(urlOrPath), path).ToString()); if (fc.IsEmpty == false) { mappedEmbeddedPics = new[] { new AttachedPic { Data = fc, Tags = new Dictionary { { "Type", "Cover" } } } }; } } } } return mappedEmbeddedPics ?? Array.Empty(); } public static MetaDataWrap ReadMeta(string urlOrPath) { FfmpegDecoder? decoder = null; try { decoder = new FfmpegDecoder(ProcessUrlOrPathForFFMPEG(urlOrPath)); return new MetaDataWrap { RawTags = decoder.Metadata, Duration = decoder.GetLength(), }; } finally { decoder?.Dispose(); } } public static WaveStream CreateWaveStream(string urlOrPath, bool decodeDsdToPcm = false) { //TODO: InputSourceProvider::CreateWaveStream detect inner path //BACKLOG: more decoder if (decodeDsdToPcm == false) { using var underlyingStream = ReadContentAsSeekableStream(urlOrPath); underlyingStream.Position = 0; if (DsfAudioStream.IsDsfFile(underlyingStream)) return new DsfAudioStream(urlOrPath); underlyingStream.Position = 0; if (DffAudioStream.IsDffFile(underlyingStream)) return new DffAudioStream(urlOrPath); } return new FFMPEGAudioStream(ProcessUrlOrPathForFFMPEG(urlOrPath)); } } public class AttachedPic { public IReadOnlyDictionary? Tags { get; init; } public ReadOnlyMemory Data { get; init; } } }