mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
commit
229be75961
@ -100,7 +100,7 @@ namespace Emby.Common.Implementations.Net
|
|||||||
#if NET46
|
#if NET46
|
||||||
public Task SendFile(string path, byte[] preBuffer, byte[] postBuffer, CancellationToken cancellationToken)
|
public Task SendFile(string path, byte[] preBuffer, byte[] postBuffer, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var options = TransmitFileOptions.UseKernelApc;
|
var options = TransmitFileOptions.UseDefaultWorkerThread;
|
||||||
|
|
||||||
var completionSource = new TaskCompletionSource<bool>();
|
var completionSource = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
|
@ -213,9 +213,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
var subtitleArgs = CopySubtitles ? " -codec:s copy" : " -sn";
|
var subtitleArgs = CopySubtitles ? " -codec:s copy" : " -sn";
|
||||||
|
|
||||||
var outputParam = string.Equals(Path.GetExtension(targetFile), ".mp4", StringComparison.OrdinalIgnoreCase) ?
|
//var outputParam = string.Equals(Path.GetExtension(targetFile), ".mp4", StringComparison.OrdinalIgnoreCase) ?
|
||||||
" -f mp4 -movflags frag_keyframe+empty_moov" :
|
// " -f mp4 -movflags frag_keyframe+empty_moov" :
|
||||||
string.Empty;
|
// string.Empty;
|
||||||
|
|
||||||
|
var outputParam = string.Empty;
|
||||||
|
|
||||||
var commandLineArgs = string.Format("-i \"{0}\"{5} {2} -map_metadata -1 -threads 0 {3}{4}{6} -y \"{1}\"",
|
var commandLineArgs = string.Format("-i \"{0}\"{5} {2} -map_metadata -1 -threads 0 {3}{4}{6} -y \"{1}\"",
|
||||||
inputTempFile,
|
inputTempFile,
|
||||||
|
@ -9,6 +9,7 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.Search;
|
using MediaBrowser.Model.Search;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Model.Services;
|
using MediaBrowser.Model.Services;
|
||||||
|
|
||||||
namespace MediaBrowser.Api
|
namespace MediaBrowser.Api
|
||||||
@ -170,11 +171,11 @@ namespace MediaBrowser.Api
|
|||||||
MatchedTerm = hintInfo.MatchedTerm,
|
MatchedTerm = hintInfo.MatchedTerm,
|
||||||
DisplayMediaType = item.DisplayMediaType,
|
DisplayMediaType = item.DisplayMediaType,
|
||||||
RunTimeTicks = item.RunTimeTicks,
|
RunTimeTicks = item.RunTimeTicks,
|
||||||
ProductionYear = item.ProductionYear
|
ProductionYear = item.ProductionYear,
|
||||||
|
ChannelId = item.ChannelId,
|
||||||
|
EndDate = item.EndDate
|
||||||
};
|
};
|
||||||
|
|
||||||
result.ChannelId = item.ChannelId;
|
|
||||||
|
|
||||||
var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary);
|
var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary);
|
||||||
|
|
||||||
if (primaryImageTag != null)
|
if (primaryImageTag != null)
|
||||||
@ -186,12 +187,27 @@ namespace MediaBrowser.Api
|
|||||||
SetThumbImageInfo(result, item);
|
SetThumbImageInfo(result, item);
|
||||||
SetBackdropImageInfo(result, item);
|
SetBackdropImageInfo(result, item);
|
||||||
|
|
||||||
|
var program = item as LiveTvProgram;
|
||||||
|
if (program != null)
|
||||||
|
{
|
||||||
|
result.StartDate = program.StartDate;
|
||||||
|
}
|
||||||
|
|
||||||
var hasSeries = item as IHasSeries;
|
var hasSeries = item as IHasSeries;
|
||||||
if (hasSeries != null)
|
if (hasSeries != null)
|
||||||
{
|
{
|
||||||
result.Series = hasSeries.SeriesName;
|
result.Series = hasSeries.SeriesName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var series = item as Series;
|
||||||
|
if (series != null)
|
||||||
|
{
|
||||||
|
if (series.Status.HasValue)
|
||||||
|
{
|
||||||
|
result.Status = series.Status.Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var album = item as MusicAlbum;
|
var album = item as MusicAlbum;
|
||||||
|
|
||||||
if (album != null)
|
if (album != null)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace MediaBrowser.Model.Search
|
using System;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Model.Search
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class SearchHintResult
|
/// Class SearchHintResult
|
||||||
@ -95,12 +97,17 @@
|
|||||||
/// <value>The display type of the media.</value>
|
/// <value>The display type of the media.</value>
|
||||||
public string DisplayMediaType { get; set; }
|
public string DisplayMediaType { get; set; }
|
||||||
|
|
||||||
|
public DateTime? StartDate { get; set; }
|
||||||
|
public DateTime? EndDate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the series.
|
/// Gets or sets the series.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The series.</value>
|
/// <value>The series.</value>
|
||||||
public string Series { get; set; }
|
public string Series { get; set; }
|
||||||
|
|
||||||
|
public string Status { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the album.
|
/// Gets or sets the album.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -243,14 +243,16 @@ namespace Priority_Queue
|
|||||||
/// If queue is empty, result is undefined
|
/// If queue is empty, result is undefined
|
||||||
/// O(log n)
|
/// O(log n)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TItem Dequeue()
|
public bool TryDequeue(out TItem item)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
if (_numNodes <= 0)
|
if (_numNodes <= 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
|
item = default(TItem);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
if (!IsValidQueue())
|
if (!IsValidQueue())
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Queue has been corrupted (Did you update a node priority manually instead of calling UpdatePriority()?" +
|
throw new InvalidOperationException("Queue has been corrupted (Did you update a node priority manually instead of calling UpdatePriority()?" +
|
||||||
@ -260,7 +262,8 @@ namespace Priority_Queue
|
|||||||
|
|
||||||
TItem returnMe = _nodes[1];
|
TItem returnMe = _nodes[1];
|
||||||
Remove(returnMe);
|
Remove(returnMe);
|
||||||
return returnMe;
|
item = returnMe;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -24,7 +24,7 @@ namespace Priority_Queue
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
|
/// Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TItem Dequeue();
|
bool TryDequeue(out TItem item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes every node from the queue.
|
/// Removes every node from the queue.
|
||||||
|
@ -873,19 +873,12 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryDequeue(out Tuple<Guid, MetadataRefreshOptions> item)
|
|
||||||
{
|
|
||||||
item = _refreshQueue.Dequeue();
|
|
||||||
|
|
||||||
return item != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task StartProcessingRefreshQueue()
|
private async Task StartProcessingRefreshQueue()
|
||||||
{
|
{
|
||||||
Tuple<Guid, MetadataRefreshOptions> refreshItem;
|
Tuple<Guid, MetadataRefreshOptions> refreshItem;
|
||||||
var libraryManager = _libraryManagerFactory();
|
var libraryManager = _libraryManagerFactory();
|
||||||
|
|
||||||
while (TryDequeue(out refreshItem))
|
while (_refreshQueue.TryDequeue(out refreshItem))
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
{
|
{
|
||||||
|
@ -126,17 +126,25 @@ namespace Priority_Queue
|
|||||||
/// If queue is empty, throws an exception
|
/// If queue is empty, throws an exception
|
||||||
/// O(log n)
|
/// O(log n)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TItem Dequeue()
|
public bool TryDequeue(out TItem item)
|
||||||
{
|
{
|
||||||
lock (_queue)
|
lock (_queue)
|
||||||
{
|
{
|
||||||
if (_queue.Count <= 0)
|
if (_queue.Count <= 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
|
item = default(TItem);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleNode node = _queue.Dequeue();
|
SimpleNode node;
|
||||||
return node.Data;
|
if (_queue.TryDequeue(out node))
|
||||||
|
{
|
||||||
|
item = node.Data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = default(TItem);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,17 +103,17 @@ namespace MediaBrowser.Providers.Omdb
|
|||||||
ParseAdditionalMetadata(itemResult, result);
|
ParseAdditionalMetadata(itemResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> FetchEpisodeData<T>(MetadataResult<T> itemResult, int episodeNumber, int seasonNumber, string imdbId, string language, string country, CancellationToken cancellationToken)
|
public async Task<bool> FetchEpisodeData<T>(MetadataResult<T> itemResult, int episodeNumber, int seasonNumber, string episodeImdbId, string seriesImdbId, string language, string country, CancellationToken cancellationToken)
|
||||||
where T : BaseItem
|
where T : BaseItem
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(imdbId))
|
if (string.IsNullOrWhiteSpace(seriesImdbId))
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("imdbId");
|
throw new ArgumentNullException("seriesImdbId");
|
||||||
}
|
}
|
||||||
|
|
||||||
T item = itemResult.Item;
|
T item = itemResult.Item;
|
||||||
|
|
||||||
var seasonResult = await GetSeasonRootObject(imdbId, seasonNumber, cancellationToken).ConfigureAwait(false);
|
var seasonResult = await GetSeasonRootObject(seriesImdbId, seasonNumber, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (seasonResult == null)
|
if (seasonResult == null)
|
||||||
{
|
{
|
||||||
@ -122,12 +122,28 @@ namespace MediaBrowser.Providers.Omdb
|
|||||||
|
|
||||||
RootObject result = null;
|
RootObject result = null;
|
||||||
|
|
||||||
foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { }))
|
if (!string.IsNullOrWhiteSpace(episodeImdbId))
|
||||||
{
|
{
|
||||||
if (episode.Episode == episodeNumber)
|
foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { }))
|
||||||
{
|
{
|
||||||
result = episode;
|
if (string.Equals(episodeImdbId, episode.imdbID, StringComparison.OrdinalIgnoreCase))
|
||||||
break;
|
{
|
||||||
|
result = episode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, search by numbers
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { }))
|
||||||
|
{
|
||||||
|
if (episode.Episode == episodeNumber)
|
||||||
|
{
|
||||||
|
result = episode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,10 @@ namespace MediaBrowser.Providers.TV
|
|||||||
string seriesImdbId;
|
string seriesImdbId;
|
||||||
if (info.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId))
|
if (info.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId))
|
||||||
{
|
{
|
||||||
if (info.IndexNumber.HasValue &&
|
if (info.IndexNumber.HasValue && info.ParentIndexNumber.HasValue)
|
||||||
info.ParentIndexNumber.HasValue)
|
|
||||||
{
|
{
|
||||||
result.HasMetadata = await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager)
|
result.HasMetadata = await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _configurationManager)
|
||||||
.FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
|
.FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, info.GetProviderId(MetadataProviders.Imdb), seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ namespace SocketHttpListener.Net
|
|||||||
{
|
{
|
||||||
var supportsDirectSocketAccess = !context.Response.SendChunked && !isExpect100Continue && !secure;
|
var supportsDirectSocketAccess = !context.Response.SendChunked && !isExpect100Continue && !secure;
|
||||||
|
|
||||||
o_stream = new ResponseStream(stream, context.Response, _memoryStreamFactory, _textEncoding, _fileSystem, sock, supportsDirectSocketAccess);
|
o_stream = new ResponseStream(stream, context.Response, _memoryStreamFactory, _textEncoding, _fileSystem, sock, supportsDirectSocketAccess, _logger);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Model.Text;
|
using MediaBrowser.Model.Text;
|
||||||
using SocketHttpListener.Primitives;
|
using SocketHttpListener.Primitives;
|
||||||
@ -26,8 +27,9 @@ namespace SocketHttpListener.Net
|
|||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IAcceptSocket _socket;
|
private readonly IAcceptSocket _socket;
|
||||||
private readonly bool _supportsDirectSocketAccess;
|
private readonly bool _supportsDirectSocketAccess;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
internal ResponseStream(Stream stream, HttpListenerResponse response, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding, IFileSystem fileSystem, IAcceptSocket socket, bool supportsDirectSocketAccess)
|
internal ResponseStream(Stream stream, HttpListenerResponse response, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding, IFileSystem fileSystem, IAcceptSocket socket, bool supportsDirectSocketAccess, ILogger logger)
|
||||||
{
|
{
|
||||||
this.response = response;
|
this.response = response;
|
||||||
_memoryStreamFactory = memoryStreamFactory;
|
_memoryStreamFactory = memoryStreamFactory;
|
||||||
@ -35,6 +37,7 @@ namespace SocketHttpListener.Net
|
|||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_socket = socket;
|
_socket = socket;
|
||||||
_supportsDirectSocketAccess = supportsDirectSocketAccess;
|
_supportsDirectSocketAccess = supportsDirectSocketAccess;
|
||||||
|
_logger = logger;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,29 +312,34 @@ namespace SocketHttpListener.Net
|
|||||||
|
|
||||||
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !response.SendChunked)
|
//if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !response.SendChunked && response.ContentLength64 > 8192)
|
||||||
//{
|
//{
|
||||||
// return TransmitFileOverSocket(path, offset, count, cancellationToken);
|
// return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken);
|
||||||
//}
|
//}
|
||||||
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
|
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly byte[] _emptyBuffer = new byte[] { };
|
private readonly byte[] _emptyBuffer = new byte[] { };
|
||||||
private async Task TransmitFileOverSocket(string path, long offset, long count, CancellationToken cancellationToken)
|
private Task TransmitFileOverSocket(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
MemoryStream ms = GetHeaders(response, _memoryStreamFactory, false);
|
||||||
|
|
||||||
var buffer = new byte[] {};
|
byte[] buffer;
|
||||||
if (ms != null)
|
if (ms != null)
|
||||||
{
|
{
|
||||||
ms.Position = 0;
|
using (var msCopy = new MemoryStream())
|
||||||
|
{
|
||||||
byte[] msBuffer;
|
ms.CopyTo(msCopy);
|
||||||
_memoryStreamFactory.TryGetBuffer(ms, out msBuffer);
|
buffer = msCopy.ToArray();
|
||||||
buffer = msBuffer;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _socket.SendFile(path, buffer, _emptyBuffer, cancellationToken).ConfigureAwait(false);
|
_logger.Info("Socket sending file {0} {1}", path, response.ContentLength64);
|
||||||
|
return _socket.SendFile(path, buffer, _emptyBuffer, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user