diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 49bf9e39c5..fbd97b6a23 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -1415,66 +1415,69 @@ namespace Emby.Server.Implementations.Data
var index = 5;
- var hasProgramAttributes = item as IHasProgramAttributes;
- if (hasProgramAttributes != null)
+ if (HasProgramAttributes(query))
{
- if (!reader.IsDBNull(index))
+ var hasProgramAttributes = item as IHasProgramAttributes;
+ if (hasProgramAttributes != null)
{
- hasProgramAttributes.IsMovie = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsMovie = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsSports = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsSports = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsKids = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsKids = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsSeries = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsSeries = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsLive = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsLive = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsNews = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsNews = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.IsPremiere = reader.GetBoolean(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsPremiere = reader.GetBoolean(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
- {
- hasProgramAttributes.EpisodeTitle = reader.GetString(index);
- }
- index++;
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.EpisodeTitle = reader.GetString(index);
+ }
+ index++;
- if (!reader.IsDBNull(index))
+ if (!reader.IsDBNull(index))
+ {
+ hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
+ }
+ index++;
+ }
+ else
{
- hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
+ index += 9;
}
- index++;
- }
- else
- {
- index += 9;
}
if (!reader.IsDBNull(index))
@@ -1483,7 +1486,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.CustomRating))
+ if (HasField(query, ItemFields.CustomRating))
{
if (!reader.IsDBNull(index))
{
@@ -1498,7 +1501,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.Settings))
+ if (HasField(query, ItemFields.Settings))
{
if (!reader.IsDBNull(index))
{
@@ -1525,7 +1528,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.ExternalEtag))
+ if (HasField(query, ItemFields.ExternalEtag))
{
if (!reader.IsDBNull(index))
{
@@ -1534,11 +1537,14 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (!reader.IsDBNull(index))
+ if (HasField(query, ItemFields.DateLastRefreshed))
{
- item.DateLastRefreshed = reader[index].ReadDateTime();
+ if (!reader.IsDBNull(index))
+ {
+ item.DateLastRefreshed = reader[index].ReadDateTime();
+ }
+ index++;
}
- index++;
if (!reader.IsDBNull(index))
{
@@ -1558,7 +1564,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.Overview))
+ if (HasField(query, ItemFields.Overview))
{
if (!reader.IsDBNull(index))
{
@@ -1585,7 +1591,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.HomePageUrl))
+ if (HasField(query, ItemFields.HomePageUrl))
{
if (!reader.IsDBNull(index))
{
@@ -1594,7 +1600,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.DisplayMediaType))
+ if (HasField(query, ItemFields.DisplayMediaType))
{
if (!reader.IsDBNull(index))
{
@@ -1603,7 +1609,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.SortName))
+ if (HasField(query, ItemFields.SortName))
{
if (!reader.IsDBNull(index))
{
@@ -1618,7 +1624,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.VoteCount))
+ if (HasField(query, ItemFields.VoteCount))
{
if (!reader.IsDBNull(index))
{
@@ -1627,7 +1633,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.DateCreated))
+ if (HasField(query, ItemFields.DateCreated))
{
if (!reader.IsDBNull(index))
{
@@ -1645,7 +1651,7 @@ namespace Emby.Server.Implementations.Data
item.Id = reader.GetGuid(index);
index++;
- if (query.HasField(ItemFields.Genres))
+ if (HasField(query, ItemFields.Genres))
{
if (!reader.IsDBNull(index))
{
@@ -1680,13 +1686,16 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (!reader.IsDBNull(index))
+ if (HasField(query, ItemFields.DateLastSaved))
{
- item.DateLastSaved = reader[index].ReadDateTime();
+ if (!reader.IsDBNull(index))
+ {
+ item.DateLastSaved = reader[index].ReadDateTime();
+ }
+ index++;
}
- index++;
- if (query.HasField(ItemFields.Settings))
+ if (HasField(query, ItemFields.Settings))
{
if (!reader.IsDBNull(index))
{
@@ -1695,7 +1704,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.Studios))
+ if (HasField(query, ItemFields.Studios))
{
if (!reader.IsDBNull(index))
{
@@ -1704,7 +1713,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.Tags))
+ if (HasField(query, ItemFields.Tags))
{
if (!reader.IsDBNull(index))
{
@@ -1729,7 +1738,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.OriginalTitle))
+ if (HasField(query, ItemFields.OriginalTitle))
{
if (!reader.IsDBNull(index))
{
@@ -1748,7 +1757,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.DateLastMediaAdded))
+ if (HasField(query, ItemFields.DateLastMediaAdded))
{
var folder = item as Folder;
if (folder != null && !reader.IsDBNull(index))
@@ -1814,7 +1823,7 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (query.HasField(ItemFields.PresentationUniqueKey))
+ if (HasField(query, ItemFields.PresentationUniqueKey))
{
if (!reader.IsDBNull(index))
{
@@ -1823,7 +1832,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.InheritedParentalRatingValue))
+ if (HasField(query, ItemFields.InheritedParentalRatingValue))
{
if (!reader.IsDBNull(index))
{
@@ -1832,7 +1841,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.Tags))
+ if (HasField(query, ItemFields.Tags))
{
if (!reader.IsDBNull(index))
{
@@ -1841,7 +1850,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.ExternalSeriesId))
+ if (HasField(query, ItemFields.ExternalSeriesId))
{
if (!reader.IsDBNull(index))
{
@@ -1850,7 +1859,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.Taglines))
+ if (HasField(query, ItemFields.Taglines))
{
if (!reader.IsDBNull(index))
{
@@ -1859,7 +1868,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.Keywords))
+ if (HasField(query, ItemFields.Keywords))
{
if (!reader.IsDBNull(index))
{
@@ -1883,7 +1892,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.ProductionLocations))
+ if (HasField(query, ItemFields.ProductionLocations))
{
if (!reader.IsDBNull(index))
{
@@ -1892,7 +1901,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.ThemeSongIds))
+ if (HasField(query, ItemFields.ThemeSongIds))
{
if (!reader.IsDBNull(index))
{
@@ -1901,7 +1910,7 @@ namespace Emby.Server.Implementations.Data
index++;
}
- if (query.HasField(ItemFields.ThemeVideoIds))
+ if (HasField(query, ItemFields.ThemeVideoIds))
{
if (!reader.IsDBNull(index))
{
@@ -1942,14 +1951,17 @@ namespace Emby.Server.Implementations.Data
}
index++;
- if (hasSeries != null)
+ if (HasField(query, ItemFields.SeriesPresentationUniqueKey))
{
- if (!reader.IsDBNull(index))
+ if (hasSeries != null)
{
- hasSeries.SeriesPresentationUniqueKey = reader.GetString(index);
+ if (!reader.IsDBNull(index))
+ {
+ hasSeries.SeriesPresentationUniqueKey = reader.GetString(index);
+ }
}
+ index++;
}
- index++;
return item;
}
@@ -2259,13 +2271,73 @@ namespace Emby.Server.Implementations.Data
return new[] { field.ToString() };
}
+ private bool HasField(InternalItemsQuery query, ItemFields name)
+ {
+ var fields = query.DtoOptions.Fields;
+
+ switch (name)
+ {
+ case ItemFields.HomePageUrl:
+ case ItemFields.Keywords:
+ case ItemFields.DisplayMediaType:
+ case ItemFields.VoteCount:
+ case ItemFields.CustomRating:
+ case ItemFields.ProductionLocations:
+ case ItemFields.Settings:
+ case ItemFields.OriginalTitle:
+ case ItemFields.Taglines:
+ case ItemFields.SortName:
+ case ItemFields.Studios:
+ case ItemFields.Tags:
+ case ItemFields.ThemeSongIds:
+ case ItemFields.ThemeVideoIds:
+ case ItemFields.DateCreated:
+ case ItemFields.Overview:
+ case ItemFields.Genres:
+ case ItemFields.DateLastMediaAdded:
+ case ItemFields.ExternalEtag:
+ case ItemFields.PresentationUniqueKey:
+ case ItemFields.InheritedParentalRatingValue:
+ case ItemFields.ExternalSeriesId:
+ case ItemFields.SeriesPresentationUniqueKey:
+ case ItemFields.DateLastRefreshed:
+ case ItemFields.DateLastSaved:
+ return fields.Contains(name);
+ case ItemFields.ServiceName:
+ return true;
+ default:
+ return true;
+ }
+ }
+
+ private bool HasProgramAttributes(InternalItemsQuery query)
+ {
+ if (query.IncludeItemTypes.Length == 0)
+ {
+ return true;
+ }
+
+ var types = new string[]
+ {
+ "Program",
+ "Recording",
+ "TvChannel",
+ "LiveTvAudioRecording",
+ "LiveTvVideoRecording",
+ "LiveTvProgram",
+ "LiveTvTvChannel"
+ };
+
+ return types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase));
+ }
+
private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns)
{
var list = startColumns.ToList();
foreach (var field in allFields)
{
- if (!query.HasField(field))
+ if (!HasField(query, field))
{
foreach (var fieldToRemove in GetColumnNamesFromField(field).ToList())
{
@@ -2274,6 +2346,19 @@ namespace Emby.Server.Implementations.Data
}
}
+ if (!HasProgramAttributes(query))
+ {
+ list.Remove("IsKids");
+ list.Remove("IsMovie");
+ list.Remove("IsSports");
+ list.Remove("IsSeries");
+ list.Remove("IsLive");
+ list.Remove("IsNews");
+ list.Remove("IsPremiere");
+ list.Remove("EpisodeTitle");
+ list.Remove("IsRepeat");
+ }
+
if (!query.DtoOptions.EnableImages)
{
list.Remove("Images");
@@ -2400,7 +2485,7 @@ namespace Emby.Server.Implementations.Data
query.Limit = query.Limit.Value + 4;
}
- var commandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new [] { "count(distinct PresentationUniqueKey)" })) + GetFromText();
+ var commandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "count(distinct PresentationUniqueKey)" })) + GetFromText();
commandText += GetJoinUserDataText(query);
var whereClauses = GetWhereClauses(query, null);
@@ -3671,6 +3756,7 @@ namespace Emby.Server.Implementations.Data
if (!string.IsNullOrWhiteSpace(query.SlugName))
{
+ Logger.Info("Searching by SlugName for {0}", query.SlugName);
whereClauses.Add("CleanName=@SlugName");
if (statement != null)
{
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index bb46e60063..6f2e437cf8 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -1137,7 +1137,10 @@ namespace Emby.Server.Implementations.Dto
return null;
}
- var artist = _libraryManager.GetArtist(i);
+ var artist = _libraryManager.GetArtist(i, new DtoOptions(false)
+ {
+ EnableImages = false
+ });
if (artist != null)
{
return new NameIdPair
@@ -1186,7 +1189,10 @@ namespace Emby.Server.Implementations.Dto
return null;
}
- var artist = _libraryManager.GetArtist(i);
+ var artist = _libraryManager.GetArtist(i, new DtoOptions(false)
+ {
+ EnableImages = false
+ });
if (artist != null)
{
return new NameIdPair
@@ -1456,7 +1462,7 @@ namespace Emby.Server.Implementations.Dto
var musicAlbum = item as MusicAlbum;
if (musicAlbum != null)
{
- var artist = musicAlbum.MusicArtist;
+ var artist = musicAlbum.GetMusicArtist(new DtoOptions(false));
if (artist != null)
{
return artist;
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 5e96eda94a..79209d438b 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.SocketSharp;
@@ -445,10 +446,7 @@ namespace Emby.Server.Implementations.HttpServer
///
/// Overridable method that can be used to implement a custom hnandler
///
- /// The HTTP req.
- /// The URL.
- /// Task.
- protected async Task RequestHandler(IHttpRequest httpReq, Uri url)
+ protected async Task RequestHandler(IHttpRequest httpReq, Uri url, CancellationToken cancellationToken)
{
var date = DateTime.Now;
var httpRes = httpReq.Response;
@@ -589,7 +587,7 @@ namespace Emby.Server.Implementations.HttpServer
if (handler != null)
{
- await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, operationName).ConfigureAwait(false);
+ await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, operationName, cancellationToken).ConfigureAwait(false);
}
else
{
diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
index 18df5682d7..82175dbed6 100644
--- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Net;
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
@@ -18,7 +19,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets or sets the request handler.
///
/// The request handler.
- Func RequestHandler { get; set; }
+ Func RequestHandler { get; set; }
///
/// Gets or sets the web socket handler.
diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
index 682fa7a0b8..f085ff71e7 100644
--- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
@@ -4,6 +4,7 @@ using SocketHttpListener.Net;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Cryptography;
@@ -50,7 +51,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
}
public Action ErrorHandler { get; set; }
- public Func RequestHandler { get; set; }
+ public Func RequestHandler { get; set; }
public Action WebSocketConnecting { get; set; }
@@ -82,10 +83,10 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
private void ProcessContext(HttpListenerContext context)
{
//Task.Factory.StartNew(() => InitTask(context), TaskCreationOptions.DenyChildAttach | TaskCreationOptions.PreferFairness);
- Task.Run(() => InitTask(context));
+ Task.Run(() => InitTask(context, CancellationToken.None));
}
- private Task InitTask(HttpListenerContext context)
+ private Task InitTask(HttpListenerContext context, CancellationToken cancellationToken)
{
IHttpRequest httpReq = null;
var request = context.Request;
@@ -111,7 +112,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
return Task.FromResult(true);
}
- return RequestHandler(httpReq, request.Url);
+ return RequestHandler(httpReq, request.Url, cancellationToken);
}
private void ProcessWebSocketRequest(HttpListenerContext ctx)
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index a423db9d6f..8907c911a1 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -885,7 +885,7 @@ namespace Emby.Server.Implementations.Library
/// Task{Person}.
public Person GetPerson(string name)
{
- return CreateItemByName(Person.GetPath, name);
+ return CreateItemByName(Person.GetPath, name, new DtoOptions(true));
}
///
@@ -895,7 +895,7 @@ namespace Emby.Server.Implementations.Library
/// Task{Studio}.
public Studio GetStudio(string name)
{
- return CreateItemByName(Studio.GetPath, name);
+ return CreateItemByName(Studio.GetPath, name, new DtoOptions(true));
}
public Guid GetStudioId(string name)
@@ -925,7 +925,7 @@ namespace Emby.Server.Implementations.Library
/// Task{Genre}.
public Genre GetGenre(string name)
{
- return CreateItemByName(Genre.GetPath, name);
+ return CreateItemByName(Genre.GetPath, name, new DtoOptions(true));
}
///
@@ -935,7 +935,7 @@ namespace Emby.Server.Implementations.Library
/// Task{MusicGenre}.
public MusicGenre GetMusicGenre(string name)
{
- return CreateItemByName(MusicGenre.GetPath, name);
+ return CreateItemByName(MusicGenre.GetPath, name, new DtoOptions(true));
}
///
@@ -945,7 +945,7 @@ namespace Emby.Server.Implementations.Library
/// Task{GameGenre}.
public GameGenre GetGameGenre(string name)
{
- return CreateItemByName(GameGenre.GetPath, name);
+ return CreateItemByName(GameGenre.GetPath, name, new DtoOptions(true));
}
///
@@ -963,7 +963,7 @@ namespace Emby.Server.Implementations.Library
var name = value.ToString(CultureInfo.InvariantCulture);
- return CreateItemByName(Year.GetPath, name);
+ return CreateItemByName(Year.GetPath, name, new DtoOptions(true));
}
///
@@ -973,10 +973,15 @@ namespace Emby.Server.Implementations.Library
/// Task{Genre}.
public MusicArtist GetArtist(string name)
{
- return CreateItemByName(MusicArtist.GetPath, name);
+ return GetArtist(name, new DtoOptions(true));
}
- private T CreateItemByName(Func getPathFn, string name)
+ public MusicArtist GetArtist(string name, DtoOptions options)
+ {
+ return CreateItemByName(MusicArtist.GetPath, name, options);
+ }
+
+ private T CreateItemByName(Func getPathFn, string name, DtoOptions options)
where T : BaseItem, new()
{
if (typeof(T) == typeof(MusicArtist))
@@ -985,7 +990,7 @@ namespace Emby.Server.Implementations.Library
{
IncludeItemTypes = new[] { typeof(T).Name },
Name = name,
- DtoOptions = new DtoOptions(true)
+ DtoOptions = options
}).Cast()
.OrderBy(i => i.IsAccessedByName ? 1 : 0)
@@ -1029,54 +1034,6 @@ namespace Emby.Server.Implementations.Library
return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId);
}
- public IEnumerable GetAlbumArtists(IEnumerable items)
- {
- var names = items
- .SelectMany(i => i.AlbumArtists)
- .DistinctNames()
- .Select(i =>
- {
- try
- {
- var artist = GetArtist(i);
-
- return artist;
- }
- catch
- {
- // Already logged at lower levels
- return null;
- }
- })
- .Where(i => i != null);
-
- return names;
- }
-
- public IEnumerable GetArtists(IEnumerable items)
- {
- var names = items
- .SelectMany(i => i.AllArtists)
- .DistinctNames()
- .Select(i =>
- {
- try
- {
- var artist = GetArtist(i);
-
- return artist;
- }
- catch
- {
- // Already logged at lower levels
- return null;
- }
- })
- .Where(i => i != null);
-
- return names;
- }
-
///
/// Validate and refresh the People sub-set of the IBN.
/// The items are stored in the db but not loaded into memory until actually requested by an operation.
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 89b772731c..83db58668d 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1234,8 +1234,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
Protocol = MediaBrowser.Model.MediaInfo.MediaProtocol.Http,
BufferMs = 0,
IgnoreDts = true,
- IgnoreIndex = true,
- GenPtsInput = true
+ IgnoreIndex = true
};
var isAudio = false;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index fa505d3fb3..48ad7cf123 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -479,7 +479,7 @@ namespace Emby.Server.Implementations.LiveTv
if (!(service is EmbyTV.EmbyTV))
{
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
- mediaSource.SupportsDirectPlay = false;
+ //mediaSource.SupportsDirectPlay = false;
mediaSource.SupportsDirectStream = false;
mediaSource.SupportsTranscoding = true;
foreach (var stream in mediaSource.MediaStreams)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 5d489985f2..c1e1bf2b62 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -422,8 +422,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
SupportsTranscoding = true,
IsInfiniteStream = true,
IgnoreDts = true,
- IgnoreIndex = true,
- GenPtsInput = true
+ IgnoreIndex = true
};
mediaSource.InferTotalBitrate();
@@ -507,12 +506,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
{
- return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Url), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
+ return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Url), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
}
// The UDP method is not working reliably on OSX, and on BSD it hasn't been tested yet
- var enableHttpStream = _environment.OperatingSystem == OperatingSystem.OSX ||
- _environment.OperatingSystem == OperatingSystem.BSD;
+ var enableHttpStream = _environment.OperatingSystem == OperatingSystem.OSX
+ || _environment.OperatingSystem == OperatingSystem.BSD;
enableHttpStream = true;
if (enableHttpStream)
{
@@ -521,17 +520,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var httpUrl = GetApiUrl(info, true) + "/auto/v" + hdhrId;
// If raw was used, the tuner doesn't support params
- if (!string.IsNullOrWhiteSpace(profile)
- && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
+ if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
{
httpUrl += "?transcode=" + profile;
}
mediaSource.Path = httpUrl;
- return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
+ return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
}
- return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
+ return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
}
public async Task Validate(TunerHostInfo info)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
index dd63bbb726..03c21b1202 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.System;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
@@ -17,24 +18,22 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
private readonly ILogger _logger;
private readonly IHttpClient _httpClient;
- private readonly IFileSystem _fileSystem;
- private readonly IServerApplicationPaths _appPaths;
private readonly IServerApplicationHost _appHost;
private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource();
private readonly TaskCompletionSource _liveStreamTaskCompletionSource = new TaskCompletionSource();
- private readonly MulticastStream _multicastStream;
- public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost)
- : base(mediaSource)
+ private readonly string _tempFilePath;
+
+ public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
+ : base(mediaSource, environment, fileSystem)
{
- _fileSystem = fileSystem;
_httpClient = httpClient;
_logger = logger;
- _appPaths = appPaths;
_appHost = appHost;
OriginalStreamId = originalStreamId;
- _multicastStream = new MulticastStream(_logger);
+
+ _tempFilePath = Path.Combine(appPaths.TranscodingTempPath, UniqueId + ".ts");
}
protected override async Task OpenInternal(CancellationToken openCancellationToken)
@@ -74,9 +73,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return _liveStreamTaskCompletionSource.Task;
}
- private async Task StartStreaming(string url, TaskCompletionSource openTaskCompletionSource, CancellationToken cancellationToken)
+ private Task StartStreaming(string url, TaskCompletionSource openTaskCompletionSource, CancellationToken cancellationToken)
{
- await Task.Run(async () =>
+ return Task.Run(async () =>
{
var isFirstAttempt = true;
@@ -101,13 +100,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
_logger.Info("Beginning multicastStream.CopyUntilCancelled");
- Action onStarted = null;
- if (isFirstAttempt)
+ FileSystem.CreateDirectory(FileSystem.GetDirectoryName(_tempFilePath));
+ using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous | FileOpenOptions.SequentialScan))
{
- onStarted = () => openTaskCompletionSource.TrySetResult(true);
- }
+ ResolveAfterDelay(2000, openTaskCompletionSource);
- await _multicastStream.CopyUntilCancelled(response.Content, onStarted, cancellationToken).ConfigureAwait(false);
+ await response.Content.CopyToAsync(fileStream, 81920, cancellationToken).ConfigureAwait(false);
+ }
}
}
}
@@ -131,13 +130,22 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
_liveStreamTaskCompletionSource.TrySetResult(true);
+ await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
+ });
+ }
- }).ConfigureAwait(false);
+ private void ResolveAfterDelay(int delayMs, TaskCompletionSource openTaskCompletionSource)
+ {
+ Task.Run(async () =>
+ {
+ await Task.Delay(delayMs).ConfigureAwait(false);
+ openTaskCompletionSource.TrySetResult(true);
+ });
}
public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
{
- return _multicastStream.CopyToAsync(stream , cancellationToken);
+ return CopyFileTo(_tempFilePath, false, stream, cancellationToken);
}
}
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
index 2c678d9f8d..3202b7313c 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs
@@ -46,10 +46,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
public class HdHomerunChannelCommands : IHdHomerunChannelCommands
{
private string _channel;
+ private string _profile;
- public HdHomerunChannelCommands(string channel)
+ public HdHomerunChannelCommands(string channel, string profile)
{
_channel = channel;
+ _profile = profile;
}
public IEnumerable> GetCommands()
@@ -57,7 +59,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var commands = new List>();
if (!String.IsNullOrEmpty(_channel))
- commands.Add(Tuple.Create("vchannel", _channel));
+ {
+ if (!string.IsNullOrWhiteSpace(_profile) && !string.Equals(_profile, "native", StringComparison.OrdinalIgnoreCase))
+ {
+ commands.Add(Tuple.Create("vchannel", String.Format("{0} transcode={1}", _channel, _profile)));
+ }
+ else
+ {
+ commands.Add(Tuple.Create("vchannel", _channel));
+ }
+ }
return commands;
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
index c84aebce76..ff6c0fb2c9 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
@@ -14,39 +14,35 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
+using MediaBrowser.Model.System;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
public class HdHomerunUdpStream : LiveStream, IDirectStreamProvider
{
private readonly ILogger _logger;
- private readonly IHttpClient _httpClient;
- private readonly IFileSystem _fileSystem;
- private readonly IServerApplicationPaths _appPaths;
private readonly IServerApplicationHost _appHost;
private readonly ISocketFactory _socketFactory;
private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource();
private readonly TaskCompletionSource _liveStreamTaskCompletionSource = new TaskCompletionSource();
- private readonly MulticastStream _multicastStream;
private readonly IHdHomerunChannelCommands _channelCommands;
private readonly int _numTuners;
private readonly INetworkManager _networkManager;
- public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
- : base(mediaSource)
+ private readonly string _tempFilePath;
+
+ public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment)
+ : base(mediaSource, environment, fileSystem)
{
- _fileSystem = fileSystem;
- _httpClient = httpClient;
_logger = logger;
- _appPaths = appPaths;
_appHost = appHost;
_socketFactory = socketFactory;
_networkManager = networkManager;
OriginalStreamId = originalStreamId;
- _multicastStream = new MulticastStream(_logger);
_channelCommands = channelCommands;
_numTuners = numTuners;
+ _tempFilePath = Path.Combine(appPaths.TranscodingTempPath, UniqueId + ".ts");
}
protected override async Task OpenInternal(CancellationToken openCancellationToken)
@@ -87,9 +83,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return _liveStreamTaskCompletionSource.Task;
}
- private async Task StartStreaming(string remoteIp, int localPort, TaskCompletionSource openTaskCompletionSource, CancellationToken cancellationToken)
+ private Task StartStreaming(string remoteIp, int localPort, TaskCompletionSource openTaskCompletionSource, CancellationToken cancellationToken)
{
- await Task.Run(async () =>
+ return Task.Run(async () =>
{
var isFirstAttempt = true;
using (var udpClient = _socketFactory.CreateUdpSocket(localPort))
@@ -124,13 +120,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (!cancellationToken.IsCancellationRequested)
{
- Action onStarted = null;
- if (isFirstAttempt)
+ FileSystem.CreateDirectory(FileSystem.GetDirectoryName(_tempFilePath));
+ using (var fileStream = FileSystem.GetFileStream(_tempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.Asynchronous | FileOpenOptions.SequentialScan))
{
- onStarted = () => openTaskCompletionSource.TrySetResult(true);
- }
+ ResolveAfterDelay(2000, openTaskCompletionSource);
- await _multicastStream.CopyUntilCancelled(new UdpClientStream(udpClient), onStarted, cancellationToken).ConfigureAwait(false);
+ await new UdpClientStream(udpClient).CopyToAsync(fileStream, 81920, cancellationToken).ConfigureAwait(false);
+ }
}
}
catch (OperationCanceledException ex)
@@ -159,12 +155,22 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
- }).ConfigureAwait(false);
+ await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
+ });
+ }
+
+ private void ResolveAfterDelay(int delayMs, TaskCompletionSource openTaskCompletionSource)
+ {
+ Task.Run(async () =>
+ {
+ await Task.Delay(delayMs).ConfigureAwait(false);
+ openTaskCompletionSource.TrySetResult(true);
+ });
}
public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
{
- return _multicastStream.CopyToAsync(stream, cancellationToken);
+ return CopyFileTo(_tempFilePath, false, stream, cancellationToken);
}
}
@@ -198,7 +204,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// This will always receive a 1328 packet size (PacketSize + RtpHeaderSize)
// The RTP header will be stripped so see how many reads we need to make to fill the buffer.
- int numReads = count / PacketSize;
+ var numReads = count / PacketSize;
+
int totalBytesRead = 0;
for (int i = 0; i < numReads; ++i)
@@ -206,7 +213,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var data = await _udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
var bytesRead = data.ReceivedBytes - RtpHeaderBytes;
-
+
// remove rtp header
Buffer.BlockCopy(data.Buffer, RtpHeaderBytes, buffer, offset, bytesRead);
offset += bytesRead;
@@ -224,7 +231,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
get
{
- throw new NotImplementedException();
+ return true;
}
}
@@ -232,7 +239,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
get
{
- throw new NotImplementedException();
+ return false;
}
}
@@ -240,7 +247,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
get
{
- throw new NotImplementedException();
+ return false;
}
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index 8cf1106f0f..2c6641ee14 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.System;
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
@@ -27,13 +28,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
+ private readonly IEnvironmentInfo _environment;
- public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
+ public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_fileSystem = fileSystem;
_httpClient = httpClient;
_appHost = appHost;
+ _environment = environment;
}
public override string Type
@@ -73,7 +76,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
- var liveStream = new LiveStream(sources.First());
+ var liveStream = new LiveStream(sources.First(), _environment, _fileSystem);
return liveStream;
}
diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs
index 3c2af60db0..22d2b95f7f 100644
--- a/Emby.Server.Implementations/Services/ResponseHelper.cs
+++ b/Emby.Server.Implementations/Services/ResponseHelper.cs
@@ -12,7 +12,7 @@ namespace Emby.Server.Implementations.Services
{
public static class ResponseHelper
{
- public static Task WriteToResponse(IResponse httpRes, IRequest httpReq, object result)
+ public static Task WriteToResponse(IResponse httpRes, IRequest httpReq, object result, CancellationToken cancellationToken)
{
if (result == null)
{
@@ -30,21 +30,17 @@ namespace Emby.Server.Implementations.Services
{
httpResult.RequestContext = httpReq;
httpReq.ResponseContentType = httpResult.ContentType ?? httpReq.ResponseContentType;
- return WriteToResponseInternal(httpRes, httpResult, httpReq);
+ return WriteToResponseInternal(httpRes, httpResult, httpReq, cancellationToken);
}
- return WriteToResponseInternal(httpRes, result, httpReq);
+ return WriteToResponseInternal(httpRes, result, httpReq, cancellationToken);
}
///
/// Writes to response.
/// Response headers are customizable by implementing IHasHeaders an returning Dictionary of Http headers.
///
- /// The response.
- /// Whether or not it was implicity handled by ServiceStack's built-in handlers.
- /// The serialization context.
- ///
- private static async Task WriteToResponseInternal(IResponse response, object result, IRequest request)
+ private static async Task WriteToResponseInternal(IResponse response, object result, IRequest request, CancellationToken cancellationToken)
{
var defaultContentType = request.ResponseContentType;
@@ -105,7 +101,7 @@ namespace Emby.Server.Implementations.Services
var asyncStreamWriter = result as IAsyncStreamWriter;
if (asyncStreamWriter != null)
{
- await asyncStreamWriter.WriteToAsync(response.OutputStream, CancellationToken.None).ConfigureAwait(false);
+ await asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken).ConfigureAwait(false);
return;
}
@@ -119,7 +115,7 @@ namespace Emby.Server.Implementations.Services
var fileWriter = result as FileWriter;
if (fileWriter != null)
{
- await fileWriter.WriteToAsync(response, CancellationToken.None).ConfigureAwait(false);
+ await fileWriter.WriteToAsync(response, cancellationToken).ConfigureAwait(false);
return;
}
diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs
index 8b59b48430..95a9dd6829 100644
--- a/Emby.Server.Implementations/Services/ServiceHandler.cs
+++ b/Emby.Server.Implementations/Services/ServiceHandler.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
using MediaBrowser.Model.Logging;
@@ -123,7 +124,7 @@ namespace Emby.Server.Implementations.Services
// Set from SSHHF.GetHandlerForPathInfo()
public string ResponseContentType { get; set; }
- public async Task ProcessRequestAsync(HttpListenerHost appHost, IRequest httpReq, IResponse httpRes, ILogger logger, string operationName)
+ public async Task ProcessRequestAsync(HttpListenerHost appHost, IRequest httpReq, IResponse httpRes, ILogger logger, string operationName, CancellationToken cancellationToken)
{
var restPath = GetRestPath(httpReq.Verb, httpReq.PathInfo);
if (restPath == null)
@@ -150,7 +151,7 @@ namespace Emby.Server.Implementations.Services
responseFilter(httpReq, httpRes, response);
}
- await ResponseHelper.WriteToResponse(httpRes, httpReq, response).ConfigureAwait(false);
+ await ResponseHelper.WriteToResponse(httpRes, httpReq, response, cancellationToken).ConfigureAwait(false);
}
public static object CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath, ILogger logger)
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 1a57ff62dd..0f1d240d0c 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -174,14 +174,15 @@ namespace MediaBrowser.Api
return options;
}
- protected MusicArtist GetArtist(string name, ILibraryManager libraryManager)
+ protected MusicArtist GetArtist(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(MusicArtist).Name }
+ IncludeItemTypes = new[] { typeof(MusicArtist).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -191,17 +192,18 @@ namespace MediaBrowser.Api
}
}
- return libraryManager.GetArtist(name);
+ return libraryManager.GetArtist(name, dtoOptions);
}
- protected Studio GetStudio(string name, ILibraryManager libraryManager)
+ protected Studio GetStudio(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(Studio).Name }
+ IncludeItemTypes = new[] { typeof(Studio).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -214,14 +216,15 @@ namespace MediaBrowser.Api
return libraryManager.GetStudio(name);
}
- protected Genre GetGenre(string name, ILibraryManager libraryManager)
+ protected Genre GetGenre(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(Genre).Name }
+ IncludeItemTypes = new[] { typeof(Genre).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -234,14 +237,15 @@ namespace MediaBrowser.Api
return libraryManager.GetGenre(name);
}
- protected MusicGenre GetMusicGenre(string name, ILibraryManager libraryManager)
+ protected MusicGenre GetMusicGenre(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(MusicGenre).Name }
+ IncludeItemTypes = new[] { typeof(MusicGenre).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -254,14 +258,15 @@ namespace MediaBrowser.Api
return libraryManager.GetMusicGenre(name);
}
- protected GameGenre GetGameGenre(string name, ILibraryManager libraryManager)
+ protected GameGenre GetGameGenre(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(GameGenre).Name }
+ IncludeItemTypes = new[] { typeof(GameGenre).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -274,14 +279,15 @@ namespace MediaBrowser.Api
return libraryManager.GetGameGenre(name);
}
- protected Person GetPerson(string name, ILibraryManager libraryManager)
+ protected Person GetPerson(string name, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
if (name.IndexOf(BaseItem.SlugChar) != -1)
{
var result = libraryManager.GetItemList(new InternalItemsQuery
{
SlugName = name,
- IncludeItemTypes = new[] { typeof(Person).Name }
+ IncludeItemTypes = new[] { typeof(Person).Name },
+ DtoOptions = dtoOptions
}).OfType().FirstOrDefault();
@@ -329,37 +335,33 @@ namespace MediaBrowser.Api
///
/// Gets the name of the item by.
///
- /// The name.
- /// The type.
- /// The library manager.
- /// Task{BaseItem}.
- protected BaseItem GetItemByName(string name, string type, ILibraryManager libraryManager)
+ protected BaseItem GetItemByName(string name, string type, ILibraryManager libraryManager, DtoOptions dtoOptions)
{
BaseItem item;
if (type.IndexOf("Person", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetPerson(name, libraryManager);
+ item = GetPerson(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("Artist", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetArtist(name, libraryManager);
+ item = GetArtist(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("Genre", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetGenre(name, libraryManager);
+ item = GetGenre(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("MusicGenre", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetMusicGenre(name, libraryManager);
+ item = GetMusicGenre(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("GameGenre", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetGameGenre(name, libraryManager);
+ item = GetGameGenre(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("Studio", StringComparison.OrdinalIgnoreCase) == 0)
{
- item = GetStudio(name, libraryManager);
+ item = GetStudio(name, libraryManager, dtoOptions);
}
else if (type.IndexOf("Year", StringComparison.OrdinalIgnoreCase) == 0)
{
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index cbbaa82b80..6c4cc22170 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -15,6 +15,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
@@ -406,7 +407,7 @@ namespace MediaBrowser.Api.Images
{
var type = GetPathValue(0);
- var item = GetItemByName(request.Name, type, _libraryManager);
+ var item = GetItemByName(request.Name, type, _libraryManager, new DtoOptions(false));
return GetImage(request, item, false);
}
@@ -415,7 +416,7 @@ namespace MediaBrowser.Api.Images
{
var type = GetPathValue(0);
- var item = GetItemByName(request.Name, type, _libraryManager);
+ var item = GetItemByName(request.Name, type, _libraryManager, new DtoOptions(false));
return GetImage(request, item, true);
}
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 3494754d0a..a90c8d9e78 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -22,6 +22,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Services;
+using MediaBrowser.Model.System;
namespace MediaBrowser.Api.LiveTv
{
@@ -698,8 +699,9 @@ namespace MediaBrowser.Api.LiveTv
private readonly IFileSystem _fileSystem;
private readonly IAuthorizationContext _authContext;
private readonly ISessionContext _sessionContext;
+ private readonly IEnvironmentInfo _environment;
- public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext)
+ public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext, IEnvironmentInfo environment)
{
_liveTvManager = liveTvManager;
_userManager = userManager;
@@ -710,6 +712,7 @@ namespace MediaBrowser.Api.LiveTv
_fileSystem = fileSystem;
_authContext = authContext;
_sessionContext = sessionContext;
+ _environment = environment;
}
public object Get(GetTunerHostTypes request)
@@ -731,7 +734,7 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
- return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, null, Logger, CancellationToken.None)
+ return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, null, Logger, _environment, CancellationToken.None)
{
AllowEndOfFile = false
};
@@ -750,7 +753,7 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
- return new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, CancellationToken.None)
+ return new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, _environment, CancellationToken.None)
{
AllowEndOfFile = false
};
diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs
index 797edd9402..3cb29de072 100644
--- a/MediaBrowser.Api/Music/InstantMixService.cs
+++ b/MediaBrowser.Api/Music/InstantMixService.cs
@@ -171,7 +171,7 @@ namespace MediaBrowser.Api.Music
public Task
private Stream GetRawResourceStream(string virtualPath)
{
- return _fileSystem.GetFileStream(GetDashboardResourcePath(virtualPath), FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, true);
+ return _fileSystem.GetFileStream(GetResourcePath(virtualPath), FileOpenMode.Open, FileAccessMode.Read, FileShareMode.ReadWrite, true);
}
}
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 140f3c2869..5a7ec0dba4 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.17.9")]
+[assembly: AssemblyVersion("3.2.17.10")]
diff --git a/SocketHttpListener.Portable/Net/ResponseStream.cs b/SocketHttpListener.Portable/Net/ResponseStream.cs
index 149b24028d..b2d0d4e9c2 100644
--- a/SocketHttpListener.Portable/Net/ResponseStream.cs
+++ b/SocketHttpListener.Portable/Net/ResponseStream.cs
@@ -148,6 +148,7 @@ namespace SocketHttpListener.Net
}
const int MsCopyBufferSize = 81920;
+ const int StreamCopyToBufferSize = 81920;
public override void Write(byte[] buffer, int offset, int count)
{
if (disposed)
@@ -340,11 +341,11 @@ namespace SocketHttpListener.Net
{
if (allowAsync)
{
- await fs.CopyToAsync(targetStream, 81920, cancellationToken).ConfigureAwait(false);
+ await fs.CopyToAsync(targetStream, StreamCopyToBufferSize, cancellationToken).ConfigureAwait(false);
}
else
{
- fs.CopyTo(targetStream, 81920);
+ fs.CopyTo(targetStream, StreamCopyToBufferSize);
}
}
}
@@ -352,16 +353,11 @@ namespace SocketHttpListener.Net
private static async Task CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken)
{
- var array = new byte[81920];
+ var array = new byte[StreamCopyToBufferSize];
int bytesRead;
while ((bytesRead = source.Read(array, 0, array.Length)) != 0)
{
- if (bytesRead == 0)
- {
- break;
- }
-
var bytesToWrite = Math.Min(bytesRead, copyLength);
if (bytesToWrite > 0)
@@ -380,16 +376,11 @@ namespace SocketHttpListener.Net
private static async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken)
{
- var array = new byte[81920];
+ var array = new byte[StreamCopyToBufferSize];
int bytesRead;
while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
- if (bytesRead == 0)
- {
- break;
- }
-
var bytesToWrite = Math.Min(bytesRead, copyLength);
if (bytesToWrite > 0)