From f8b45ed9db73dfddb570a68df7cb89865957a216 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Mon, 24 May 2021 09:03:39 -0500 Subject: [PATCH] fix unc path replacements from jellyfin and emby (#205) * fix UNC path replacements from non-windows JF and Emby servers * use emby path replacements for playback --- ...etPlayoutItemProcessByChannelNumberHandler.cs | 12 +++++++++++- ErsatzTV.Core/Emby/EmbyPathReplacementService.cs | 16 ++++++++++------ .../Jellyfin/JellyfinPathReplacementService.cs | 16 ++++++++++------ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs b/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs index df1512546..612ead67b 100644 --- a/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs +++ b/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs @@ -5,6 +5,7 @@ using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Errors; using ErsatzTV.Core.FFmpeg; +using ErsatzTV.Core.Interfaces.Emby; using ErsatzTV.Core.Interfaces.Jellyfin; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Plex; @@ -20,6 +21,7 @@ namespace ErsatzTV.Application.Streaming.Queries private readonly IConfigElementRepository _configElementRepository; private readonly FFmpegProcessService _ffmpegProcessService; private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService; + private readonly IEmbyPathReplacementService _embyPathReplacementService; private readonly ILocalFileSystem _localFileSystem; private readonly IPlayoutRepository _playoutRepository; private readonly IPlexPathReplacementService _plexPathReplacementService; @@ -31,7 +33,8 @@ namespace ErsatzTV.Application.Streaming.Queries FFmpegProcessService ffmpegProcessService, ILocalFileSystem localFileSystem, IPlexPathReplacementService plexPathReplacementService, - IJellyfinPathReplacementService jellyfinPathReplacementService) + IJellyfinPathReplacementService jellyfinPathReplacementService, + IEmbyPathReplacementService embyPathReplacementService) : base(channelRepository, configElementRepository) { _configElementRepository = configElementRepository; @@ -40,6 +43,7 @@ namespace ErsatzTV.Application.Streaming.Queries _localFileSystem = localFileSystem; _plexPathReplacementService = plexPathReplacementService; _jellyfinPathReplacementService = jellyfinPathReplacementService; + _embyPathReplacementService = embyPathReplacementService; } protected override async Task> GetProcess( @@ -178,6 +182,12 @@ namespace ErsatzTV.Application.Streaming.Queries JellyfinEpisode jellyfinEpisode => await _jellyfinPathReplacementService.GetReplacementJellyfinPath( jellyfinEpisode.LibraryPathId, path), + EmbyMovie embyMovie => await _embyPathReplacementService.GetReplacementEmbyPath( + embyMovie.LibraryPathId, + path), + EmbyEpisode embyEpisode => await _embyPathReplacementService.GetReplacementEmbyPath( + embyEpisode.LibraryPathId, + path), _ => path }; } diff --git a/ErsatzTV.Core/Emby/EmbyPathReplacementService.cs b/ErsatzTV.Core/Emby/EmbyPathReplacementService.cs index b60c7591d..465858756 100644 --- a/ErsatzTV.Core/Emby/EmbyPathReplacementService.cs +++ b/ErsatzTV.Core/Emby/EmbyPathReplacementService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -44,7 +45,7 @@ namespace ErsatzTV.Core.Emby .SingleOrDefault( r => { - string separatorChar = IsWindows(r.EmbyMediaSource) ? @"\" : @"/"; + string separatorChar = IsWindows(r.EmbyMediaSource, path) ? @"\" : @"/"; string prefix = r.EmbyPath.EndsWith(separatorChar) ? r.EmbyPath : r.EmbyPath + separatorChar; @@ -55,11 +56,11 @@ namespace ErsatzTV.Core.Emby replacement => { string finalPath = path.Replace(replacement.EmbyPath, replacement.LocalPath); - if (IsWindows(replacement.EmbyMediaSource) && !_runtimeInfo.IsOSPlatform(OSPlatform.Windows)) + if (IsWindows(replacement.EmbyMediaSource, path) && !_runtimeInfo.IsOSPlatform(OSPlatform.Windows)) { finalPath = finalPath.Replace(@"\", @"/"); } - else if (!IsWindows(replacement.EmbyMediaSource) && + else if (!IsWindows(replacement.EmbyMediaSource, path) && _runtimeInfo.IsOSPlatform(OSPlatform.Windows)) { finalPath = finalPath.Replace(@"/", @"\"); @@ -79,7 +80,10 @@ namespace ErsatzTV.Core.Emby () => path); } - private static bool IsWindows(EmbyMediaSource embyMediaSource) => - embyMediaSource.OperatingSystem.ToLowerInvariant().StartsWith("windows"); + private static bool IsWindows(EmbyMediaSource embyMediaSource, string path) + { + bool isUnc = Uri.TryCreate(path, UriKind.Absolute, out Uri uri) && uri.IsUnc; + return isUnc || embyMediaSource.OperatingSystem.ToLowerInvariant().StartsWith("windows"); + } } } diff --git a/ErsatzTV.Core/Jellyfin/JellyfinPathReplacementService.cs b/ErsatzTV.Core/Jellyfin/JellyfinPathReplacementService.cs index b0d21d905..0108e99b5 100644 --- a/ErsatzTV.Core/Jellyfin/JellyfinPathReplacementService.cs +++ b/ErsatzTV.Core/Jellyfin/JellyfinPathReplacementService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -44,7 +45,7 @@ namespace ErsatzTV.Core.Jellyfin .SingleOrDefault( r => { - string separatorChar = IsWindows(r.JellyfinMediaSource) ? @"\" : @"/"; + string separatorChar = IsWindows(r.JellyfinMediaSource, path) ? @"\" : @"/"; string prefix = r.JellyfinPath.EndsWith(separatorChar) ? r.JellyfinPath : r.JellyfinPath + separatorChar; @@ -55,11 +56,11 @@ namespace ErsatzTV.Core.Jellyfin replacement => { string finalPath = path.Replace(replacement.JellyfinPath, replacement.LocalPath); - if (IsWindows(replacement.JellyfinMediaSource) && !_runtimeInfo.IsOSPlatform(OSPlatform.Windows)) + if (IsWindows(replacement.JellyfinMediaSource, path) && !_runtimeInfo.IsOSPlatform(OSPlatform.Windows)) { finalPath = finalPath.Replace(@"\", @"/"); } - else if (!IsWindows(replacement.JellyfinMediaSource) && + else if (!IsWindows(replacement.JellyfinMediaSource, path) && _runtimeInfo.IsOSPlatform(OSPlatform.Windows)) { finalPath = finalPath.Replace(@"/", @"\"); @@ -79,7 +80,10 @@ namespace ErsatzTV.Core.Jellyfin () => path); } - private static bool IsWindows(JellyfinMediaSource jellyfinMediaSource) => - jellyfinMediaSource.OperatingSystem.ToLowerInvariant().StartsWith("windows"); + private static bool IsWindows(JellyfinMediaSource jellyfinMediaSource, string path) + { + bool isUnc = Uri.TryCreate(path, UriKind.Absolute, out Uri uri) && uri.IsUnc; + return isUnc || jellyfinMediaSource.OperatingSystem.ToLowerInvariant().StartsWith("windows"); + } } }