MediaSegmentManager.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Immutable;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Jellyfin.Data.Entities;
  7. using Jellyfin.Data.Enums;
  8. using MediaBrowser.Controller;
  9. using MediaBrowser.Controller.Entities;
  10. using MediaBrowser.Model.MediaSegments;
  11. using Microsoft.EntityFrameworkCore;
  12. namespace Jellyfin.Server.Implementations.MediaSegments;
  13. /// <summary>
  14. /// Manages media segments retrival and storage.
  15. /// </summary>
  16. public class MediaSegmentManager : IMediaSegmentManager
  17. {
  18. private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
  19. /// <summary>
  20. /// Initializes a new instance of the <see cref="MediaSegmentManager"/> class.
  21. /// </summary>
  22. /// <param name="dbProvider">EFCore Database factory.</param>
  23. public MediaSegmentManager(IDbContextFactory<JellyfinDbContext> dbProvider)
  24. {
  25. _dbProvider = dbProvider;
  26. }
  27. /// <inheritdoc />
  28. public async Task<MediaSegmentDto> CreateSegmentAsync(MediaSegmentDto mediaSegment, string segmentProviderId)
  29. {
  30. ArgumentOutOfRangeException.ThrowIfLessThan(mediaSegment.EndTicks, mediaSegment.StartTicks);
  31. using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
  32. db.MediaSegments.Add(Map(mediaSegment, segmentProviderId));
  33. await db.SaveChangesAsync().ConfigureAwait(false);
  34. return mediaSegment;
  35. }
  36. /// <inheritdoc />
  37. public async Task DeleteSegmentAsync(Guid segmentId)
  38. {
  39. using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
  40. await db.MediaSegments.Where(e => e.Id.Equals(segmentId)).ExecuteDeleteAsync().ConfigureAwait(false);
  41. }
  42. /// <inheritdoc />
  43. public async Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(Guid itemId, IEnumerable<MediaSegmentType>? typeFilter)
  44. {
  45. using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
  46. var query = db.MediaSegments
  47. .Where(e => e.ItemId.Equals(itemId));
  48. if (typeFilter is not null)
  49. {
  50. query = query.Where(e => typeFilter.Contains(e.Type));
  51. }
  52. return query
  53. .OrderBy(e => e.StartTicks)
  54. .AsNoTracking()
  55. .ToImmutableList()
  56. .Select(Map);
  57. }
  58. private static MediaSegmentDto Map(MediaSegment segment)
  59. {
  60. return new MediaSegmentDto()
  61. {
  62. Id = segment.Id,
  63. EndTicks = segment.EndTicks,
  64. ItemId = segment.ItemId,
  65. StartTicks = segment.StartTicks,
  66. Type = segment.Type
  67. };
  68. }
  69. private static MediaSegment Map(MediaSegmentDto segment, string segmentProviderId)
  70. {
  71. return new MediaSegment()
  72. {
  73. Id = segment.Id,
  74. EndTicks = segment.EndTicks,
  75. ItemId = segment.ItemId,
  76. StartTicks = segment.StartTicks,
  77. Type = segment.Type,
  78. SegmentProviderId = segmentProviderId
  79. };
  80. }
  81. /// <inheritdoc />
  82. public bool HasSegments(Guid itemId)
  83. {
  84. using var db = _dbProvider.CreateDbContext();
  85. return db.MediaSegments.Any(e => e.ItemId.Equals(itemId));
  86. }
  87. /// <inheritdoc/>
  88. public bool IsTypeSupported(BaseItem baseItem)
  89. {
  90. return baseItem.MediaType is Data.Enums.MediaType.Video or Data.Enums.MediaType.Audio;
  91. }
  92. }