2024-10-25 14:31:50 -04:00
|
|
|
// Copyright (C) 2024 Intro-Skipper contributors <intro-skipper.org>
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-only.
|
2024-10-25 14:15:12 -04:00
|
|
|
|
2024-10-11 21:08:12 +02:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
2024-11-02 18:17:22 +01:00
|
|
|
using IntroSkipper.Data;
|
2024-10-11 21:08:12 +02:00
|
|
|
using Jellyfin.Data.Enums;
|
|
|
|
using MediaBrowser.Controller;
|
|
|
|
using MediaBrowser.Controller.Entities;
|
2024-10-20 13:27:05 +02:00
|
|
|
using MediaBrowser.Controller.Entities.Movies;
|
|
|
|
using MediaBrowser.Controller.Entities.TV;
|
2024-10-11 21:08:12 +02:00
|
|
|
using MediaBrowser.Model;
|
|
|
|
using MediaBrowser.Model.MediaSegments;
|
|
|
|
|
2024-10-19 23:50:41 +02:00
|
|
|
namespace IntroSkipper.Providers
|
2024-10-11 21:08:12 +02:00
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Introskipper media segment provider.
|
|
|
|
/// </summary>
|
|
|
|
public class SegmentProvider : IMediaSegmentProvider
|
|
|
|
{
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public string Name => Plugin.Instance!.Name;
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public Task<IReadOnlyList<MediaSegmentDto>> GetMediaSegments(MediaSegmentGenerationRequest request, CancellationToken cancellationToken)
|
|
|
|
{
|
2024-11-02 18:17:22 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(request);
|
|
|
|
ArgumentNullException.ThrowIfNull(Plugin.Instance);
|
|
|
|
|
2024-10-11 21:08:12 +02:00
|
|
|
var segments = new List<MediaSegmentDto>();
|
2024-11-02 18:17:22 +01:00
|
|
|
var remainingTicks = Plugin.Instance.Configuration.RemainingSecondsOfIntro * TimeSpan.TicksPerSecond;
|
|
|
|
var itemSegments = Plugin.Instance.GetSegmentsById(request.ItemId);
|
2024-10-11 21:08:12 +02:00
|
|
|
|
2024-11-02 18:17:22 +01:00
|
|
|
// Add intro segment if found
|
|
|
|
if (itemSegments.TryGetValue(AnalysisMode.Introduction, out var introSegment) && introSegment.Valid)
|
2024-10-11 21:08:12 +02:00
|
|
|
{
|
|
|
|
segments.Add(new MediaSegmentDto
|
|
|
|
{
|
2024-11-02 18:17:22 +01:00
|
|
|
StartTicks = (long)(introSegment.Start * TimeSpan.TicksPerSecond),
|
|
|
|
EndTicks = (long)(introSegment.End * TimeSpan.TicksPerSecond) - remainingTicks,
|
2024-10-11 21:08:12 +02:00
|
|
|
ItemId = request.ItemId,
|
|
|
|
Type = MediaSegmentType.Intro
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-11-02 18:17:22 +01:00
|
|
|
// Add outro/credits segment if found
|
|
|
|
if (itemSegments.TryGetValue(AnalysisMode.Introduction, out var creditSegment) && creditSegment.Valid)
|
2024-10-11 21:08:12 +02:00
|
|
|
{
|
2024-11-02 18:17:22 +01:00
|
|
|
var creditEndTicks = (long)(creditSegment.End * TimeSpan.TicksPerSecond);
|
2024-10-21 08:52:43 +02:00
|
|
|
var runTimeTicks = Plugin.Instance.GetItem(request.ItemId)?.RunTimeTicks ?? long.MaxValue;
|
2024-11-02 18:17:22 +01:00
|
|
|
|
2024-10-20 13:27:05 +02:00
|
|
|
segments.Add(new MediaSegmentDto
|
|
|
|
{
|
2024-11-02 18:17:22 +01:00
|
|
|
StartTicks = (long)(creditSegment.Start * TimeSpan.TicksPerSecond),
|
2024-10-21 08:52:43 +02:00
|
|
|
EndTicks = runTimeTicks > creditEndTicks + TimeSpan.TicksPerSecond
|
2024-11-02 18:17:22 +01:00
|
|
|
? creditEndTicks - remainingTicks
|
|
|
|
: runTimeTicks,
|
2024-10-20 13:27:05 +02:00
|
|
|
ItemId = request.ItemId,
|
|
|
|
Type = MediaSegmentType.Outro
|
|
|
|
});
|
2024-10-11 21:08:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Task.FromResult<IReadOnlyList<MediaSegmentDto>>(segments);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
2024-10-20 13:27:05 +02:00
|
|
|
public ValueTask<bool> Supports(BaseItem item) => ValueTask.FromResult(item is Episode or Movie);
|
2024-10-11 21:08:12 +02:00
|
|
|
}
|
|
|
|
}
|