commit
308f60855a
|
@ -12,6 +12,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.TV;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.Xml;
|
||||
|
||||
|
@ -31,6 +32,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
private readonly IUserViewManager _userViewManager;
|
||||
private readonly Func<IMediaEncoder> _mediaEncoder;
|
||||
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
|
||||
private readonly ITVSeriesManager _tvSeriesManager;
|
||||
|
||||
public ContentDirectory(IDlnaManager dlna,
|
||||
IUserDataManager userDataManager,
|
||||
|
@ -39,7 +41,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
IServerConfigurationManager config,
|
||||
IUserManager userManager,
|
||||
ILogger logger,
|
||||
IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func<IMediaEncoder> mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
|
||||
IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func<IMediaEncoder> mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager)
|
||||
: base(logger, httpClient)
|
||||
{
|
||||
_dlna = dlna;
|
||||
|
@ -54,6 +56,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
_userViewManager = userViewManager;
|
||||
_mediaEncoder = mediaEncoder;
|
||||
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
|
||||
_tvSeriesManager = tvSeriesManager;
|
||||
}
|
||||
|
||||
private int SystemUpdateId
|
||||
|
@ -97,7 +100,8 @@ namespace Emby.Dlna.ContentDirectory
|
|||
_mediaSourceManager,
|
||||
_userViewManager,
|
||||
_mediaEncoder(),
|
||||
XmlReaderSettingsFactory)
|
||||
XmlReaderSettingsFactory,
|
||||
_tvSeriesManager)
|
||||
.ProcessControlRequest(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ using MediaBrowser.Controller.Dto;
|
|||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Controller.TV;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.Xml;
|
||||
|
||||
|
@ -40,6 +41,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
private readonly IServerConfigurationManager _config;
|
||||
private readonly User _user;
|
||||
private readonly IUserViewManager _userViewManager;
|
||||
private readonly ITVSeriesManager _tvSeriesManager;
|
||||
|
||||
private const string NS_DC = "http://purl.org/dc/elements/1.1/";
|
||||
private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/";
|
||||
|
@ -53,7 +55,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
|
||||
private readonly DeviceProfile _profile;
|
||||
|
||||
public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
|
||||
public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager)
|
||||
: base(config, logger, xmlReaderSettingsFactory)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
|
@ -62,6 +64,7 @@ namespace Emby.Dlna.ContentDirectory
|
|||
_systemUpdateId = systemUpdateId;
|
||||
_channelManager = channelManager;
|
||||
_userViewManager = userViewManager;
|
||||
_tvSeriesManager = tvSeriesManager;
|
||||
_profile = profile;
|
||||
_config = config;
|
||||
|
||||
|
@ -488,6 +491,14 @@ namespace Emby.Dlna.ContentDirectory
|
|||
{
|
||||
return GetMusicFolders(item, user, stubType, sort, startIndex, limit);
|
||||
}
|
||||
if (collectionFolder != null && string.Equals(CollectionType.Movies, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return GetMovieFolders(item, user, stubType, sort, startIndex, limit);
|
||||
}
|
||||
if (collectionFolder != null && string.Equals(CollectionType.TvShows, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return GetTvFolders(item, user, stubType, sort, startIndex, limit);
|
||||
}
|
||||
|
||||
if (stubType.HasValue)
|
||||
{
|
||||
|
@ -656,6 +667,231 @@ namespace Emby.Dlna.ContentDirectory
|
|||
};
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit)
|
||||
{
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
StartIndex = startIndex,
|
||||
Limit = limit
|
||||
};
|
||||
SetSorting(query, sort, false);
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.ContinueWatching)
|
||||
{
|
||||
return GetMovieContinueWatching(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Latest)
|
||||
{
|
||||
return GetMovieLatest(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Movies)
|
||||
{
|
||||
return GetMovieMovies(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Collections)
|
||||
{
|
||||
return GetMovieCollections(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Favorites)
|
||||
{
|
||||
return GetMovieFavorites(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Genres)
|
||||
{
|
||||
return GetGenres(item, user, query);
|
||||
}
|
||||
|
||||
var list = new List<ServerItem>();
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.ContinueWatching
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Latest
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Movies
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Collections
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Favorites
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Genres
|
||||
});
|
||||
|
||||
return new QueryResult<ServerItem>
|
||||
{
|
||||
Items = list.ToArray(),
|
||||
TotalRecordCount = list.Count
|
||||
};
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetTvFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit)
|
||||
{
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
StartIndex = startIndex,
|
||||
Limit = limit
|
||||
};
|
||||
SetSorting(query, sort, false);
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.ContinueWatching)
|
||||
{
|
||||
return GetMovieContinueWatching(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.NextUp)
|
||||
{
|
||||
return GetNextUp(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Latest)
|
||||
{
|
||||
return GetTvLatest(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Series)
|
||||
{
|
||||
return GetSeries(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.FavoriteSeries)
|
||||
{
|
||||
return GetFavoriteSeries(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.FavoriteEpisodes)
|
||||
{
|
||||
return GetFavoriteEpisodes(item, user, query);
|
||||
}
|
||||
|
||||
if (stubType.HasValue && stubType.Value == StubType.Genres)
|
||||
{
|
||||
return GetGenres(item, user, query);
|
||||
}
|
||||
|
||||
var list = new List<ServerItem>();
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.ContinueWatching
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.NextUp
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Latest
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Series
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.FavoriteSeries
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.FavoriteEpisodes
|
||||
});
|
||||
|
||||
list.Add(new ServerItem(item)
|
||||
{
|
||||
StubType = StubType.Genres
|
||||
});
|
||||
|
||||
return new QueryResult<ServerItem>
|
||||
{
|
||||
Items = list.ToArray(),
|
||||
TotalRecordCount = list.Count
|
||||
};
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieContinueWatching(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
|
||||
query.OrderBy = new List<Tuple<string, SortOrder>>
|
||||
{
|
||||
new Tuple<string, SortOrder> (ItemSortBy.DatePlayed, SortOrder.Descending),
|
||||
new Tuple<string, SortOrder> (ItemSortBy.SortName, SortOrder.Ascending)
|
||||
};
|
||||
|
||||
query.IsResumable = true;
|
||||
query.Limit = 10;
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetSeries(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
|
||||
query.IncludeItemTypes = new[] { typeof(Series).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieMovies(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
|
||||
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieCollections(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
//query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
|
||||
query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMusicAlbums(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
|
@ -695,6 +931,45 @@ namespace Emby.Dlna.ContentDirectory
|
|||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetFavoriteSeries(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
query.IsFavorite = true;
|
||||
query.IncludeItemTypes = new[] { typeof(Series).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetFavoriteEpisodes(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
query.IsFavorite = true;
|
||||
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieFavorites(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.Parent = parent;
|
||||
query.SetUser(user);
|
||||
query.IsFavorite = true;
|
||||
query.IncludeItemTypes = new[] { typeof(Movie).Name };
|
||||
|
||||
var result = _libraryManager.GetItemsResult(query);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetFavoriteAlbums(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
|
@ -708,6 +983,24 @@ namespace Emby.Dlna.ContentDirectory
|
|||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetGenres(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
var genresResult = _libraryManager.GetGenres(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorIds = new[] { parent.Id.ToString("N") },
|
||||
StartIndex = query.StartIndex,
|
||||
Limit = query.Limit
|
||||
});
|
||||
|
||||
var result = new QueryResult<BaseItem>
|
||||
{
|
||||
TotalRecordCount = genresResult.TotalRecordCount,
|
||||
Items = genresResult.Items.Select(i => i.Item1).ToArray()
|
||||
};
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMusicGenres(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
var genresResult = _libraryManager.GetMusicGenres(new InternalItemsQuery(user)
|
||||
|
@ -810,6 +1103,55 @@ namespace Emby.Dlna.ContentDirectory
|
|||
return ToResult(items);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.SortBy = new string[] { };
|
||||
|
||||
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
|
||||
{
|
||||
Limit = query.Limit,
|
||||
StartIndex = query.StartIndex,
|
||||
UserId = query.User.Id.ToString("N")
|
||||
|
||||
}, new List<Folder> { (Folder)parent }, query.DtoOptions);
|
||||
|
||||
return ToResult(result);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.SortBy = new string[] { };
|
||||
|
||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
||||
{
|
||||
UserId = user.Id.ToString("N"),
|
||||
Limit = 50,
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name },
|
||||
ParentId = parent == null ? null : parent.Id.ToString("N"),
|
||||
GroupItems = true
|
||||
|
||||
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToList();
|
||||
|
||||
return ToResult(items);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.SortBy = new string[] { };
|
||||
|
||||
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
|
||||
{
|
||||
UserId = user.Id.ToString("N"),
|
||||
Limit = 50,
|
||||
IncludeItemTypes = new[] { typeof(Movie).Name },
|
||||
ParentId = parent == null ? null : parent.Id.ToString("N"),
|
||||
GroupItems = true
|
||||
|
||||
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToList();
|
||||
|
||||
return ToResult(items);
|
||||
}
|
||||
|
||||
private QueryResult<ServerItem> GetMusicArtistItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit)
|
||||
{
|
||||
var query = new InternalItemsQuery(user)
|
||||
|
@ -942,65 +1284,16 @@ namespace Emby.Dlna.ContentDirectory
|
|||
id = parts[23];
|
||||
}
|
||||
|
||||
if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase))
|
||||
var enumNames = Enum.GetNames(typeof(StubType));
|
||||
foreach (var name in enumNames)
|
||||
{
|
||||
stubType = StubType.Folder;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("people_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.People;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("latest_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Latest;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("playlists_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Playlists;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("Albums_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Albums;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("AlbumArtists_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.AlbumArtists;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("Artists_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Artists;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("Genres_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Genres;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("Songs_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.Songs;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("FavoriteAlbums_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.FavoriteAlbums;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("FavoriteArtists_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.FavoriteArtists;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
}
|
||||
else if (id.StartsWith("FavoriteSongs_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = StubType.FavoriteSongs;
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
if (id.StartsWith(name + "_", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
stubType = (StubType)Enum.Parse(typeof(StubType), name, true);
|
||||
id = id.Split(new[] { '_' }, 2)[1];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Guid.TryParse(id, out itemId))
|
||||
|
@ -1048,6 +1341,14 @@ namespace Emby.Dlna.ContentDirectory
|
|||
Genres = 8,
|
||||
FavoriteSongs = 9,
|
||||
FavoriteArtists = 10,
|
||||
FavoriteAlbums = 11
|
||||
FavoriteAlbums = 11,
|
||||
ContinueWatching = 12,
|
||||
Movies = 13,
|
||||
Collections = 14,
|
||||
Favorites = 15,
|
||||
NextUp = 16,
|
||||
Series = 17,
|
||||
FavoriteSeries = 18,
|
||||
FavoriteEpisodes = 19
|
||||
}
|
||||
}
|
||||
|
|
|
@ -439,6 +439,38 @@ namespace Emby.Dlna.Didl
|
|||
{
|
||||
return _localization.GetLocalizedString("ViewTypeMusicFavoriteSongs");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.ContinueWatching)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeMovieResume");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.Movies)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeMovieMovies");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.Collections)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeMovieCollections");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.Favorites)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeMovieFavorites");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.NextUp)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeTvNextUp");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSeries)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeTvFavoriteSeries");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteEpisodes)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeTvFavoriteEpisodes");
|
||||
}
|
||||
if (itemStubType.HasValue && itemStubType.Value == StubType.Series)
|
||||
{
|
||||
return _localization.GetLocalizedString("ViewTypeTvShowSeries");
|
||||
}
|
||||
|
||||
var episode = item as Episode;
|
||||
var season = context as Season;
|
||||
|
|
|
@ -667,7 +667,7 @@ namespace Emby.Server.Core
|
|||
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
|
||||
RegisterSingleInstance(UserViewManager);
|
||||
|
||||
var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder, new XmlReaderSettingsFactory());
|
||||
var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder, new XmlReaderSettingsFactory(), TVSeriesManager);
|
||||
RegisterSingleInstance<IContentDirectory>(contentDirectory);
|
||||
|
||||
var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager, new XmlReaderSettingsFactory());
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"ViewTypeTvResume": "Resume",
|
||||
"ViewTypeTvNextUp": "Next Up",
|
||||
"ViewTypeTvLatest": "Latest",
|
||||
"ViewTypeTvShowSeries": "Series",
|
||||
"ViewTypeTvShowSeries": "Shows",
|
||||
"ViewTypeTvGenres": "Genres",
|
||||
"ViewTypeTvFavoriteSeries": "Favorite Series",
|
||||
"ViewTypeTvFavoriteEpisodes": "Favorite Episodes",
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace Emby.Server.Implementations.MediaEncoder
|
|||
|
||||
var container = video.Container;
|
||||
|
||||
var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
|
||||
var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.GetDefaultVideoStream(), video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
|
||||
_fileSystem.CopyFile(tempFile, path, true);
|
||||
|
||||
try
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace MediaBrowser.Api.Playback
|
|||
LibraryManager = libraryManager;
|
||||
IsoManager = isoManager;
|
||||
MediaEncoder = mediaEncoder;
|
||||
EncodingHelper = new EncodingHelper(MediaEncoder, serverConfig, FileSystem, SubtitleEncoder);
|
||||
EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
@ -19,14 +18,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
private readonly IMediaEncoder _mediaEncoder;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ISubtitleEncoder _subtitleEncoder;
|
||||
|
||||
public EncodingHelper(IMediaEncoder mediaEncoder, IServerConfigurationManager config, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder)
|
||||
public EncodingHelper(IMediaEncoder mediaEncoder, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder)
|
||||
{
|
||||
_mediaEncoder = mediaEncoder;
|
||||
_config = config;
|
||||
_fileSystem = fileSystem;
|
||||
_subtitleEncoder = subtitleEncoder;
|
||||
}
|
||||
|
@ -1771,29 +1768,34 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
return null;
|
||||
}
|
||||
|
||||
return GetVideoDecoder(state.MediaSource.VideoType ?? VideoType.VideoFile, state.VideoStream, encodingOptions);
|
||||
}
|
||||
|
||||
public string GetVideoDecoder(VideoType videoType, MediaStream videoStream, EncodingOptions encodingOptions)
|
||||
{
|
||||
// Only use alternative encoders for video files.
|
||||
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
||||
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
||||
if (state.VideoType != VideoType.VideoFile)
|
||||
if (videoType != VideoType.VideoFile)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (state.VideoStream != null &&
|
||||
!string.IsNullOrWhiteSpace(state.VideoStream.Codec) &&
|
||||
if (videoStream != null &&
|
||||
!string.IsNullOrWhiteSpace(videoStream.Codec) &&
|
||||
!string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) &&
|
||||
encodingOptions.EnableHardwareDecoding)
|
||||
{
|
||||
if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
switch (state.MediaSource.VideoStream.Codec.ToLower())
|
||||
switch (videoStream.Codec.ToLower())
|
||||
{
|
||||
case "avc":
|
||||
case "h264":
|
||||
if (_mediaEncoder.SupportsDecoder("h264_qsv"))
|
||||
{
|
||||
// qsv decoder does not support 10-bit input
|
||||
if ((state.VideoStream.BitDepth ?? 8) > 8)
|
||||
if ((videoStream.BitDepth ?? 8) > 8)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -1824,7 +1826,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
|
||||
else if (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
switch (state.MediaSource.VideoStream.Codec.ToLower())
|
||||
switch (videoStream.Codec.ToLower())
|
||||
{
|
||||
case "avc":
|
||||
case "h264":
|
||||
|
|
|
@ -39,29 +39,16 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
/// <summary>
|
||||
/// Extracts the video image.
|
||||
/// </summary>
|
||||
/// <param name="inputFiles">The input files.</param>
|
||||
/// <param name="protocol">The protocol.</param>
|
||||
/// <param name="threedFormat">The threed format.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||
|
||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken);
|
||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the video images on interval.
|
||||
/// </summary>
|
||||
/// <param name="inputFiles">The input files.</param>
|
||||
/// <param name="protocol">The protocol.</param>
|
||||
/// <param name="threedFormat">The threed format.</param>
|
||||
/// <param name="interval">The interval.</param>
|
||||
/// <param name="targetDirectory">The target directory.</param>
|
||||
/// <param name="filenamePrefix">The filename prefix.</param>
|
||||
/// <param name="maxWidth">The maximum width.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
||||
string container,
|
||||
MediaStream videoStream,
|
||||
MediaProtocol protocol,
|
||||
Video3DFormat? threedFormat,
|
||||
TimeSpan interval,
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
MediaSourceManager = mediaSourceManager;
|
||||
ProcessFactory = processFactory;
|
||||
|
||||
EncodingHelper = new EncodingHelper(MediaEncoder, ConfigurationManager, FileSystem, SubtitleEncoder);
|
||||
EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder);
|
||||
}
|
||||
|
||||
public async Task<EncodingJob> Start(EncodingJobOptions options,
|
||||
|
|
|
@ -615,20 +615,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
|
||||
public Task<string> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken)
|
||||
{
|
||||
return ExtractImage(new[] { path }, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
|
||||
return ExtractImage(new[] { path }, null, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||
{
|
||||
return ExtractImage(inputFiles, container, null, protocol, false, threedFormat, offset, cancellationToken);
|
||||
return ExtractImage(inputFiles, container, videoStream, null, protocol, false, threedFormat, offset, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken)
|
||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken)
|
||||
{
|
||||
return ExtractImage(inputFiles, container, imageStreamIndex, protocol, false, null, null, cancellationToken);
|
||||
return ExtractImage(inputFiles, container, imageStream, imageStreamIndex, protocol, false, null, null, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<string> ExtractImage(string[] inputFiles, string container, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
|
||||
private async Task<string> ExtractImage(string[] inputFiles, string container, MediaStream videoStream, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
|
||||
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||
{
|
||||
var inputArgument = GetInputArgument(inputFiles, protocol);
|
||||
|
@ -645,7 +645,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
{
|
||||
try
|
||||
{
|
||||
return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, true, cancellationToken).ConfigureAwait(false);
|
||||
return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
|
@ -657,10 +657,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
}
|
||||
}
|
||||
|
||||
return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, false, cancellationToken).ConfigureAwait(false);
|
||||
return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<string> ExtractImageInternal(string inputPath, string container, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken)
|
||||
private async Task<string> ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int? imageStreamIndex, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(inputPath))
|
||||
{
|
||||
|
@ -726,6 +726,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args;
|
||||
}
|
||||
|
||||
var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder());
|
||||
if (videoStream != null)
|
||||
{
|
||||
var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
|
||||
if (!string.IsNullOrWhiteSpace(decoder))
|
||||
{
|
||||
args = decoder + " " + args;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(container))
|
||||
{
|
||||
var inputFormat = encodinghelper.GetInputFormat(container);
|
||||
if (!string.IsNullOrWhiteSpace(inputFormat))
|
||||
{
|
||||
args = "-f " + inputFormat + " " + args;
|
||||
}
|
||||
}
|
||||
|
||||
var process = _processFactory.Create(new ProcessOptions
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
|
@ -786,6 +805,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
}
|
||||
|
||||
public async Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
||||
string container,
|
||||
MediaStream videoStream,
|
||||
MediaProtocol protocol,
|
||||
Video3DFormat? threedFormat,
|
||||
TimeSpan interval,
|
||||
|
@ -825,6 +846,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
args = analyzeDurationArgument + " " + args;
|
||||
}
|
||||
|
||||
var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder());
|
||||
if (videoStream != null)
|
||||
{
|
||||
var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
|
||||
if (!string.IsNullOrWhiteSpace(decoder))
|
||||
{
|
||||
args = decoder + " " + args;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(container))
|
||||
{
|
||||
var inputFormat = encodinghelper.GetInputFormat(container);
|
||||
if (!string.IsNullOrWhiteSpace(inputFormat))
|
||||
{
|
||||
args = "-f " + inputFormat + " " + args;
|
||||
}
|
||||
}
|
||||
|
||||
var process = _processFactory.Create(new ProcessOptions
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace MediaBrowser.Model.Dto
|
|||
{
|
||||
foreach (MediaStream i in MediaStreams)
|
||||
{
|
||||
if (i.Type == MediaStreamType.Video && StringHelper.IndexOfIgnoreCase(i.Codec ?? string.Empty, "jpeg") == -1)
|
||||
if (i.Type == MediaStreamType.Video)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
}
|
||||
}
|
||||
|
||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoIndex, cancellationToken).ConfigureAwait(false);
|
||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, imageStream, videoIndex, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -144,7 +144,9 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
|
||||
: TimeSpan.FromSeconds(10);
|
||||
|
||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
||||
var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
|
||||
|
||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return new DynamicImageResponse
|
||||
|
|
|
@ -60,10 +60,15 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
movie.SetProviderId(MetadataProviders.TmdbCollection, tmdbcolid);
|
||||
}
|
||||
|
||||
var val = reader.ReadElementContentAsString();
|
||||
var val = reader.ReadInnerXml();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val) && movie != null)
|
||||
{
|
||||
movie.CollectionName = val;
|
||||
// TODO Handle this better later
|
||||
if (val.IndexOf('<') == -1)
|
||||
{
|
||||
movie.CollectionName = val;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common</id>
|
||||
<version>3.0.709</version>
|
||||
<version>3.0.710</version>
|
||||
<title>Emby.Common</title>
|
||||
<authors>Emby Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Server.Core</id>
|
||||
<version>3.0.709</version>
|
||||
<version>3.0.710</version>
|
||||
<title>Emby.Server.Core</title>
|
||||
<authors>Emby Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains core components required to build plugins for Emby Server.</description>
|
||||
<copyright>Copyright © Emby 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.709" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.710" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("3.2.26.11")]
|
||||
[assembly: AssemblyVersion("3.2.26.12")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user