using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.MediaSegments; using Microsoft.EntityFrameworkCore; namespace Jellyfin.Server.Implementations.MediaSegments; /// /// Manages media segments retrival and storage. /// public class MediaSegmentManager : IMediaSegmentManager { private readonly IDbContextFactory _dbProvider; /// /// Initializes a new instance of the class. /// /// EFCore Database factory. public MediaSegmentManager(IDbContextFactory dbProvider) { _dbProvider = dbProvider; } /// public async Task CreateSegmentAsync(MediaSegmentDto mediaSegment, string segmentProviderId) { ArgumentOutOfRangeException.ThrowIfLessThan(mediaSegment.EndTicks, mediaSegment.StartTicks); using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false); db.MediaSegments.Add(Map(mediaSegment, segmentProviderId)); await db.SaveChangesAsync().ConfigureAwait(false); return mediaSegment; } /// public async Task DeleteSegmentAsync(Guid segmentId) { using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false); await db.MediaSegments.Where(e => e.Id.Equals(segmentId)).ExecuteDeleteAsync().ConfigureAwait(false); } /// public async Task> GetSegmentsAsync(Guid itemId, IEnumerable? typeFilter) { using var db = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false); var query = db.MediaSegments .Where(e => e.ItemId.Equals(itemId)); if (typeFilter is not null) { query = query.Where(e => typeFilter.Contains(e.Type)); } return query .OrderBy(e => e.StartTicks) .AsNoTracking() .ToImmutableList() .Select(Map); } private static MediaSegmentDto Map(MediaSegment segment) { return new MediaSegmentDto() { Id = segment.Id, EndTicks = segment.EndTicks, ItemId = segment.ItemId, StartTicks = segment.StartTicks, Type = segment.Type }; } private static MediaSegment Map(MediaSegmentDto segment, string segmentProviderId) { return new MediaSegment() { Id = segment.Id, EndTicks = segment.EndTicks, ItemId = segment.ItemId, StartTicks = segment.StartTicks, Type = segment.Type, SegmentProviderId = segmentProviderId }; } /// public bool HasSegments(Guid itemId) { using var db = _dbProvider.CreateDbContext(); return db.MediaSegments.Any(e => e.ItemId.Equals(itemId)); } /// public bool IsTypeSupported(BaseItem baseItem) { return baseItem.MediaType is Data.Enums.MediaType.Video or Data.Enums.MediaType.Audio; } }