MediaStreamRepository.cs 8.2 KB

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