InputSourceProvider.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using Bmp.Core.FFMpeg.CsCorePorts;
  2. using Bmp.Core.FFMpeg.CsCorePorts.FFMpegWrap;
  3. using Bmp.Core.Lite.Metadata;
  4. using Bmp.Core.Lite.Playback.Inputs;
  5. using NAudio.Wave;
  6. namespace Bmp.Core.Playback.Inputs
  7. {
  8. public class InputSourceProvider : InputSourceProviderLite
  9. {
  10. protected InputSourceProvider()
  11. {
  12. }
  13. public static AttachedPic[] GetPics(string urlOrPath)
  14. {
  15. AttachedPic[]? mappedEmbeddedPics = null;
  16. try
  17. {
  18. using var decoder = new FfmpegDecoder(ProcessUrlOrPathForFFMPEG(urlOrPath));
  19. var fp = decoder.AttachedPics;
  20. mappedEmbeddedPics = fp?.Select(p => new AttachedPic { Tags = p.Meta, Data = p.Data.ToArray() }).ToArray();
  21. }
  22. catch (Exception e)
  23. {
  24. //TODO: 消息机制 警告 无法从元数据获取图片
  25. Console.WriteLine(e);
  26. }
  27. if (mappedEmbeddedPics?.Length > 1 == false)
  28. {
  29. foreach (var path in CoverFilePaths)
  30. {
  31. //TODO: DEBUG 尝试读取 旁边的 < 600KB
  32. var fi = FileCheckSize(path);
  33. if (fi.exists && fi.size < 600 * 1024)
  34. {
  35. var fc = ReadContent(new Uri(new Uri(urlOrPath), path).ToString());
  36. if (fc.IsEmpty == false)
  37. {
  38. mappedEmbeddedPics = new[]
  39. {
  40. new AttachedPic { Data = fc, Tags = new Dictionary<string, string> { { "Type", "Cover" } } }
  41. };
  42. }
  43. }
  44. }
  45. }
  46. return mappedEmbeddedPics ?? Array.Empty<AttachedPic>();
  47. }
  48. public static MetaDataWrap ReadMeta(string urlOrPath)
  49. {
  50. FfmpegDecoder? decoder = null;
  51. try
  52. {
  53. decoder = new FfmpegDecoder(ProcessUrlOrPathForFFMPEG(urlOrPath));
  54. return new MetaDataWrap
  55. {
  56. RawTags = decoder.Metadata,
  57. Duration = decoder.GetLength(),
  58. };
  59. }
  60. finally
  61. {
  62. decoder?.Dispose();
  63. }
  64. }
  65. public static WaveStream CreateWaveStream(string urlOrPath, bool decodeDsdToPcm = false)
  66. {
  67. //TODO: InputSourceProvider::CreateWaveStream detect inner path
  68. //BACKLOG: more decoder
  69. if (decodeDsdToPcm == false)
  70. {
  71. using var underlyingStream = ReadContentAsSeekableStream(urlOrPath);
  72. underlyingStream.Position = 0;
  73. if (DsfAudioStream.IsDsfFile(underlyingStream)) return new DsfAudioStream(urlOrPath);
  74. underlyingStream.Position = 0;
  75. if (DffAudioStream.IsDffFile(underlyingStream)) return new DffAudioStream(urlOrPath);
  76. }
  77. return new FFMPEGAudioStream(ProcessUrlOrPathForFFMPEG(urlOrPath));
  78. }
  79. }
  80. public class AttachedPic
  81. {
  82. public IReadOnlyDictionary<string, string>? Tags { get; init; }
  83. public ReadOnlyMemory<byte> Data { get; init; }
  84. }
  85. }