mirror of https://github.com/jellyfin/jellyfin.git
Merge pull request #2772 from barronpm/codecleanup
MediaBrowser.Api code cleanup
This commit is contained in:
commit
14674d4469
|
@ -86,12 +86,9 @@ namespace MediaBrowser.Api
|
||||||
return Array.Empty<string>();
|
return Array.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removeEmpty)
|
return removeEmpty
|
||||||
{
|
? value.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
return value.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
|
: value.Split(separator);
|
||||||
}
|
|
||||||
|
|
||||||
return value.Split(separator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SemaphoreSlim GetTranscodingLock(string outputPath)
|
public SemaphoreSlim GetTranscodingLock(string outputPath)
|
||||||
|
@ -258,7 +255,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
public void ReportTranscodingProgress(TranscodingJob job, StreamState state, TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
|
||||||
{
|
{
|
||||||
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;
|
var ticks = transcodingPosition?.Ticks;
|
||||||
|
|
||||||
if (job != null)
|
if (job != null)
|
||||||
{
|
{
|
||||||
|
@ -487,16 +484,9 @@ namespace MediaBrowser.Api
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
internal Task KillTranscodingJobs(string deviceId, string playSessionId, Func<string, bool> deleteFiles)
|
internal Task KillTranscodingJobs(string deviceId, string playSessionId, Func<string, bool> deleteFiles)
|
||||||
{
|
{
|
||||||
return KillTranscodingJobs(j =>
|
return KillTranscodingJobs(j => string.IsNullOrWhiteSpace(playSessionId)
|
||||||
{
|
? string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase)
|
||||||
if (!string.IsNullOrWhiteSpace(playSessionId))
|
: string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase), deleteFiles);
|
||||||
{
|
|
||||||
return string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
}, deleteFiles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -561,10 +551,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
lock (job.ProcessLock)
|
lock (job.ProcessLock)
|
||||||
{
|
{
|
||||||
if (job.TranscodingThrottler != null)
|
job.TranscodingThrottler?.Stop().GetAwaiter().GetResult();
|
||||||
{
|
|
||||||
job.TranscodingThrottler.Stop().GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
var process = job.Process;
|
var process = job.Process;
|
||||||
|
|
||||||
|
|
|
@ -58,12 +58,9 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
public static string[] SplitValue(string value, char delim)
|
public static string[] SplitValue(string value, char delim)
|
||||||
{
|
{
|
||||||
if (value == null)
|
return value == null
|
||||||
{
|
? Array.Empty<string>()
|
||||||
return Array.Empty<string>();
|
: value.Split(new[] { delim }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
|
||||||
|
|
||||||
return value.Split(new[] { delim }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid[] GetGuids(string value)
|
public static Guid[] GetGuids(string value)
|
||||||
|
@ -97,19 +94,10 @@ namespace MediaBrowser.Api
|
||||||
var authenticatedUser = auth.User;
|
var authenticatedUser = auth.User;
|
||||||
|
|
||||||
// If they're going to update the record of another user, they must be an administrator
|
// If they're going to update the record of another user, they must be an administrator
|
||||||
if (!userId.Equals(auth.UserId))
|
if ((!userId.Equals(auth.UserId) && !authenticatedUser.Policy.IsAdministrator)
|
||||||
|
|| (restrictUserPreferences && !authenticatedUser.Policy.EnableUserPreferenceAccess))
|
||||||
{
|
{
|
||||||
if (!authenticatedUser.Policy.IsAdministrator)
|
throw new SecurityException("Unauthorized access.");
|
||||||
{
|
|
||||||
throw new SecurityException("Unauthorized access.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (restrictUserPreferences)
|
|
||||||
{
|
|
||||||
if (!authenticatedUser.Policy.EnableUserPreferenceAccess)
|
|
||||||
{
|
|
||||||
throw new SecurityException("Unauthorized access.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,8 +126,8 @@ namespace MediaBrowser.Api
|
||||||
options.Fields = hasFields.GetItemFields();
|
options.Fields = hasFields.GetItemFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.ContainsField(Model.Querying.ItemFields.RecursiveItemCount)
|
if (!options.ContainsField(ItemFields.RecursiveItemCount)
|
||||||
|| !options.ContainsField(Model.Querying.ItemFields.ChildCount))
|
|| !options.ContainsField(ItemFields.ChildCount))
|
||||||
{
|
{
|
||||||
var client = authContext.GetAuthorizationInfo(Request).Client ?? string.Empty;
|
var client = authContext.GetAuthorizationInfo(Request).Client ?? string.Empty;
|
||||||
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
|
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||||
|
@ -150,7 +138,7 @@ namespace MediaBrowser.Api
|
||||||
int oldLen = options.Fields.Length;
|
int oldLen = options.Fields.Length;
|
||||||
var arr = new ItemFields[oldLen + 1];
|
var arr = new ItemFields[oldLen + 1];
|
||||||
options.Fields.CopyTo(arr, 0);
|
options.Fields.CopyTo(arr, 0);
|
||||||
arr[oldLen] = Model.Querying.ItemFields.RecursiveItemCount;
|
arr[oldLen] = ItemFields.RecursiveItemCount;
|
||||||
options.Fields = arr;
|
options.Fields = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +154,7 @@ namespace MediaBrowser.Api
|
||||||
int oldLen = options.Fields.Length;
|
int oldLen = options.Fields.Length;
|
||||||
var arr = new ItemFields[oldLen + 1];
|
var arr = new ItemFields[oldLen + 1];
|
||||||
options.Fields.CopyTo(arr, 0);
|
options.Fields.CopyTo(arr, 0);
|
||||||
arr[oldLen] = Model.Querying.ItemFields.ChildCount;
|
arr[oldLen] = ItemFields.ChildCount;
|
||||||
options.Fields = arr;
|
options.Fields = arr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,27 +270,21 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
}).OfType<T>().FirstOrDefault();
|
}).OfType<T>().FirstOrDefault();
|
||||||
|
|
||||||
if (result == null)
|
result ??= libraryManager.GetItemList(new InternalItemsQuery
|
||||||
{
|
{
|
||||||
result = libraryManager.GetItemList(new InternalItemsQuery
|
Name = name.Replace(BaseItem.SlugChar, '/'),
|
||||||
{
|
IncludeItemTypes = new[] { typeof(T).Name },
|
||||||
Name = name.Replace(BaseItem.SlugChar, '/'),
|
DtoOptions = dtoOptions
|
||||||
IncludeItemTypes = new[] { typeof(T).Name },
|
|
||||||
DtoOptions = dtoOptions
|
|
||||||
|
|
||||||
}).OfType<T>().FirstOrDefault();
|
}).OfType<T>().FirstOrDefault();
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null)
|
result ??= libraryManager.GetItemList(new InternalItemsQuery
|
||||||
{
|
{
|
||||||
result = libraryManager.GetItemList(new InternalItemsQuery
|
Name = name.Replace(BaseItem.SlugChar, '?'),
|
||||||
{
|
IncludeItemTypes = new[] { typeof(T).Name },
|
||||||
Name = name.Replace(BaseItem.SlugChar, '?'),
|
DtoOptions = dtoOptions
|
||||||
IncludeItemTypes = new[] { typeof(T).Name },
|
|
||||||
DtoOptions = dtoOptions
|
|
||||||
|
|
||||||
}).OfType<T>().FirstOrDefault();
|
}).OfType<T>().FirstOrDefault();
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,12 +116,9 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
var val = Filters;
|
var val = Filters;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(val))
|
return string.IsNullOrEmpty(val)
|
||||||
{
|
? Array.Empty<ItemFilter>()
|
||||||
return new ItemFilter[] { };
|
: val.Split(',').Select(v => Enum.Parse<ItemFilter>(v, true));
|
||||||
}
|
|
||||||
|
|
||||||
return val.Split(',').Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -173,14 +170,9 @@ namespace MediaBrowser.Api
|
||||||
/// <returns>IEnumerable{ItemFilter}.</returns>
|
/// <returns>IEnumerable{ItemFilter}.</returns>
|
||||||
public IEnumerable<ItemFilter> GetFilters()
|
public IEnumerable<ItemFilter> GetFilters()
|
||||||
{
|
{
|
||||||
var val = Filters;
|
return string.IsNullOrEmpty(Filters)
|
||||||
|
? Array.Empty<ItemFilter>()
|
||||||
if (string.IsNullOrEmpty(val))
|
: Filters.Split(',').Select(v => Enum.Parse<ItemFilter>(v, true));
|
||||||
{
|
|
||||||
return new ItemFilter[] { };
|
|
||||||
}
|
|
||||||
|
|
||||||
return val.Split(',').Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +233,7 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
StartIndex = request.StartIndex,
|
StartIndex = request.StartIndex,
|
||||||
ChannelIds = new Guid[] { new Guid(request.Id) },
|
ChannelIds = new[] { new Guid(request.Id) },
|
||||||
ParentId = string.IsNullOrWhiteSpace(request.FolderId) ? Guid.Empty : new Guid(request.FolderId),
|
ParentId = string.IsNullOrWhiteSpace(request.FolderId) ? Guid.Empty : new Guid(request.FolderId),
|
||||||
OrderBy = request.GetOrderBy(),
|
OrderBy = request.GetOrderBy(),
|
||||||
DtoOptions = new Controller.Dto.DtoOptions
|
DtoOptions = new Controller.Dto.DtoOptions
|
||||||
|
|
|
@ -155,16 +155,14 @@ namespace MediaBrowser.Api.Devices
|
||||||
Id = id
|
Id = id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
return _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
|
||||||
{
|
{
|
||||||
return _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
|
MimeType = Request.ContentType,
|
||||||
{
|
Album = album,
|
||||||
MimeType = Request.ContentType,
|
Name = name,
|
||||||
Album = album,
|
Id = id
|
||||||
Name = name,
|
});
|
||||||
Id = id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,12 +258,7 @@ namespace MediaBrowser.Api
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request.IncludeDirectories && isDirectory)
|
return request.IncludeDirectories || !isDirectory;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return entries.Select(f => new FileSystemEntryInfo
|
return entries.Select(f => new FileSystemEntryInfo
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Api
|
||||||
// Non recursive not yet supported for library folders
|
// Non recursive not yet supported for library folders
|
||||||
if ((request.Recursive ?? true) || parentItem is UserView || parentItem is ICollectionFolder)
|
if ((request.Recursive ?? true) || parentItem is UserView || parentItem is ICollectionFolder)
|
||||||
{
|
{
|
||||||
genreQuery.AncestorIds = parentItem == null ? Array.Empty<Guid>() : new Guid[] { parentItem.Id };
|
genreQuery.AncestorIds = parentItem == null ? Array.Empty<Guid>() : new[] { parentItem.Id };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -231,7 +231,7 @@ namespace MediaBrowser.Api
|
||||||
EnableTotalRecordCount = false,
|
EnableTotalRecordCount = false,
|
||||||
DtoOptions = new Controller.Dto.DtoOptions
|
DtoOptions = new Controller.Dto.DtoOptions
|
||||||
{
|
{
|
||||||
Fields = new ItemFields[] { ItemFields.Genres, ItemFields.Tags },
|
Fields = new[] { ItemFields.Genres, ItemFields.Tags },
|
||||||
EnableImages = false,
|
EnableImages = false,
|
||||||
EnableUserData = false
|
EnableUserData = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -650,7 +650,7 @@ namespace MediaBrowser.Api.Images
|
||||||
if (!string.IsNullOrWhiteSpace(request.Format)
|
if (!string.IsNullOrWhiteSpace(request.Format)
|
||||||
&& Enum.TryParse(request.Format, true, out ImageFormat format))
|
&& Enum.TryParse(request.Format, true, out ImageFormat format))
|
||||||
{
|
{
|
||||||
return new ImageFormat[] { format };
|
return new[] { format };
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetClientSupportedFormats();
|
return GetClientSupportedFormats();
|
||||||
|
@ -743,24 +743,22 @@ namespace MediaBrowser.Api.Images
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task PostImage(BaseItem entity, Stream inputStream, ImageType imageType, string mimeType)
|
public async Task PostImage(BaseItem entity, Stream inputStream, ImageType imageType, string mimeType)
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(inputStream))
|
using var reader = new StreamReader(inputStream);
|
||||||
|
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
var bytes = Convert.FromBase64String(text);
|
||||||
|
|
||||||
|
var memoryStream = new MemoryStream(bytes)
|
||||||
{
|
{
|
||||||
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
|
Position = 0
|
||||||
|
};
|
||||||
|
|
||||||
var bytes = Convert.FromBase64String(text);
|
// Handle image/png; charset=utf-8
|
||||||
|
mimeType = mimeType.Split(';').FirstOrDefault();
|
||||||
|
|
||||||
var memoryStream = new MemoryStream(bytes)
|
await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
|
||||||
{
|
|
||||||
Position = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle image/png; charset=utf-8
|
entity.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||||
mimeType = mimeType.Split(';').FirstOrDefault();
|
|
||||||
|
|
||||||
await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
|
|
||||||
|
|
||||||
entity.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,27 +261,25 @@ namespace MediaBrowser.Api.Images
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath)
|
private async Task DownloadImage(string url, Guid urlHash, string pointerCachePath)
|
||||||
{
|
{
|
||||||
using (var result = await _httpClient.GetResponse(new HttpRequestOptions
|
using var result = await _httpClient.GetResponse(new HttpRequestOptions
|
||||||
{
|
{
|
||||||
Url = url,
|
Url = url,
|
||||||
BufferContent = false
|
BufferContent = false
|
||||||
|
|
||||||
}).ConfigureAwait(false))
|
}).ConfigureAwait(false);
|
||||||
|
var ext = result.ContentType.Split('/').Last();
|
||||||
|
|
||||||
|
var fullCachePath = GetFullCachePath(urlHash + "." + ext);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
||||||
|
using (var stream = result.Content)
|
||||||
{
|
{
|
||||||
var ext = result.ContentType.Split('/').Last();
|
using var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true);
|
||||||
|
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
||||||
var fullCachePath = GetFullCachePath(urlHash + "." + ext);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
|
||||||
using (var stream = result.Content)
|
|
||||||
using (var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true))
|
|
||||||
{
|
|
||||||
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
|
||||||
File.WriteAllText(pointerCachePath, fullCachePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
||||||
|
File.WriteAllText(pointerCachePath, fullCachePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -305,9 +305,16 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath));
|
||||||
using (var stream = result.Content)
|
using (var stream = result.Content)
|
||||||
using (var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true))
|
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(filestream).ConfigureAwait(false);
|
using var fileStream = new FileStream(
|
||||||
|
fullCachePath,
|
||||||
|
FileMode.Create,
|
||||||
|
FileAccess.Write,
|
||||||
|
FileShare.Read,
|
||||||
|
IODefaults.FileStreamBufferSize,
|
||||||
|
true);
|
||||||
|
|
||||||
|
await stream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath));
|
||||||
|
|
|
@ -263,8 +263,7 @@ namespace MediaBrowser.Api
|
||||||
item.Overview = request.Overview;
|
item.Overview = request.Overview;
|
||||||
item.Genres = request.Genres;
|
item.Genres = request.Genres;
|
||||||
|
|
||||||
var episode = item as Episode;
|
if (item is Episode episode)
|
||||||
if (episode != null)
|
|
||||||
{
|
{
|
||||||
episode.AirsAfterSeasonNumber = request.AirsAfterSeasonNumber;
|
episode.AirsAfterSeasonNumber = request.AirsAfterSeasonNumber;
|
||||||
episode.AirsBeforeEpisodeNumber = request.AirsBeforeEpisodeNumber;
|
episode.AirsBeforeEpisodeNumber = request.AirsBeforeEpisodeNumber;
|
||||||
|
@ -302,14 +301,12 @@ namespace MediaBrowser.Api
|
||||||
item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;
|
item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;
|
||||||
item.PreferredMetadataLanguage = request.PreferredMetadataLanguage;
|
item.PreferredMetadataLanguage = request.PreferredMetadataLanguage;
|
||||||
|
|
||||||
var hasDisplayOrder = item as IHasDisplayOrder;
|
if (item is IHasDisplayOrder hasDisplayOrder)
|
||||||
if (hasDisplayOrder != null)
|
|
||||||
{
|
{
|
||||||
hasDisplayOrder.DisplayOrder = request.DisplayOrder;
|
hasDisplayOrder.DisplayOrder = request.DisplayOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasAspectRatio = item as IHasAspectRatio;
|
if (item is IHasAspectRatio hasAspectRatio)
|
||||||
if (hasAspectRatio != null)
|
|
||||||
{
|
{
|
||||||
hasAspectRatio.AspectRatio = request.AspectRatio;
|
hasAspectRatio.AspectRatio = request.AspectRatio;
|
||||||
}
|
}
|
||||||
|
@ -337,16 +334,14 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
item.ProviderIds = request.ProviderIds;
|
item.ProviderIds = request.ProviderIds;
|
||||||
|
|
||||||
var video = item as Video;
|
if (item is Video video)
|
||||||
if (video != null)
|
|
||||||
{
|
{
|
||||||
video.Video3DFormat = request.Video3DFormat;
|
video.Video3DFormat = request.Video3DFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.AlbumArtists != null)
|
if (request.AlbumArtists != null)
|
||||||
{
|
{
|
||||||
var hasAlbumArtists = item as IHasAlbumArtist;
|
if (item is IHasAlbumArtist hasAlbumArtists)
|
||||||
if (hasAlbumArtists != null)
|
|
||||||
{
|
{
|
||||||
hasAlbumArtists.AlbumArtists = request
|
hasAlbumArtists.AlbumArtists = request
|
||||||
.AlbumArtists
|
.AlbumArtists
|
||||||
|
@ -357,8 +352,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
if (request.ArtistItems != null)
|
if (request.ArtistItems != null)
|
||||||
{
|
{
|
||||||
var hasArtists = item as IHasArtist;
|
if (item is IHasArtist hasArtists)
|
||||||
if (hasArtists != null)
|
|
||||||
{
|
{
|
||||||
hasArtists.Artists = request
|
hasArtists.Artists = request
|
||||||
.ArtistItems
|
.ArtistItems
|
||||||
|
@ -367,20 +361,17 @@ namespace MediaBrowser.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var song = item as Audio;
|
if (item is Audio song)
|
||||||
if (song != null)
|
|
||||||
{
|
{
|
||||||
song.Album = request.Album;
|
song.Album = request.Album;
|
||||||
}
|
}
|
||||||
|
|
||||||
var musicVideo = item as MusicVideo;
|
if (item is MusicVideo musicVideo)
|
||||||
if (musicVideo != null)
|
|
||||||
{
|
{
|
||||||
musicVideo.Album = request.Album;
|
musicVideo.Album = request.Album;
|
||||||
}
|
}
|
||||||
|
|
||||||
var series = item as Series;
|
if (item is Series series)
|
||||||
if (series != null)
|
|
||||||
{
|
{
|
||||||
series.Status = GetSeriesStatus(request);
|
series.Status = GetSeriesStatus(request);
|
||||||
|
|
||||||
|
@ -400,7 +391,6 @@ namespace MediaBrowser.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
return (SeriesStatus)Enum.Parse(typeof(SeriesStatus), item.Status, true);
|
return (SeriesStatus)Enum.Parse(typeof(SeriesStatus), item.Status, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,28 +348,19 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
private string[] GetRepresentativeItemTypes(string contentType)
|
private string[] GetRepresentativeItemTypes(string contentType)
|
||||||
{
|
{
|
||||||
switch (contentType)
|
return contentType switch
|
||||||
{
|
{
|
||||||
case CollectionType.BoxSets:
|
CollectionType.BoxSets => new[] {"BoxSet"},
|
||||||
return new string[] { "BoxSet" };
|
CollectionType.Playlists => new[] {"Playlist"},
|
||||||
case CollectionType.Playlists:
|
CollectionType.Movies => new[] {"Movie"},
|
||||||
return new string[] { "Playlist" };
|
CollectionType.TvShows => new[] {"Series", "Season", "Episode"},
|
||||||
case CollectionType.Movies:
|
CollectionType.Books => new[] {"Book"},
|
||||||
return new string[] { "Movie" };
|
CollectionType.Music => new[] {"MusicAlbum", "MusicArtist", "Audio", "MusicVideo"},
|
||||||
case CollectionType.TvShows:
|
CollectionType.HomeVideos => new[] {"Video", "Photo"},
|
||||||
return new string[] { "Series", "Season", "Episode" };
|
CollectionType.Photos => new[] {"Video", "Photo"},
|
||||||
case CollectionType.Books:
|
CollectionType.MusicVideos => new[] {"MusicVideo"},
|
||||||
return new string[] { "Book" };
|
_ => new[] {"Series", "Season", "Episode", "Movie"}
|
||||||
case CollectionType.Music:
|
};
|
||||||
return new string[] { "MusicAlbum", "MusicArtist", "Audio", "MusicVideo" };
|
|
||||||
case CollectionType.HomeVideos:
|
|
||||||
case CollectionType.Photos:
|
|
||||||
return new string[] { "Video", "Photo" };
|
|
||||||
case CollectionType.MusicVideos:
|
|
||||||
return new string[] { "MusicVideo" };
|
|
||||||
default:
|
|
||||||
return new string[] { "Series", "Season", "Episode", "Movie" };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSaverEnabledByDefault(string name, string[] itemTypes, bool isNewLibrary)
|
private bool IsSaverEnabledByDefault(string name, string[] itemTypes, bool isNewLibrary)
|
||||||
|
@ -397,54 +388,22 @@ namespace MediaBrowser.Api.Library
|
||||||
{
|
{
|
||||||
if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase))
|
return !(string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase)
|
||||||
{
|
|| string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase)
|
||||||
return true;
|
|| string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
|
||||||
if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "The Open Movie Database", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataOptions = ServerConfigurationManager.Configuration.MetadataOptions
|
var metadataOptions = ServerConfigurationManager.Configuration.MetadataOptions
|
||||||
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
|
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
if (metadataOptions.Length == 0)
|
return metadataOptions.Length == 0
|
||||||
{
|
|| metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
|
private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
|
||||||
|
@ -453,50 +412,17 @@ namespace MediaBrowser.Api.Library
|
||||||
{
|
{
|
||||||
if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase))
|
return !string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase)
|
||||||
{
|
&& !string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase)
|
||||||
return false;
|
&& !string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase)
|
||||||
}
|
&& !string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase);
|
||||||
if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "The Open Movie Database", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "Emby Designs", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "Screen Grabber", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "Screen Grabber", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "Emby Designs", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataOptions = ServerConfigurationManager.Configuration.MetadataOptions
|
var metadataOptions = ServerConfigurationManager.Configuration.MetadataOptions
|
||||||
|
@ -561,8 +487,7 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
ImageOption[] defaultImageOptions = null;
|
TypeOptions.DefaultImageOptions.TryGetValue(type, out var defaultImageOptions);
|
||||||
TypeOptions.DefaultImageOptions.TryGetValue(type, out defaultImageOptions);
|
|
||||||
|
|
||||||
typeOptions.Add(new LibraryTypeOptions
|
typeOptions.Add(new LibraryTypeOptions
|
||||||
{
|
{
|
||||||
|
@ -609,8 +534,6 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
public object Get(GetSimilarItems request)
|
public object Get(GetSimilarItems request)
|
||||||
{
|
{
|
||||||
var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
|
|
||||||
|
|
||||||
var item = string.IsNullOrEmpty(request.Id) ?
|
var item = string.IsNullOrEmpty(request.Id) ?
|
||||||
(!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
|
(!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
|
||||||
_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
|
_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
|
||||||
|
@ -668,7 +591,7 @@ namespace MediaBrowser.Api.Library
|
||||||
// ExcludeArtistIds
|
// ExcludeArtistIds
|
||||||
if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
|
if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
|
||||||
{
|
{
|
||||||
query.ExcludeArtistIds = BaseApiService.GetGuids(request.ExcludeArtistIds);
|
query.ExcludeArtistIds = GetGuids(request.ExcludeArtistIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BaseItem> itemsResult;
|
List<BaseItem> itemsResult;
|
||||||
|
@ -689,7 +612,6 @@ namespace MediaBrowser.Api.Library
|
||||||
var result = new QueryResult<BaseItemDto>
|
var result = new QueryResult<BaseItemDto>
|
||||||
{
|
{
|
||||||
Items = returnList,
|
Items = returnList,
|
||||||
|
|
||||||
TotalRecordCount = itemsResult.Count
|
TotalRecordCount = itemsResult.Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -919,12 +841,10 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
private BaseItem TranslateParentItem(BaseItem item, User user)
|
private BaseItem TranslateParentItem(BaseItem item, User user)
|
||||||
{
|
{
|
||||||
if (item.GetParent() is AggregateFolder)
|
return item.GetParent() is AggregateFolder
|
||||||
{
|
? _libraryManager.GetUserRootFolder().GetChildren(user, true)
|
||||||
return _libraryManager.GetUserRootFolder().GetChildren(user, true).FirstOrDefault(i => i.PhysicalLocations.Contains(item.Path));
|
.FirstOrDefault(i => i.PhysicalLocations.Contains(item.Path))
|
||||||
}
|
: item;
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1086,7 +1006,7 @@ namespace MediaBrowser.Api.Library
|
||||||
var item = string.IsNullOrEmpty(request.Id)
|
var item = string.IsNullOrEmpty(request.Id)
|
||||||
? (!request.UserId.Equals(Guid.Empty)
|
? (!request.UserId.Equals(Guid.Empty)
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: (Folder)_libraryManager.RootFolder)
|
: _libraryManager.RootFolder)
|
||||||
: _libraryManager.GetItemById(request.Id);
|
: _libraryManager.GetItemById(request.Id);
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -1094,18 +1014,13 @@ namespace MediaBrowser.Api.Library
|
||||||
throw new ResourceNotFoundException("Item not found.");
|
throw new ResourceNotFoundException("Item not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseItem[] themeItems = Array.Empty<BaseItem>();
|
IEnumerable<BaseItem> themeItems;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
themeItems = item.GetThemeSongs().ToArray();
|
themeItems = item.GetThemeSongs();
|
||||||
|
|
||||||
if (themeItems.Length > 0)
|
if (themeItems.Any() || !request.InheritFromParent)
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!request.InheritFromParent)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1119,11 +1034,9 @@ namespace MediaBrowser.Api.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(_authContext, request);
|
var dtoOptions = GetDtoOptions(_authContext, request);
|
||||||
|
var items = themeItems
|
||||||
var dtos = themeItems
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
.ToArray();
|
||||||
|
|
||||||
var items = dtos.ToArray();
|
|
||||||
|
|
||||||
return new ThemeMediaResult
|
return new ThemeMediaResult
|
||||||
{
|
{
|
||||||
|
@ -1140,9 +1053,7 @@ namespace MediaBrowser.Api.Library
|
||||||
/// <returns>System.Object.</returns>
|
/// <returns>System.Object.</returns>
|
||||||
public object Get(GetThemeVideos request)
|
public object Get(GetThemeVideos request)
|
||||||
{
|
{
|
||||||
var result = GetThemeVideos(request);
|
return ToOptimizedResult(GetThemeVideos(request));
|
||||||
|
|
||||||
return ToOptimizedResult(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThemeMediaResult GetThemeVideos(GetThemeVideos request)
|
public ThemeMediaResult GetThemeVideos(GetThemeVideos request)
|
||||||
|
@ -1152,7 +1063,7 @@ namespace MediaBrowser.Api.Library
|
||||||
var item = string.IsNullOrEmpty(request.Id)
|
var item = string.IsNullOrEmpty(request.Id)
|
||||||
? (!request.UserId.Equals(Guid.Empty)
|
? (!request.UserId.Equals(Guid.Empty)
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: (Folder)_libraryManager.RootFolder)
|
: _libraryManager.RootFolder)
|
||||||
: _libraryManager.GetItemById(request.Id);
|
: _libraryManager.GetItemById(request.Id);
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -1160,18 +1071,13 @@ namespace MediaBrowser.Api.Library
|
||||||
throw new ResourceNotFoundException("Item not found.");
|
throw new ResourceNotFoundException("Item not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseItem[] themeItems = Array.Empty<BaseItem>();
|
IEnumerable<BaseItem> themeItems;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
themeItems = item.GetThemeVideos().ToArray();
|
themeItems = item.GetThemeVideos();
|
||||||
|
|
||||||
if (themeItems.Length > 0)
|
if (themeItems.Any() || !request.InheritFromParent)
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!request.InheritFromParent)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1186,10 +1092,9 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(_authContext, request);
|
var dtoOptions = GetDtoOptions(_authContext, request);
|
||||||
|
|
||||||
var dtos = themeItems
|
var items = themeItems
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
||||||
|
.ToArray();
|
||||||
var items = dtos.ToArray();
|
|
||||||
|
|
||||||
return new ThemeMediaResult
|
return new ThemeMediaResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -327,15 +327,11 @@ namespace MediaBrowser.Api.Library
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var mediaPath = request.PathInfo;
|
var mediaPath = request.PathInfo ?? new MediaPathInfo
|
||||||
|
|
||||||
if (mediaPath == null)
|
|
||||||
{
|
{
|
||||||
mediaPath = new MediaPathInfo
|
Path = request.Path
|
||||||
{
|
};
|
||||||
Path = request.Path
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_libraryManager.AddMediaPath(request.Name, mediaPath);
|
_libraryManager.AddMediaPath(request.Name, mediaPath);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -885,11 +885,10 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
{
|
{
|
||||||
// SchedulesDirect requires a SHA1 hash of the user's password
|
// SchedulesDirect requires a SHA1 hash of the user's password
|
||||||
// https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-a-token
|
// https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#obtain-a-token
|
||||||
using (SHA1 sha = SHA1.Create())
|
using SHA1 sha = SHA1.Create();
|
||||||
{
|
|
||||||
return Hex.Encode(
|
return Hex.Encode(
|
||||||
sha.ComputeHash(Encoding.UTF8.GetBytes(str)));
|
sha.ComputeHash(Encoding.UTF8.GetBytes(str)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(DeleteListingProvider request)
|
public void Delete(DeleteListingProvider request)
|
||||||
|
@ -1050,8 +1049,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
{
|
{
|
||||||
query.IsSeries = true;
|
query.IsSeries = true;
|
||||||
|
|
||||||
var series = _libraryManager.GetItemById(request.LibrarySeriesId) as Series;
|
if (_libraryManager.GetItemById(request.LibrarySeriesId) is Series series)
|
||||||
if (series != null)
|
|
||||||
{
|
{
|
||||||
query.Name = series.Name;
|
query.Name = series.Name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,7 +394,7 @@ namespace MediaBrowser.Api.Movies
|
||||||
{
|
{
|
||||||
var people = _libraryManager.GetPeople(new InternalPeopleQuery
|
var people = _libraryManager.GetPeople(new InternalPeopleQuery
|
||||||
{
|
{
|
||||||
PersonTypes = new string[]
|
PersonTypes = new[]
|
||||||
{
|
{
|
||||||
PersonType.Director
|
PersonType.Director
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,12 +137,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
var ext = outputFileExtension.ToLowerInvariant();
|
var ext = outputFileExtension.ToLowerInvariant();
|
||||||
var folder = ServerConfigurationManager.GetTranscodePath();
|
var folder = ServerConfigurationManager.GetTranscodePath();
|
||||||
|
|
||||||
if (EnableOutputInSubFolder)
|
return EnableOutputInSubFolder
|
||||||
{
|
? Path.Combine(folder, filename, filename + ext)
|
||||||
return Path.Combine(folder, filename, filename + ext);
|
: Path.Combine(folder, filename + ext);
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(folder, filename + ext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual string GetDefaultEncoderPreset()
|
protected virtual string GetDefaultEncoderPreset()
|
||||||
|
@ -248,14 +245,8 @@ namespace MediaBrowser.Api.Playback
|
||||||
if (state.VideoRequest != null
|
if (state.VideoRequest != null
|
||||||
&& string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
logFilePrefix = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)
|
||||||
{
|
? "ffmpeg-remux" : "ffmpeg-directstream";
|
||||||
logFilePrefix = "ffmpeg-remux";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logFilePrefix = "ffmpeg-directstream";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
|
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
|
||||||
|
@ -389,195 +380,181 @@ namespace MediaBrowser.Api.Playback
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0)
|
switch (i)
|
||||||
{
|
{
|
||||||
request.DeviceProfileId = val;
|
case 0:
|
||||||
}
|
request.DeviceProfileId = val;
|
||||||
else if (i == 1)
|
break;
|
||||||
{
|
case 1:
|
||||||
request.DeviceId = val;
|
request.DeviceId = val;
|
||||||
}
|
break;
|
||||||
else if (i == 2)
|
case 2:
|
||||||
{
|
request.MediaSourceId = val;
|
||||||
request.MediaSourceId = val;
|
break;
|
||||||
}
|
case 3:
|
||||||
else if (i == 3)
|
request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
{
|
break;
|
||||||
request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
case 4:
|
||||||
}
|
if (videoRequest != null)
|
||||||
else if (i == 4)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.VideoCodec = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 5)
|
|
||||||
{
|
|
||||||
request.AudioCodec = val;
|
|
||||||
}
|
|
||||||
else if (i == 6)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.AudioStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 7)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.SubtitleStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 8)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.VideoBitRate = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 9)
|
|
||||||
{
|
|
||||||
request.AudioBitRate = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
else if (i == 10)
|
|
||||||
{
|
|
||||||
request.MaxAudioChannels = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
else if (i == 11)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.MaxFramerate = float.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 12)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.MaxWidth = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 13)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.MaxHeight = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 14)
|
|
||||||
{
|
|
||||||
request.StartTimeTicks = long.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
else if (i == 15)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.Level = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 16)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.MaxRefFrames = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 17)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.MaxVideoBitDepth = int.Parse(val, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 18)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.Profile = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 19)
|
|
||||||
{
|
|
||||||
// cabac no longer used
|
|
||||||
}
|
|
||||||
else if (i == 20)
|
|
||||||
{
|
|
||||||
request.PlaySessionId = val;
|
|
||||||
}
|
|
||||||
else if (i == 21)
|
|
||||||
{
|
|
||||||
// api_key
|
|
||||||
}
|
|
||||||
else if (i == 22)
|
|
||||||
{
|
|
||||||
request.LiveStreamId = val;
|
|
||||||
}
|
|
||||||
else if (i == 23)
|
|
||||||
{
|
|
||||||
// Duplicating ItemId because of MediaMonkey
|
|
||||||
}
|
|
||||||
else if (i == 24)
|
|
||||||
{
|
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
|
||||||
videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (i == 25)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
|
|
||||||
{
|
|
||||||
if (Enum.TryParse(val, out SubtitleDeliveryMethod method))
|
|
||||||
{
|
{
|
||||||
videoRequest.SubtitleMethod = method;
|
videoRequest.VideoCodec = val;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
break;
|
||||||
else if (i == 26)
|
case 5:
|
||||||
{
|
request.AudioCodec = val;
|
||||||
request.TranscodingMaxAudioChannels = int.Parse(val, CultureInfo.InvariantCulture);
|
break;
|
||||||
}
|
case 6:
|
||||||
else if (i == 27)
|
if (videoRequest != null)
|
||||||
{
|
{
|
||||||
if (videoRequest != null)
|
videoRequest.AudioStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
{
|
}
|
||||||
videoRequest.EnableSubtitlesInManifest = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
break;
|
||||||
}
|
case 7:
|
||||||
else if (i == 28)
|
if (videoRequest != null)
|
||||||
{
|
{
|
||||||
request.Tag = val;
|
videoRequest.SubtitleStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
else if (i == 29)
|
|
||||||
{
|
break;
|
||||||
if (videoRequest != null)
|
case 8:
|
||||||
{
|
if (videoRequest != null)
|
||||||
videoRequest.RequireAvc = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
{
|
||||||
}
|
videoRequest.VideoBitRate = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
else if (i == 30)
|
|
||||||
{
|
break;
|
||||||
request.SubtitleCodec = val;
|
case 9:
|
||||||
}
|
request.AudioBitRate = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
else if (i == 31)
|
break;
|
||||||
{
|
case 10:
|
||||||
if (videoRequest != null)
|
request.MaxAudioChannels = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
{
|
break;
|
||||||
videoRequest.RequireNonAnamorphic = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
case 11:
|
||||||
}
|
if (videoRequest != null)
|
||||||
}
|
{
|
||||||
else if (i == 32)
|
videoRequest.MaxFramerate = float.Parse(val, CultureInfo.InvariantCulture);
|
||||||
{
|
}
|
||||||
if (videoRequest != null)
|
|
||||||
{
|
break;
|
||||||
videoRequest.DeInterlace = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
case 12:
|
||||||
}
|
if (videoRequest != null)
|
||||||
}
|
{
|
||||||
else if (i == 33)
|
videoRequest.MaxWidth = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
{
|
}
|
||||||
request.TranscodeReasons = val;
|
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.MaxHeight = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
request.StartTimeTicks = long.Parse(val, CultureInfo.InvariantCulture);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.Level = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.MaxRefFrames = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.MaxVideoBitDepth = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.Profile = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
// cabac no longer used
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
request.PlaySessionId = val;
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
// api_key
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
request.LiveStreamId = val;
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
// Duplicating ItemId because of MediaMonkey
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
|
||||||
|
{
|
||||||
|
if (Enum.TryParse(val, out SubtitleDeliveryMethod method))
|
||||||
|
{
|
||||||
|
videoRequest.SubtitleMethod = method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
request.TranscodingMaxAudioChannels = int.Parse(val, CultureInfo.InvariantCulture);
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.EnableSubtitlesInManifest = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
request.Tag = val;
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.RequireAvc = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
request.SubtitleCodec = val;
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.RequireNonAnamorphic = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
if (videoRequest != null)
|
||||||
|
{
|
||||||
|
videoRequest.DeInterlace = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
request.TranscodeReasons = val;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,14 +607,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
throw new ArgumentException("Invalid timeseek header");
|
throw new ArgumentException("Invalid timeseek header");
|
||||||
}
|
}
|
||||||
int index = value.IndexOf('-');
|
int index = value.IndexOf('-');
|
||||||
if (index == -1)
|
value = index == -1
|
||||||
{
|
? value.Substring(Npt.Length)
|
||||||
value = value.Substring(Npt.Length);
|
: value.Substring(Npt.Length, index - Npt.Length);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = value.Substring(Npt.Length, index - Npt.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.IndexOf(':') == -1)
|
if (value.IndexOf(':') == -1)
|
||||||
{
|
{
|
||||||
|
@ -856,21 +828,11 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
state.DeviceProfile = DlnaManager.GetProfile(state.Request.DeviceProfileId);
|
state.DeviceProfile = DlnaManager.GetProfile(state.Request.DeviceProfileId);
|
||||||
}
|
}
|
||||||
else
|
else if (!string.IsNullOrWhiteSpace(state.Request.DeviceId))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(state.Request.DeviceId))
|
var caps = DeviceManager.GetCapabilities(state.Request.DeviceId);
|
||||||
{
|
|
||||||
var caps = DeviceManager.GetCapabilities(state.Request.DeviceId);
|
|
||||||
|
|
||||||
if (caps != null)
|
state.DeviceProfile = caps == null ? DlnaManager.GetProfile(headers) : caps.DeviceProfile;
|
||||||
{
|
|
||||||
state.DeviceProfile = caps.DeviceProfile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.DeviceProfile = DlnaManager.GetProfile(headers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var profile = state.DeviceProfile;
|
var profile = state.DeviceProfile;
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
if (isLive)
|
if (isLive)
|
||||||
{
|
{
|
||||||
job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType);
|
job ??= ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType);
|
||||||
|
|
||||||
if (job != null)
|
if (job != null)
|
||||||
{
|
{
|
||||||
|
@ -156,7 +156,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
var playlistText = GetMasterPlaylistFileText(playlist, videoBitrate + audioBitrate, baselineStreamBitrate);
|
var playlistText = GetMasterPlaylistFileText(playlist, videoBitrate + audioBitrate, baselineStreamBitrate);
|
||||||
|
|
||||||
job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType);
|
job ??= ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType);
|
||||||
|
|
||||||
if (job != null)
|
if (job != null)
|
||||||
{
|
{
|
||||||
|
@ -168,22 +168,19 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
private string GetLivePlaylistText(string path, int segmentLength)
|
private string GetLivePlaylistText(string path, int segmentLength)
|
||||||
{
|
{
|
||||||
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
{
|
using var reader = new StreamReader(stream);
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
var text = reader.ReadToEnd();
|
|
||||||
|
|
||||||
text = text.Replace("#EXTM3U", "#EXTM3U\n#EXT-X-PLAYLIST-TYPE:EVENT");
|
var text = reader.ReadToEnd();
|
||||||
|
|
||||||
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(CultureInfo.InvariantCulture);
|
text = text.Replace("#EXTM3U", "#EXTM3U\n#EXT-X-PLAYLIST-TYPE:EVENT");
|
||||||
|
|
||||||
text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength - 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(CultureInfo.InvariantCulture);
|
||||||
//text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
return text;
|
text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength - 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
//text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetMasterPlaylistFileText(string firstPlaylist, int bitrate, int baselineStreamBitrate)
|
private string GetMasterPlaylistFileText(string firstPlaylist, int bitrate, int baselineStreamBitrate)
|
||||||
|
@ -212,29 +209,25 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
|
// Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
|
||||||
using (var fileStream = GetPlaylistFileStream(playlist))
|
using var fileStream = GetPlaylistFileStream(playlist);
|
||||||
|
using var reader = new StreamReader(fileStream);
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
while (!reader.EndOfStream)
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(fileStream))
|
var line = reader.ReadLine();
|
||||||
|
|
||||||
|
if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
{
|
||||||
var count = 0;
|
count++;
|
||||||
|
if (count >= segmentCount)
|
||||||
while (!reader.EndOfStream)
|
|
||||||
{
|
{
|
||||||
var line = reader.ReadLine();
|
Logger.LogDebug("Finished waiting for {0} segments in {1}", segmentCount, playlist);
|
||||||
|
return;
|
||||||
if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
if (count >= segmentCount)
|
|
||||||
{
|
|
||||||
Logger.LogDebug("Finished waiting for {0} segments in {1}", segmentCount, playlist);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
|
@ -247,17 +240,13 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
protected Stream GetPlaylistFileStream(string path)
|
protected Stream GetPlaylistFileStream(string path)
|
||||||
{
|
{
|
||||||
var tmpPath = path + ".tmp";
|
return new FileStream(
|
||||||
tmpPath = path;
|
path,
|
||||||
|
FileMode.Open,
|
||||||
try
|
FileAccess.Read,
|
||||||
{
|
FileShare.ReadWrite,
|
||||||
return new FileStream(tmpPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, FileOptions.SequentialScan);
|
IODefaults.FileStreamBufferSize,
|
||||||
}
|
FileOptions.SequentialScan);
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, FileOptions.SequentialScan);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string GetCommandLineArguments(string outputPath, EncodingOptions encodingOptions, StreamState state, bool isEncoding)
|
protected override string GetCommandLineArguments(string outputPath, EncodingOptions encodingOptions, StreamState state, bool isEncoding)
|
||||||
|
|
|
@ -284,7 +284,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Logger.LogDebug("returning {0} [general case]", segmentPath);
|
Logger.LogDebug("returning {0} [general case]", segmentPath);
|
||||||
job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
job ??= ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||||
return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, requestedIndex, job, cancellationToken).ConfigureAwait(false);
|
return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, requestedIndex, job, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,8 +438,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
var segmentId = "0";
|
var segmentId = "0";
|
||||||
|
|
||||||
var segmentRequest = request as GetHlsVideoSegment;
|
if (request is GetHlsVideoSegment segmentRequest)
|
||||||
if (segmentRequest != null)
|
|
||||||
{
|
{
|
||||||
segmentId = segmentRequest.SegmentId;
|
segmentId = segmentRequest.SegmentId;
|
||||||
}
|
}
|
||||||
|
@ -690,8 +689,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = state.Request as IMasterHlsRequest;
|
if (state.Request is IMasterHlsRequest request && !request.EnableAdaptiveBitrateStreaming)
|
||||||
if (request != null && !request.EnableAdaptiveBitrateStreaming)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -936,7 +934,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
|
|
||||||
var framerate = state.VideoStream?.RealFrameRate;
|
var framerate = state.VideoStream?.RealFrameRate;
|
||||||
|
|
||||||
if (framerate != null && framerate.HasValue)
|
if (framerate.HasValue)
|
||||||
{
|
{
|
||||||
// This is to make sure keyframe interval is limited to our segment,
|
// This is to make sure keyframe interval is limited to our segment,
|
||||||
// as forcing keyframes is not enough.
|
// as forcing keyframes is not enough.
|
||||||
|
|
|
@ -234,7 +234,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
OpenToken = mediaSource.OpenToken
|
OpenToken = mediaSource.OpenToken
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
info.MediaSources = new MediaSourceInfo[] { openStreamResult.MediaSource };
|
info.MediaSources = new[] { openStreamResult.MediaSource };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
var mediaSource = await _mediaSourceManager.GetLiveStream(liveStreamId, CancellationToken.None).ConfigureAwait(false);
|
var mediaSource = await _mediaSourceManager.GetLiveStream(liveStreamId, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
mediaSources = new MediaSourceInfo[] { mediaSource };
|
mediaSources = new[] { mediaSource };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaSources.Length == 0)
|
if (mediaSources.Length == 0)
|
||||||
|
@ -366,7 +366,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
var options = new VideoOptions
|
var options = new VideoOptions
|
||||||
{
|
{
|
||||||
MediaSources = new MediaSourceInfo[] { mediaSource },
|
MediaSources = new[] { mediaSource },
|
||||||
Context = EncodingContext.Streaming,
|
Context = EncodingContext.Streaming,
|
||||||
DeviceId = auth.DeviceId,
|
DeviceId = auth.DeviceId,
|
||||||
ItemId = item.Id,
|
ItemId = item.Id,
|
||||||
|
@ -583,7 +583,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
private long? GetMaxBitrate(long? clientMaxBitrate, User user)
|
private long? GetMaxBitrate(long? clientMaxBitrate, User user)
|
||||||
{
|
{
|
||||||
var maxBitrate = clientMaxBitrate;
|
var maxBitrate = clientMaxBitrate;
|
||||||
var remoteClientMaxBitrate = user == null ? 0 : user.Policy.RemoteClientBitrateLimit;
|
var remoteClientMaxBitrate = user?.Policy.RemoteClientBitrateLimit ?? 0;
|
||||||
|
|
||||||
if (remoteClientMaxBitrate <= 0)
|
if (remoteClientMaxBitrate <= 0)
|
||||||
{
|
{
|
||||||
|
@ -662,17 +662,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
};
|
};
|
||||||
}).ThenBy(i =>
|
}).ThenBy(i =>
|
||||||
{
|
{
|
||||||
if (maxBitrate.HasValue)
|
if (maxBitrate.HasValue && i.Bitrate.HasValue)
|
||||||
{
|
{
|
||||||
if (i.Bitrate.HasValue)
|
return i.Bitrate.Value <= maxBitrate.Value ? 0 : 2;
|
||||||
{
|
|
||||||
if (i.Bitrate.Value <= maxBitrate.Value)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -167,7 +167,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
AudioCodec = request.AudioCodec,
|
AudioCodec = request.AudioCodec,
|
||||||
Protocol = request.TranscodingProtocol,
|
Protocol = request.TranscodingProtocol,
|
||||||
BreakOnNonKeyFrames = request.BreakOnNonKeyFrames,
|
BreakOnNonKeyFrames = request.BreakOnNonKeyFrames,
|
||||||
MaxAudioChannels = request.TranscodingAudioChannels.HasValue ? request.TranscodingAudioChannels.Value.ToString(CultureInfo.InvariantCulture) : null
|
MaxAudioChannels = request.TranscodingAudioChannels?.ToString(CultureInfo.InvariantCulture)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
// hls segment container can only be mpegts or fmp4 per ffmpeg documentation
|
// hls segment container can only be mpegts or fmp4 per ffmpeg documentation
|
||||||
// TODO: remove this when we switch back to the segment muxer
|
// TODO: remove this when we switch back to the segment muxer
|
||||||
var supportedHLSContainers = new string[] { "mpegts", "fmp4" };
|
var supportedHLSContainers = new[] { "mpegts", "fmp4" };
|
||||||
|
|
||||||
var newRequest = new GetMasterHlsAudioPlaylist
|
var newRequest = new GetMasterHlsAudioPlaylist
|
||||||
{
|
{
|
||||||
|
|
|
@ -243,9 +243,7 @@ namespace MediaBrowser.Api
|
||||||
// https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
|
// https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
|
||||||
var id = Guid.Parse(GetPathValue(1));
|
var id = Guid.Parse(GetPathValue(1));
|
||||||
|
|
||||||
var plugin = _appHost.Plugins.First(p => p.Id == id) as IHasPluginConfiguration;
|
if (!(_appHost.Plugins.First(p => p.Id == id) is IHasPluginConfiguration plugin))
|
||||||
|
|
||||||
if (plugin == null)
|
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,9 +123,7 @@ namespace MediaBrowser.Api.ScheduledTasks
|
||||||
{
|
{
|
||||||
var isHidden = false;
|
var isHidden = false;
|
||||||
|
|
||||||
var configurableTask = i.ScheduledTask as IConfigurableScheduledTask;
|
if (i.ScheduledTask is IConfigurableScheduledTask configurableTask)
|
||||||
|
|
||||||
if (configurableTask != null)
|
|
||||||
{
|
{
|
||||||
isHidden = configurableTask.IsHidden;
|
isHidden = configurableTask.IsHidden;
|
||||||
}
|
}
|
||||||
|
@ -142,9 +140,7 @@ namespace MediaBrowser.Api.ScheduledTasks
|
||||||
{
|
{
|
||||||
var isEnabled = true;
|
var isEnabled = true;
|
||||||
|
|
||||||
var configurableTask = i.ScheduledTask as IConfigurableScheduledTask;
|
if (i.ScheduledTask is IConfigurableScheduledTask configurableTask)
|
||||||
|
|
||||||
if (configurableTask != null)
|
|
||||||
{
|
{
|
||||||
isEnabled = configurableTask.IsEnabled;
|
isEnabled = configurableTask.IsEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,59 +234,48 @@ namespace MediaBrowser.Api
|
||||||
SetThumbImageInfo(result, item);
|
SetThumbImageInfo(result, item);
|
||||||
SetBackdropImageInfo(result, item);
|
SetBackdropImageInfo(result, item);
|
||||||
|
|
||||||
var program = item as LiveTvProgram;
|
switch (item)
|
||||||
if (program != null)
|
|
||||||
{
|
{
|
||||||
result.StartDate = program.StartDate;
|
case IHasSeries hasSeries:
|
||||||
}
|
result.Series = hasSeries.SeriesName;
|
||||||
|
break;
|
||||||
|
case LiveTvProgram program:
|
||||||
|
result.StartDate = program.StartDate;
|
||||||
|
break;
|
||||||
|
case Series series:
|
||||||
|
if (series.Status.HasValue)
|
||||||
|
{
|
||||||
|
result.Status = series.Status.Value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
var hasSeries = item as IHasSeries;
|
break;
|
||||||
if (hasSeries != null)
|
case MusicAlbum album:
|
||||||
{
|
result.Artists = album.Artists;
|
||||||
result.Series = hasSeries.SeriesName;
|
result.AlbumArtist = album.AlbumArtist;
|
||||||
}
|
break;
|
||||||
|
case Audio song:
|
||||||
|
result.AlbumArtist = song.AlbumArtists.FirstOrDefault();
|
||||||
|
result.Artists = song.Artists;
|
||||||
|
|
||||||
var series = item as Series;
|
MusicAlbum musicAlbum = song.AlbumEntity;
|
||||||
if (series != null)
|
|
||||||
{
|
|
||||||
if (series.Status.HasValue)
|
|
||||||
{
|
|
||||||
result.Status = series.Status.Value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var album = item as MusicAlbum;
|
if (musicAlbum != null)
|
||||||
|
{
|
||||||
|
result.Album = musicAlbum.Name;
|
||||||
|
result.AlbumId = musicAlbum.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Album = song.Album;
|
||||||
|
}
|
||||||
|
|
||||||
if (album != null)
|
break;
|
||||||
{
|
|
||||||
result.Artists = album.Artists;
|
|
||||||
result.AlbumArtist = album.AlbumArtist;
|
|
||||||
}
|
|
||||||
|
|
||||||
var song = item as Audio;
|
|
||||||
|
|
||||||
if (song != null)
|
|
||||||
{
|
|
||||||
result.AlbumArtist = song.AlbumArtists.FirstOrDefault();
|
|
||||||
result.Artists = song.Artists;
|
|
||||||
|
|
||||||
album = song.AlbumEntity;
|
|
||||||
|
|
||||||
if (album != null)
|
|
||||||
{
|
|
||||||
result.Album = album.Name;
|
|
||||||
result.AlbumId = album.Id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Album = song.Album;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.ChannelId.Equals(Guid.Empty))
|
if (!item.ChannelId.Equals(Guid.Empty))
|
||||||
{
|
{
|
||||||
var channel = _libraryManager.GetItemById(item.ChannelId);
|
var channel = _libraryManager.GetItemById(item.ChannelId);
|
||||||
result.ChannelName = channel == null ? null : channel.Name;
|
result.ChannelName = channel?.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -296,12 +285,9 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
var itemWithImage = item.HasImage(ImageType.Thumb) ? item : null;
|
var itemWithImage = item.HasImage(ImageType.Thumb) ? item : null;
|
||||||
|
|
||||||
if (itemWithImage == null)
|
if (itemWithImage == null && item is Episode)
|
||||||
{
|
{
|
||||||
if (item is Episode)
|
itemWithImage = GetParentWithImage<Series>(item, ImageType.Thumb);
|
||||||
{
|
|
||||||
itemWithImage = GetParentWithImage<Series>(item, ImageType.Thumb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemWithImage == null)
|
if (itemWithImage == null)
|
||||||
|
@ -323,12 +309,8 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
private void SetBackdropImageInfo(SearchHint hint, BaseItem item)
|
private void SetBackdropImageInfo(SearchHint hint, BaseItem item)
|
||||||
{
|
{
|
||||||
var itemWithImage = item.HasImage(ImageType.Backdrop) ? item : null;
|
var itemWithImage = (item.HasImage(ImageType.Backdrop) ? item : null)
|
||||||
|
?? GetParentWithImage<BaseItem>(item, ImageType.Backdrop);
|
||||||
if (itemWithImage == null)
|
|
||||||
{
|
|
||||||
itemWithImage = GetParentWithImage<BaseItem>(item, ImageType.Backdrop);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemWithImage != null)
|
if (itemWithImage != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -230,17 +230,14 @@ namespace MediaBrowser.Api.Subtitles
|
||||||
|
|
||||||
if (string.Equals(request.Format, "vtt", StringComparison.OrdinalIgnoreCase) && request.AddVttTimeMap)
|
if (string.Equals(request.Format, "vtt", StringComparison.OrdinalIgnoreCase) && request.AddVttTimeMap)
|
||||||
{
|
{
|
||||||
using (var stream = await GetSubtitles(request).ConfigureAwait(false))
|
using var stream = await GetSubtitles(request).ConfigureAwait(false);
|
||||||
{
|
using var reader = new StreamReader(stream);
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
var text = reader.ReadToEnd();
|
|
||||||
|
|
||||||
text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000");
|
var text = reader.ReadToEnd();
|
||||||
|
|
||||||
return ResultFactory.GetResult(Request, text, MimeTypes.GetMimeType("file." + request.Format));
|
text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000");
|
||||||
}
|
|
||||||
}
|
return ResultFactory.GetResult(Request, text, MimeTypes.GetMimeType("file." + request.Format));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultFactory.GetResult(Request, await GetSubtitles(request).ConfigureAwait(false), MimeTypes.GetMimeType("file." + request.Format));
|
return ResultFactory.GetResult(Request, await GetSubtitles(request).ConfigureAwait(false), MimeTypes.GetMimeType("file." + request.Format));
|
||||||
|
|
|
@ -168,12 +168,9 @@ namespace MediaBrowser.Api.System
|
||||||
.First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));
|
.First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
// For older files, assume fully static
|
// For older files, assume fully static
|
||||||
if (file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1))
|
var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;
|
||||||
{
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.Read);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite);
|
return ResultFactory.GetStaticFileResult(Request, file.FullName, fileShare);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -92,10 +92,7 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
lock (_timerLock)
|
lock (_timerLock)
|
||||||
{
|
{
|
||||||
if (KillTimer != null)
|
KillTimer?.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
{
|
|
||||||
KillTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -424,9 +424,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(request.SeasonId))
|
if (!string.IsNullOrWhiteSpace(request.SeasonId))
|
||||||
{
|
{
|
||||||
var season = _libraryManager.GetItemById(new Guid(request.SeasonId)) as Season;
|
if (!(_libraryManager.GetItemById(new Guid(request.SeasonId)) is Season season))
|
||||||
|
|
||||||
if (season == null)
|
|
||||||
{
|
{
|
||||||
throw new ResourceNotFoundException("No season exists with Id " + request.SeasonId);
|
throw new ResourceNotFoundException("No season exists with Id " + request.SeasonId);
|
||||||
}
|
}
|
||||||
|
@ -444,14 +442,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
var season = series.GetSeasons(user, dtoOptions).FirstOrDefault(i => i.IndexNumber == request.Season.Value);
|
var season = series.GetSeasons(user, dtoOptions).FirstOrDefault(i => i.IndexNumber == request.Season.Value);
|
||||||
|
|
||||||
if (season == null)
|
episodes = season == null ? new List<BaseItem>() : ((Season)season).GetEpisodes(user, dtoOptions);
|
||||||
{
|
|
||||||
episodes = new List<BaseItem>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
episodes = ((Season)season).GetEpisodes(user, dtoOptions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,12 +126,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
|
|
||||||
protected override QueryResult<(BaseItem, ItemCounts)> GetItems(GetItemsByName request, InternalItemsQuery query)
|
protected override QueryResult<(BaseItem, ItemCounts)> GetItems(GetItemsByName request, InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (request is GetAlbumArtists)
|
return request is GetAlbumArtists ? LibraryManager.GetAlbumArtists(query) : LibraryManager.GetArtists(query);
|
||||||
{
|
|
||||||
return LibraryManager.GetAlbumArtists(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
return LibraryManager.GetArtists(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -82,8 +82,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
{
|
{
|
||||||
var parent = GetParentItem(request);
|
var parent = GetParentItem(request);
|
||||||
|
|
||||||
var collectionFolder = parent as IHasCollectionType;
|
if (parent is IHasCollectionType collectionFolder)
|
||||||
if (collectionFolder != null)
|
|
||||||
{
|
{
|
||||||
return collectionFolder.CollectionType;
|
return collectionFolder.CollectionType;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +273,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
DtoOptions = dtoOptions
|
DtoOptions = dtoOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
Func<BaseItem, bool> filter = i => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes);
|
bool Filter(BaseItem i) => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes);
|
||||||
|
|
||||||
if (parentItem.IsFolder)
|
if (parentItem.IsFolder)
|
||||||
{
|
{
|
||||||
|
@ -284,18 +283,18 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
{
|
{
|
||||||
items = request.Recursive ?
|
items = request.Recursive ?
|
||||||
folder.GetRecursiveChildren(user, query).ToList() :
|
folder.GetRecursiveChildren(user, query).ToList() :
|
||||||
folder.GetChildren(user, true).Where(filter).ToList();
|
folder.GetChildren(user, true).Where(Filter).ToList();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
items = request.Recursive ?
|
items = request.Recursive ?
|
||||||
folder.GetRecursiveChildren(filter) :
|
folder.GetRecursiveChildren(Filter) :
|
||||||
folder.Children.Where(filter).ToList();
|
folder.Children.Where(Filter).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
items = new[] { parentItem }.Where(filter).ToList();
|
items = new[] { parentItem }.Where(Filter).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var extractedItems = GetAllItems(request, items);
|
var extractedItems = GetAllItems(request, items);
|
||||||
|
@ -346,30 +345,21 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
private bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
|
private bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes)
|
||||||
{
|
{
|
||||||
// Exclude item types
|
// Exclude item types
|
||||||
if (excludeItemTypes.Length > 0)
|
if (excludeItemTypes.Length > 0 && excludeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (excludeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include item types
|
// Include item types
|
||||||
if (includeItemTypes.Length > 0)
|
if (includeItemTypes.Length > 0 && !includeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!includeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include MediaTypes
|
// Include MediaTypes
|
||||||
if (mediaTypes.Length > 0)
|
if (mediaTypes.Length > 0 && !mediaTypes.Contains(f.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!mediaTypes.Contains(f.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -396,12 +396,10 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
|
|
||||||
public VideoType[] GetVideoTypes()
|
public VideoType[] GetVideoTypes()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(VideoTypes))
|
return string.IsNullOrEmpty(VideoTypes)
|
||||||
{
|
? Array.Empty<VideoType>()
|
||||||
return Array.Empty<VideoType>();
|
: VideoTypes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
}
|
.Select(v => Enum.Parse<VideoType>(v, true)).ToArray();
|
||||||
|
|
||||||
return VideoTypes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (VideoType)Enum.Parse(typeof(VideoType), v, true)).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -412,12 +410,10 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
{
|
{
|
||||||
var val = Filters;
|
var val = Filters;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(val))
|
return string.IsNullOrEmpty(val)
|
||||||
{
|
? Array.Empty<ItemFilter>()
|
||||||
return new ItemFilter[] { };
|
: val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
}
|
.Select(v => Enum.Parse<ItemFilter>(v, true)).ToArray();
|
||||||
|
|
||||||
return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true)).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -428,12 +424,9 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
{
|
{
|
||||||
var val = ImageTypes;
|
var val = ImageTypes;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(val))
|
return string.IsNullOrEmpty(val)
|
||||||
{
|
? Array.Empty<ImageType>()
|
||||||
return new ImageType[] { };
|
: val.Split(',').Select(v => Enum.Parse<ImageType>(v, true)).ToArray();
|
||||||
}
|
|
||||||
|
|
||||||
return val.Split(',').Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -469,7 +462,9 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
var sortOrderIndex = sortOrders.Length > i ? i : 0;
|
var sortOrderIndex = sortOrders.Length > i ? i : 0;
|
||||||
|
|
||||||
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
|
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
|
||||||
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase) ? MediaBrowser.Model.Entities.SortOrder.Descending : MediaBrowser.Model.Entities.SortOrder.Ascending;
|
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? MediaBrowser.Model.Entities.SortOrder.Descending
|
||||||
|
: MediaBrowser.Model.Entities.SortOrder.Ascending;
|
||||||
|
|
||||||
result[i] = new ValueTuple<string, SortOrder>(vals[i], sortOrder);
|
result[i] = new ValueTuple<string, SortOrder>(vals[i], sortOrder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,14 +199,12 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
item = _libraryManager.GetUserRootFolder();
|
item = _libraryManager.GetUserRootFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder folder = item as Folder;
|
if (!(item is Folder folder))
|
||||||
if (folder == null)
|
|
||||||
{
|
{
|
||||||
folder = _libraryManager.GetUserRootFolder();
|
folder = _libraryManager.GetUserRootFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasCollectionType = folder as IHasCollectionType;
|
if (folder is IHasCollectionType hasCollectionType
|
||||||
if (hasCollectionType != null
|
|
||||||
&& string.Equals(hasCollectionType.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(hasCollectionType.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
request.Recursive = true;
|
request.Recursive = true;
|
||||||
|
|
|
@ -139,17 +139,11 @@ namespace MediaBrowser.Api
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var primaryVersion = videosWithVersions.FirstOrDefault();
|
var primaryVersion = videosWithVersions.FirstOrDefault();
|
||||||
|
|
||||||
if (primaryVersion == null)
|
if (primaryVersion == null)
|
||||||
{
|
{
|
||||||
primaryVersion = items.OrderBy(i =>
|
primaryVersion = items.OrderBy(i =>
|
||||||
{
|
{
|
||||||
if (i.Video3DFormat.HasValue)
|
if (i.Video3DFormat.HasValue || i.VideoType != Model.Entities.VideoType.VideoFile)
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i.VideoType != Model.Entities.VideoType.VideoFile)
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -158,10 +152,7 @@ namespace MediaBrowser.Api
|
||||||
})
|
})
|
||||||
.ThenByDescending(i =>
|
.ThenByDescending(i =>
|
||||||
{
|
{
|
||||||
var stream = i.GetDefaultVideoStream();
|
return i.GetDefaultVideoStream()?.Width ?? 0;
|
||||||
|
|
||||||
return stream == null || stream.Width == null ? 0 : stream.Width.Value;
|
|
||||||
|
|
||||||
}).First();
|
}).First();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue