mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-07 02:36:20 +00:00
update query fields
This commit is contained in:
@@ -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))
|
||||
{
|
||||
hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
|
||||
if (!reader.IsDBNull(index))
|
||||
{
|
||||
hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Overridable method that can be used to implement a custom hnandler
|
||||
/// </summary>
|
||||
/// <param name="httpReq">The HTTP req.</param>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <returns>Task.</returns>
|
||||
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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
/// <value>The request handler.</value>
|
||||
Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
|
||||
Func<IHttpRequest, Uri, CancellationToken, Task> RequestHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the web socket handler.
|
||||
|
||||
@@ -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<Exception, IRequest, bool> ErrorHandler { get; set; }
|
||||
public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
|
||||
public Func<IHttpRequest, Uri, CancellationToken, Task> RequestHandler { get; set; }
|
||||
|
||||
public Action<WebSocketConnectingEventArgs> 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)
|
||||
|
||||
@@ -885,7 +885,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{Person}.</returns>
|
||||
public Person GetPerson(string name)
|
||||
{
|
||||
return CreateItemByName<Person>(Person.GetPath, name);
|
||||
return CreateItemByName<Person>(Person.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -895,7 +895,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{Studio}.</returns>
|
||||
public Studio GetStudio(string name)
|
||||
{
|
||||
return CreateItemByName<Studio>(Studio.GetPath, name);
|
||||
return CreateItemByName<Studio>(Studio.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
public Guid GetStudioId(string name)
|
||||
@@ -925,7 +925,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
public Genre GetGenre(string name)
|
||||
{
|
||||
return CreateItemByName<Genre>(Genre.GetPath, name);
|
||||
return CreateItemByName<Genre>(Genre.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -935,7 +935,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{MusicGenre}.</returns>
|
||||
public MusicGenre GetMusicGenre(string name)
|
||||
{
|
||||
return CreateItemByName<MusicGenre>(MusicGenre.GetPath, name);
|
||||
return CreateItemByName<MusicGenre>(MusicGenre.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -945,7 +945,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{GameGenre}.</returns>
|
||||
public GameGenre GetGameGenre(string name)
|
||||
{
|
||||
return CreateItemByName<GameGenre>(GameGenre.GetPath, name);
|
||||
return CreateItemByName<GameGenre>(GameGenre.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -963,7 +963,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var name = value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
return CreateItemByName<Year>(Year.GetPath, name);
|
||||
return CreateItemByName<Year>(Year.GetPath, name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -973,10 +973,15 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
public MusicArtist GetArtist(string name)
|
||||
{
|
||||
return CreateItemByName<MusicArtist>(MusicArtist.GetPath, name);
|
||||
return GetArtist(name, new DtoOptions(true));
|
||||
}
|
||||
|
||||
private T CreateItemByName<T>(Func<string, string> getPathFn, string name)
|
||||
public MusicArtist GetArtist(string name, DtoOptions options)
|
||||
{
|
||||
return CreateItemByName<MusicArtist>(MusicArtist.GetPath, name, options);
|
||||
}
|
||||
|
||||
private T CreateItemByName<T>(Func<string, string> 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<MusicArtist>()
|
||||
.OrderBy(i => i.IsAccessedByName ? 1 : 0)
|
||||
@@ -1029,54 +1034,6 @@ namespace Emby.Server.Implementations.Library
|
||||
return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId);
|
||||
}
|
||||
|
||||
public IEnumerable<MusicArtist> GetAlbumArtists(IEnumerable<IHasAlbumArtist> 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<MusicArtist> GetArtists(IEnumerable<IHasArtist> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||
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<bool> openTaskCompletionSource, CancellationToken cancellationToken)
|
||||
private Task StartStreaming(string url, TaskCompletionSource<bool> 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<bool> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Tuple<string, string>> GetCommands()
|
||||
@@ -57,7 +59,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
var commands = new List<Tuple<string, string>>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||
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<bool> openTaskCompletionSource, CancellationToken cancellationToken)
|
||||
private Task StartStreaming(string remoteIp, int localPort, TaskCompletionSource<bool> 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<bool> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes to response.
|
||||
/// Response headers are customizable by implementing IHasHeaders an returning Dictionary of Http headers.
|
||||
/// </summary>
|
||||
/// <param name="response">The response.</param>
|
||||
/// <param name="result">Whether or not it was implicity handled by ServiceStack's built-in handlers.</param>
|
||||
/// <param name="request">The serialization context.</param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user