MediaStreamRepository.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Immutable;
  4. using System.Linq;
  5. using System.Threading;
  6. using Jellyfin.Data.Entities;
  7. using MediaBrowser.Controller;
  8. using MediaBrowser.Controller.Persistence;
  9. using MediaBrowser.Model.Entities;
  10. using MediaBrowser.Model.Globalization;
  11. using Microsoft.EntityFrameworkCore;
  12. namespace Jellyfin.Server.Implementations.Item;
  13. /// <summary>
  14. /// Initializes a new instance of the <see cref="MediaStreamRepository"/> class.
  15. /// </summary>
  16. /// <param name="dbProvider">The EFCore db factory.</param>
  17. /// <param name="serverApplicationHost">The Application host.</param>
  18. /// <param name="localization">The Localisation Provider.</param>
  19. public class MediaStreamRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost serverApplicationHost, ILocalizationManager localization) : IMediaStreamRepository
  20. {
  21. /// <inheritdoc />
  22. public void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken)
  23. {
  24. using var context = dbProvider.CreateDbContext();
  25. using var transaction = context.Database.BeginTransaction();
  26. context.MediaStreamInfos.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
  27. context.MediaStreamInfos.AddRange(streams.Select(f => Map(f, id)));
  28. context.SaveChanges();
  29. transaction.Commit();
  30. }
  31. /// <inheritdoc />
  32. public IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery filter)
  33. {
  34. using var context = dbProvider.CreateDbContext();
  35. return TranslateQuery(context.MediaStreamInfos, filter).ToList().Select(Map).ToImmutableArray();
  36. }
  37. private string? GetPathToSave(string? path)
  38. {
  39. if (path is null)
  40. {
  41. return null;
  42. }
  43. return serverApplicationHost.ReverseVirtualPath(path);
  44. }
  45. private string? RestorePath(string? path)
  46. {
  47. if (path is null)
  48. {
  49. return null;
  50. }
  51. return serverApplicationHost.ExpandVirtualPath(path);
  52. }
  53. private IQueryable<MediaStreamInfo> TranslateQuery(IQueryable<MediaStreamInfo> query, MediaStreamQuery filter)
  54. {
  55. query = query.Where(e => e.ItemId.Equals(filter.ItemId));
  56. if (filter.Index.HasValue)
  57. {
  58. query = query.Where(e => e.StreamIndex == filter.Index);
  59. }
  60. if (filter.Type.HasValue)
  61. {
  62. query = query.Where(e => e.StreamType == filter.Type.ToString());
  63. }
  64. return query;
  65. }
  66. private MediaStream Map(MediaStreamInfo entity)
  67. {
  68. var dto = new MediaStream();
  69. dto.Index = entity.StreamIndex;
  70. if (entity.StreamType != null)
  71. {
  72. dto.Type = Enum.Parse<MediaStreamType>(entity.StreamType);
  73. }
  74. dto.IsAVC = entity.IsAvc;
  75. dto.Codec = entity.Codec;
  76. dto.Language = entity.Language;
  77. dto.ChannelLayout = entity.ChannelLayout;
  78. dto.Profile = entity.Profile;
  79. dto.AspectRatio = entity.AspectRatio;
  80. dto.Path = RestorePath(entity.Path);
  81. dto.IsInterlaced = entity.IsInterlaced;
  82. dto.BitRate = entity.BitRate;
  83. dto.Channels = entity.Channels;
  84. dto.SampleRate = entity.SampleRate;
  85. dto.IsDefault = entity.IsDefault;
  86. dto.IsForced = entity.IsForced;
  87. dto.IsExternal = entity.IsExternal;
  88. dto.Height = entity.Height;
  89. dto.Width = entity.Width;
  90. dto.AverageFrameRate = entity.AverageFrameRate;
  91. dto.RealFrameRate = entity.RealFrameRate;
  92. dto.Level = entity.Level;
  93. dto.PixelFormat = entity.PixelFormat;
  94. dto.BitDepth = entity.BitDepth;
  95. dto.IsAnamorphic = entity.IsAnamorphic;
  96. dto.RefFrames = entity.RefFrames;
  97. dto.CodecTag = entity.CodecTag;
  98. dto.Comment = entity.Comment;
  99. dto.NalLengthSize = entity.NalLengthSize;
  100. dto.Title = entity.Title;
  101. dto.TimeBase = entity.TimeBase;
  102. dto.CodecTimeBase = entity.CodecTimeBase;
  103. dto.ColorPrimaries = entity.ColorPrimaries;
  104. dto.ColorSpace = entity.ColorSpace;
  105. dto.ColorTransfer = entity.ColorTransfer;
  106. dto.DvVersionMajor = entity.DvVersionMajor;
  107. dto.DvVersionMinor = entity.DvVersionMinor;
  108. dto.DvProfile = entity.DvProfile;
  109. dto.DvLevel = entity.DvLevel;
  110. dto.RpuPresentFlag = entity.RpuPresentFlag;
  111. dto.ElPresentFlag = entity.ElPresentFlag;
  112. dto.BlPresentFlag = entity.BlPresentFlag;
  113. dto.DvBlSignalCompatibilityId = entity.DvBlSignalCompatibilityId;
  114. dto.IsHearingImpaired = entity.IsHearingImpaired;
  115. dto.Rotation = entity.Rotation;
  116. if (dto.Type is MediaStreamType.Audio or MediaStreamType.Subtitle)
  117. {
  118. dto.LocalizedDefault = localization.GetLocalizedString("Default");
  119. dto.LocalizedExternal = localization.GetLocalizedString("External");
  120. if (dto.Type is MediaStreamType.Subtitle)
  121. {
  122. dto.LocalizedUndefined = localization.GetLocalizedString("Undefined");
  123. dto.LocalizedForced = localization.GetLocalizedString("Forced");
  124. dto.LocalizedHearingImpaired = localization.GetLocalizedString("HearingImpaired");
  125. }
  126. }
  127. return dto;
  128. }
  129. private MediaStreamInfo Map(MediaStream dto, Guid itemId)
  130. {
  131. var entity = new MediaStreamInfo
  132. {
  133. Item = null!,
  134. ItemId = itemId,
  135. StreamIndex = dto.Index,
  136. StreamType = dto.Type.ToString(),
  137. IsAvc = dto.IsAVC.GetValueOrDefault(),
  138. Codec = dto.Codec,
  139. Language = dto.Language,
  140. ChannelLayout = dto.ChannelLayout,
  141. Profile = dto.Profile,
  142. AspectRatio = dto.AspectRatio,
  143. Path = GetPathToSave(dto.Path),
  144. IsInterlaced = dto.IsInterlaced,
  145. BitRate = dto.BitRate.GetValueOrDefault(0),
  146. Channels = dto.Channels.GetValueOrDefault(0),
  147. SampleRate = dto.SampleRate.GetValueOrDefault(0),
  148. IsDefault = dto.IsDefault,
  149. IsForced = dto.IsForced,
  150. IsExternal = dto.IsExternal,
  151. Height = dto.Height.GetValueOrDefault(0),
  152. Width = dto.Width.GetValueOrDefault(0),
  153. AverageFrameRate = dto.AverageFrameRate.GetValueOrDefault(0),
  154. RealFrameRate = dto.RealFrameRate.GetValueOrDefault(0),
  155. Level = (float)dto.Level.GetValueOrDefault(),
  156. PixelFormat = dto.PixelFormat,
  157. BitDepth = dto.BitDepth.GetValueOrDefault(0),
  158. IsAnamorphic = dto.IsAnamorphic.GetValueOrDefault(),
  159. RefFrames = dto.RefFrames.GetValueOrDefault(0),
  160. CodecTag = dto.CodecTag,
  161. Comment = dto.Comment,
  162. NalLengthSize = dto.NalLengthSize,
  163. Title = dto.Title,
  164. TimeBase = dto.TimeBase,
  165. CodecTimeBase = dto.CodecTimeBase,
  166. ColorPrimaries = dto.ColorPrimaries,
  167. ColorSpace = dto.ColorSpace,
  168. ColorTransfer = dto.ColorTransfer,
  169. DvVersionMajor = dto.DvVersionMajor.GetValueOrDefault(0),
  170. DvVersionMinor = dto.DvVersionMinor.GetValueOrDefault(0),
  171. DvProfile = dto.DvProfile.GetValueOrDefault(0),
  172. DvLevel = dto.DvLevel.GetValueOrDefault(0),
  173. RpuPresentFlag = dto.RpuPresentFlag.GetValueOrDefault(0),
  174. ElPresentFlag = dto.ElPresentFlag.GetValueOrDefault(0),
  175. BlPresentFlag = dto.BlPresentFlag.GetValueOrDefault(0),
  176. DvBlSignalCompatibilityId = dto.DvBlSignalCompatibilityId.GetValueOrDefault(0),
  177. IsHearingImpaired = dto.IsHearingImpaired,
  178. Rotation = dto.Rotation.GetValueOrDefault(0)
  179. };
  180. return entity;
  181. }
  182. }