* add download media sample button to playback troubleshooting * fixes
110 lines
4.3 KiB
C#
110 lines
4.3 KiB
C#
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.Core.Interfaces.Emby;
|
|
using ErsatzTV.Core.Interfaces.Jellyfin;
|
|
using ErsatzTV.Core.Interfaces.Plex;
|
|
|
|
namespace ErsatzTV.Core.Extensions;
|
|
|
|
public static class MediaItemExtensions
|
|
{
|
|
extension(MediaItem mediaItem)
|
|
{
|
|
public Option<TimeSpan> GetNonZeroDuration()
|
|
{
|
|
Option<TimeSpan> maybeDuration = mediaItem switch
|
|
{
|
|
Movie m => m.MediaVersions.HeadOrNone().Map(v => v.Duration),
|
|
Episode e => e.MediaVersions.HeadOrNone().Map(v => v.Duration),
|
|
MusicVideo mv => mv.MediaVersions.HeadOrNone().Map(v => v.Duration),
|
|
OtherVideo ov => ov.MediaVersions.HeadOrNone().Map(v => v.Duration),
|
|
Song s => s.MediaVersions.HeadOrNone().Map(v => v.Duration),
|
|
ChapterMediaItem c => c.MediaVersion.Duration,
|
|
_ => None
|
|
};
|
|
|
|
// zero duration is invalid, so return none in that case
|
|
return maybeDuration.Any(duration => duration == TimeSpan.Zero) ? Option<TimeSpan>.None : maybeDuration;
|
|
}
|
|
|
|
public TimeSpan GetDurationForPlayout()
|
|
{
|
|
if (mediaItem is Image image)
|
|
{
|
|
return TimeSpan.FromSeconds(image.ImageMetadata.Head().DurationSeconds ?? Image.DefaultSeconds);
|
|
}
|
|
|
|
MediaVersion version = mediaItem.GetHeadVersion();
|
|
|
|
if (mediaItem is RemoteStream remoteStream)
|
|
{
|
|
return version.Duration == TimeSpan.Zero && remoteStream.Duration.HasValue
|
|
? remoteStream.Duration.Value
|
|
: version.Duration;
|
|
}
|
|
|
|
return version.Duration;
|
|
}
|
|
|
|
public MediaVersion GetHeadVersion() =>
|
|
mediaItem switch
|
|
{
|
|
Movie m => m.MediaVersions.Head(),
|
|
Episode e => e.MediaVersions.Head(),
|
|
MusicVideo mv => mv.MediaVersions.Head(),
|
|
OtherVideo ov => ov.MediaVersions.Head(),
|
|
Song s => s.MediaVersions.Head(),
|
|
Image i => i.MediaVersions.Head(),
|
|
RemoteStream rs => rs.MediaVersions.Head(),
|
|
ChapterMediaItem c => c.MediaVersion,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(mediaItem))
|
|
};
|
|
|
|
public async Task<string> GetLocalPath(
|
|
IPlexPathReplacementService plexPathReplacementService,
|
|
IJellyfinPathReplacementService jellyfinPathReplacementService,
|
|
IEmbyPathReplacementService embyPathReplacementService,
|
|
CancellationToken cancellationToken,
|
|
bool log = true)
|
|
{
|
|
MediaVersion version = mediaItem.GetHeadVersion();
|
|
|
|
MediaFile file = version.MediaFiles.Head();
|
|
string path = file.Path;
|
|
return mediaItem switch
|
|
{
|
|
PlexMovie plexMovie => await plexPathReplacementService.GetReplacementPlexPath(
|
|
plexMovie.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
PlexEpisode plexEpisode => await plexPathReplacementService.GetReplacementPlexPath(
|
|
plexEpisode.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
JellyfinMovie jellyfinMovie => await jellyfinPathReplacementService.GetReplacementJellyfinPath(
|
|
jellyfinMovie.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
JellyfinEpisode jellyfinEpisode => await jellyfinPathReplacementService.GetReplacementJellyfinPath(
|
|
jellyfinEpisode.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
EmbyMovie embyMovie => await embyPathReplacementService.GetReplacementEmbyPath(
|
|
embyMovie.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
EmbyEpisode embyEpisode => await embyPathReplacementService.GetReplacementEmbyPath(
|
|
embyEpisode.LibraryPathId,
|
|
path,
|
|
cancellationToken,
|
|
log),
|
|
_ => path
|
|
};
|
|
}
|
|
}
|
|
}
|