mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-06 10:22:04 +01:00
Merge branch 'dev' of https://github.com/MediaBrowser/MediaBrowser into dev
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using ServiceStack;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Api
|
||||
{
|
||||
@@ -52,7 +54,14 @@ namespace MediaBrowser.Api
|
||||
|
||||
var options = GetRefreshOptions(request);
|
||||
|
||||
_providerManager.QueueRefresh(item.Id, options);
|
||||
if (item is Folder)
|
||||
{
|
||||
_providerManager.QueueRefresh(item.Id, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
_providerManager.RefreshFullItem(item, options, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
|
||||
private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request)
|
||||
|
||||
@@ -591,7 +591,7 @@ namespace MediaBrowser.Api.Library
|
||||
ThemeSongsResult = themeSongs,
|
||||
ThemeVideosResult = themeVideos,
|
||||
|
||||
SoundtrackSongsResult = GetSoundtrackSongs(request, request.Id, request.UserId, request.InheritFromParent)
|
||||
SoundtrackSongsResult = new ThemeMediaResult()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -789,53 +789,5 @@ namespace MediaBrowser.Api.Library
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(lookup);
|
||||
}
|
||||
|
||||
public ThemeMediaResult GetSoundtrackSongs(GetThemeMedia request, string id, Guid? userId, bool inheritFromParent)
|
||||
{
|
||||
var user = userId.HasValue ? _userManager.GetUserById(userId.Value) : null;
|
||||
|
||||
var item = string.IsNullOrEmpty(id)
|
||||
? (userId.HasValue
|
||||
? user.RootFolder
|
||||
: _libraryManager.RootFolder)
|
||||
: _libraryManager.GetItemById(id);
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var dtos = GetSoundtrackSongIds(item, inheritFromParent)
|
||||
.Select(_libraryManager.GetItemById)
|
||||
.OfType<MusicAlbum>()
|
||||
.SelectMany(i => i.GetRecursiveChildren(a => a is Audio))
|
||||
.OrderBy(i => i.SortName)
|
||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
||||
|
||||
var items = dtos.ToArray();
|
||||
|
||||
return new ThemeMediaResult
|
||||
{
|
||||
Items = items,
|
||||
TotalRecordCount = items.Length,
|
||||
OwnerId = _dtoService.GetDtoId(item)
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<Guid> GetSoundtrackSongIds(BaseItem item, bool inherit)
|
||||
{
|
||||
var hasSoundtracks = item as IHasSoundtracks;
|
||||
|
||||
if (hasSoundtracks != null)
|
||||
{
|
||||
return hasSoundtracks.SoundtrackIds;
|
||||
}
|
||||
|
||||
if (!inherit)
|
||||
{
|
||||
return new List<Guid>();
|
||||
}
|
||||
|
||||
hasSoundtracks = item.Parents.OfType<IHasSoundtracks>().FirstOrDefault();
|
||||
|
||||
return hasSoundtracks != null ? hasSoundtracks.SoundtrackIds : new List<Guid>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +62,15 @@ namespace MediaBrowser.Api.Movies
|
||||
|
||||
public async Task<object> Post(CreateCollection request)
|
||||
{
|
||||
var userId = AuthorizationContext.GetAuthorizationInfo(Request).UserId;
|
||||
|
||||
var item = await _collectionManager.CreateCollection(new CollectionCreationOptions
|
||||
{
|
||||
IsLocked = request.IsLocked,
|
||||
Name = request.Name,
|
||||
ParentId = request.ParentId,
|
||||
ItemIdList = (request.Ids ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList()
|
||||
ItemIdList = (request.Ids ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(),
|
||||
UserIds = new List<Guid> { new Guid(userId) }
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -1522,6 +1522,10 @@ namespace MediaBrowser.Api.Playback
|
||||
{
|
||||
request.LiveStreamId = val;
|
||||
}
|
||||
else if (i == 24)
|
||||
{
|
||||
// Duplicating ItemId because of MediaMonkey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2029,8 +2033,6 @@ namespace MediaBrowser.Api.Playback
|
||||
profile.GetVideoMediaProfile(state.OutputContainer,
|
||||
audioCodec,
|
||||
videoCodec,
|
||||
state.OutputAudioBitrate,
|
||||
state.OutputAudioChannels,
|
||||
state.OutputWidth,
|
||||
state.OutputHeight,
|
||||
state.TargetVideoBitDepth,
|
||||
@@ -2117,8 +2119,6 @@ namespace MediaBrowser.Api.Playback
|
||||
state.OutputHeight,
|
||||
state.TargetVideoBitDepth,
|
||||
state.OutputVideoBitrate,
|
||||
state.OutputAudioBitrate,
|
||||
state.OutputAudioChannels,
|
||||
state.TargetTimestamp,
|
||||
isStaticallyStreamed,
|
||||
state.RunTimeTicks,
|
||||
|
||||
@@ -159,10 +159,12 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
{
|
||||
var text = reader.ReadToEnd();
|
||||
|
||||
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(UsCulture) + Environment.NewLine + "#EXT-X-ALLOW-CACHE:NO";
|
||||
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(UsCulture);
|
||||
|
||||
// ffmpeg pads the reported length by a full second
|
||||
return text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(UsCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
||||
text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(UsCulture), newDuration, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,7 +608,6 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
builder.AppendLine("#EXT-X-VERSION:3");
|
||||
builder.AppendLine("#EXT-X-TARGETDURATION:" + state.SegmentLength.ToString(UsCulture));
|
||||
builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
|
||||
builder.AppendLine("#EXT-X-ALLOW-CACHE:NO");
|
||||
|
||||
var queryStringIndex = Request.RawUrl.IndexOf('?');
|
||||
var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex);
|
||||
|
||||
@@ -18,16 +18,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Api.Playback
|
||||
{
|
||||
[Route("/Items/{Id}/MediaInfo", "GET", Summary = "Gets live playback media info for an item")]
|
||||
public class GetLiveMediaInfo : IReturn<PlaybackInfoResponse>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
|
||||
public class GetPlaybackInfo : IReturn<PlaybackInfoResponse>
|
||||
{
|
||||
@@ -55,6 +45,19 @@ namespace MediaBrowser.Api.Playback
|
||||
public string LiveStreamId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Playback/BitrateTest", "GET")]
|
||||
public class GetBitrateTestBytes : IReturn<PlaybackInfoResponse>
|
||||
{
|
||||
[ApiMember(Name = "Size", Description = "Size", IsRequired = true, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public long Size { get; set; }
|
||||
|
||||
public GetBitrateTestBytes()
|
||||
{
|
||||
// 100k
|
||||
Size = 102400;
|
||||
}
|
||||
}
|
||||
|
||||
[Authenticated]
|
||||
public class MediaInfoService : BaseApiService
|
||||
{
|
||||
@@ -73,13 +76,19 @@ namespace MediaBrowser.Api.Playback
|
||||
_networkManager = networkManager;
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetPlaybackInfo request)
|
||||
public object Get(GetBitrateTestBytes request)
|
||||
{
|
||||
var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false);
|
||||
return ToOptimizedResult(result);
|
||||
var bytes = new byte[request.Size];
|
||||
|
||||
for (var i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes[i] = 0;
|
||||
}
|
||||
|
||||
return ResultFactory.GetResult(bytes, "application/octet-stream");
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetLiveMediaInfo request)
|
||||
public async Task<object> Get(GetPlaybackInfo request)
|
||||
{
|
||||
var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false);
|
||||
return ToOptimizedResult(result);
|
||||
@@ -325,10 +334,11 @@ namespace MediaBrowser.Api.Playback
|
||||
private int? GetMaxBitrate(int? clientMaxBitrate)
|
||||
{
|
||||
var maxBitrate = clientMaxBitrate;
|
||||
var remoteClientMaxBitrate = _config.Configuration.RemoteClientBitrateLimit;
|
||||
|
||||
if (_config.Configuration.RemoteClientBitrateLimit > 0 && !_networkManager.IsInLocalNetwork(Request.RemoteIp))
|
||||
if (remoteClientMaxBitrate > 0 && !_networkManager.IsInLocalNetwork(Request.RemoteIp))
|
||||
{
|
||||
maxBitrate = Math.Min(maxBitrate ?? _config.Configuration.RemoteClientBitrateLimit, _config.Configuration.RemoteClientBitrateLimit);
|
||||
maxBitrate = Math.Min(maxBitrate ?? remoteClientMaxBitrate, remoteClientMaxBitrate);
|
||||
}
|
||||
|
||||
return maxBitrate;
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace MediaBrowser.Api
|
||||
_config.Configuration.EnableStandaloneMetadata = true;
|
||||
_config.Configuration.EnableLibraryMetadataSubFolder = true;
|
||||
_config.Configuration.EnableUserSpecificUserViews = true;
|
||||
_config.Configuration.EnableCustomPathSubFolders = true;
|
||||
_config.SaveConfiguration();
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace MediaBrowser.Api.Subtitles
|
||||
}
|
||||
|
||||
[Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")]
|
||||
[Authenticated]
|
||||
public class GetSubtitlePlaylist
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Sync;
|
||||
@@ -230,6 +231,11 @@ namespace MediaBrowser.Api.Sync
|
||||
{
|
||||
var jobItem = _syncManager.GetJobItem(request.Id);
|
||||
|
||||
if (jobItem == null)
|
||||
{
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
if (jobItem.Status < SyncJobItemStatus.ReadyToTransfer)
|
||||
{
|
||||
throw new ArgumentException("The job item is not yet ready for transfer.");
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
|
||||
[ApiMember(Name = "StudioIds", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string StudioIds { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the studios.
|
||||
/// </summary>
|
||||
@@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
|
||||
[ApiMember(Name = "ArtistIds", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string ArtistIds { get; set; }
|
||||
|
||||
|
||||
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Albums { get; set; }
|
||||
|
||||
@@ -622,7 +622,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager)
|
||||
{
|
||||
var video = i as Video;
|
||||
|
||||
|
||||
if (!isPreFiltered)
|
||||
{
|
||||
var mediaTypes = request.GetMediaTypes();
|
||||
@@ -979,8 +979,8 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Apply person filter
|
||||
var personIds = request.GetPersonIds();
|
||||
if (personIds.Length > 0)
|
||||
@@ -1057,7 +1057,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
// Artists
|
||||
if (!string.IsNullOrEmpty(request.ArtistIds))
|
||||
{
|
||||
var artistIds = request.ArtistIds.Split('|');
|
||||
var artistIds = request.ArtistIds.Split(new[] { '|', ',' });
|
||||
|
||||
var audio = i as IHasArtist;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user