mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 22:17:25 -04:00
support audio sync transcoding
This commit is contained in:
parent
24e1f9834a
commit
c93740461e
22 changed files with 157 additions and 47 deletions
|
@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
using System;
|
using System;
|
||||||
|
@ -85,7 +86,9 @@ namespace MediaBrowser.Api
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void DeleteEncodedMediaCache()
|
private void DeleteEncodedMediaCache()
|
||||||
{
|
{
|
||||||
foreach (var file in Directory.EnumerateFiles(_config.ApplicationPaths.TranscodingTempPath, "*", SearchOption.AllDirectories)
|
var path = Path.Combine(_config.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower());
|
||||||
|
|
||||||
|
foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
|
||||||
.ToList())
|
.ToList())
|
||||||
{
|
{
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
|
|
|
@ -119,7 +119,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private string GetOutputFilePath(StreamState state)
|
private string GetOutputFilePath(StreamState state)
|
||||||
{
|
{
|
||||||
var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath;
|
var folder = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower());
|
||||||
|
|
||||||
var outputFileExtension = GetOutputFileExtension(state);
|
var outputFileExtension = GetOutputFileExtension(state);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -65,7 +66,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
|
var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
|
||||||
|
|
||||||
file = Path.Combine(_appPaths.TranscodingTempPath, file);
|
file = Path.Combine(_appPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
|
return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
||||||
|
|
||||||
file = Path.Combine(_appPaths.TranscodingTempPath, file);
|
file = Path.Combine(_appPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
|
return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using ServiceStack;
|
using ServiceStack;
|
||||||
using System;
|
using System;
|
||||||
|
@ -70,7 +71,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
|
||||||
|
|
||||||
file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, file);
|
file = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower(), file);
|
||||||
|
|
||||||
return ResultFactory.GetStaticFileResult(Request, file);
|
return ResultFactory.GetStaticFileResult(Request, file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,7 @@
|
||||||
<Compile Include="LiveTv\TimerInfo.cs" />
|
<Compile Include="LiveTv\TimerInfo.cs" />
|
||||||
<Compile Include="Localization\ILocalizationManager.cs" />
|
<Compile Include="Localization\ILocalizationManager.cs" />
|
||||||
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
|
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
|
||||||
|
<Compile Include="MediaEncoding\EncodingJobOptions.cs" />
|
||||||
<Compile Include="MediaEncoding\IEncodingManager.cs" />
|
<Compile Include="MediaEncoding\IEncodingManager.cs" />
|
||||||
<Compile Include="MediaEncoding\ImageEncodingOptions.cs" />
|
<Compile Include="MediaEncoding\ImageEncodingOptions.cs" />
|
||||||
<Compile Include="MediaEncoding\IMediaEncoder.cs" />
|
<Compile Include="MediaEncoding\IMediaEncoder.cs" />
|
||||||
|
|
|
@ -96,5 +96,16 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
/// <param name="ticks">The ticks.</param>
|
/// <param name="ticks">The ticks.</param>
|
||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
string GetTimeParameter(long ticks);
|
string GetTimeParameter(long ticks);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encodes the audio.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The options.</param>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task<string> EncodeAudio(EncodingJobOptions options,
|
||||||
|
IProgress<double> progress,
|
||||||
|
CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,8 @@ namespace MediaBrowser.LocalMetadata.Savers
|
||||||
"Website",
|
"Website",
|
||||||
"Zap2ItId",
|
"Zap2ItId",
|
||||||
"CollectionItems",
|
"CollectionItems",
|
||||||
"PlaylistItems"
|
"PlaylistItems",
|
||||||
|
"Shares"
|
||||||
|
|
||||||
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
using MediaBrowser.Common.IO;
|
||||||
|
using MediaBrowser.Controller.Channels;
|
||||||
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -51,11 +57,26 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
public string Version { get; private set; }
|
public string Version { get; private set; }
|
||||||
|
|
||||||
public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version)
|
protected readonly IServerConfigurationManager ConfigurationManager;
|
||||||
|
protected readonly IFileSystem FileSystem;
|
||||||
|
protected readonly ILiveTvManager LiveTvManager;
|
||||||
|
protected readonly IIsoManager IsoManager;
|
||||||
|
protected readonly ILibraryManager LibraryManager;
|
||||||
|
protected readonly IChannelManager ChannelManager;
|
||||||
|
protected readonly ISessionManager SessionManager;
|
||||||
|
|
||||||
|
public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
Version = version;
|
Version = version;
|
||||||
|
ConfigurationManager = configurationManager;
|
||||||
|
FileSystem = fileSystem;
|
||||||
|
LiveTvManager = liveTvManager;
|
||||||
|
IsoManager = isoManager;
|
||||||
|
LibraryManager = libraryManager;
|
||||||
|
ChannelManager = channelManager;
|
||||||
|
SessionManager = sessionManager;
|
||||||
FFProbePath = ffProbePath;
|
FFProbePath = ffProbePath;
|
||||||
FFMpegPath = ffMpegPath;
|
FFMpegPath = ffMpegPath;
|
||||||
}
|
}
|
||||||
|
@ -511,5 +532,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
throw new ApplicationException(msg);
|
throw new ApplicationException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<string> EncodeAudio(EncodingJobOptions options,
|
||||||
|
IProgress<double> progress,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var job = await new AudioEncoder(this,
|
||||||
|
_logger,
|
||||||
|
ConfigurationManager,
|
||||||
|
FileSystem,
|
||||||
|
LiveTvManager,
|
||||||
|
IsoManager,
|
||||||
|
LibraryManager,
|
||||||
|
ChannelManager,
|
||||||
|
SessionManager)
|
||||||
|
.Start(options, progress, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await job.TaskCompletionSource.Task.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return job.OutputFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,12 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
||||||
<Compile Include="Configuration\EncodingConfigurationFactory.cs" />
|
<Compile Include="Configuration\EncodingConfigurationFactory.cs" />
|
||||||
|
<Compile Include="Encoder\AudioEncoder.cs" />
|
||||||
|
<Compile Include="Encoder\BaseEncoder.cs" />
|
||||||
|
<Compile Include="Encoder\EncodingJob.cs" />
|
||||||
|
<Compile Include="Encoder\EncodingJobFactory.cs" />
|
||||||
<Compile Include="Encoder\EncodingUtils.cs" />
|
<Compile Include="Encoder\EncodingUtils.cs" />
|
||||||
|
<Compile Include="Encoder\JobLogger.cs" />
|
||||||
<Compile Include="Encoder\MediaEncoder.cs" />
|
<Compile Include="Encoder\MediaEncoder.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Subtitles\ISubtitleParser.cs" />
|
<Compile Include="Subtitles\ISubtitleParser.cs" />
|
||||||
|
|
|
@ -109,7 +109,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
ItemId = options.ItemId,
|
ItemId = options.ItemId,
|
||||||
MediaType = DlnaProfileType.Audio,
|
MediaType = DlnaProfileType.Audio,
|
||||||
MediaSource = item,
|
MediaSource = item,
|
||||||
RunTimeTicks = item.RunTimeTicks
|
RunTimeTicks = item.RunTimeTicks,
|
||||||
|
Context = options.Context
|
||||||
};
|
};
|
||||||
|
|
||||||
int? maxBitrateSetting = options.GetMaxBitrate();
|
int? maxBitrateSetting = options.GetMaxBitrate();
|
||||||
|
@ -240,7 +241,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
ItemId = options.ItemId,
|
ItemId = options.ItemId,
|
||||||
MediaType = DlnaProfileType.Video,
|
MediaType = DlnaProfileType.Video,
|
||||||
MediaSource = item,
|
MediaSource = item,
|
||||||
RunTimeTicks = item.RunTimeTicks
|
RunTimeTicks = item.RunTimeTicks,
|
||||||
|
Context = options.Context
|
||||||
};
|
};
|
||||||
|
|
||||||
int? audioStreamIndex = options.AudioStreamIndex ?? item.DefaultAudioStreamIndex;
|
int? audioStreamIndex = options.AudioStreamIndex ?? item.DefaultAudioStreamIndex;
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
public string ItemId { get; set; }
|
public string ItemId { get; set; }
|
||||||
|
|
||||||
public PlayMethod PlayMethod { get; set; }
|
public PlayMethod PlayMethod { get; set; }
|
||||||
|
public EncodingContext Context { get; set; }
|
||||||
|
|
||||||
public DlnaProfileType MediaType { get; set; }
|
public DlnaProfileType MediaType { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MediaBrowser.Model.Sync
|
||||||
/// Gets or sets the unique identifier.
|
/// Gets or sets the unique identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The unique identifier.</value>
|
/// <value>The unique identifier.</value>
|
||||||
public string UniqueId { get; set; }
|
public string Id { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the item identifier.
|
/// Gets or sets the item identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -9,12 +9,12 @@ using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
|
using MediaBrowser.Model.Users;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Users;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Devices
|
namespace MediaBrowser.Server.Implementations.Devices
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
@ -21,6 +22,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
private Timer _timer;
|
private Timer _timer;
|
||||||
private readonly TimeSpan _frequency = TimeSpan.FromHours(24);
|
private readonly TimeSpan _frequency = TimeSpan.FromHours(24);
|
||||||
|
@ -65,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await new UsageReporter(_applicationHost, _networkManager, _httpClient)
|
await new UsageReporter(_applicationHost, _networkManager, _httpClient, _userManager)
|
||||||
.ReportAppUsage(client, CancellationToken.None)
|
.ReportAppUsage(client, CancellationToken.None)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await new UsageReporter(_applicationHost, _networkManager, _httpClient)
|
await new UsageReporter(_applicationHost, _networkManager, _httpClient, _userManager)
|
||||||
.ReportServerUsage(CancellationToken.None)
|
.ReportServerUsage(CancellationToken.None)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Connect;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -12,13 +16,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
private readonly IApplicationHost _applicationHost;
|
private readonly IApplicationHost _applicationHost;
|
||||||
private readonly INetworkManager _networkManager;
|
private readonly INetworkManager _networkManager;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
private const string MbAdminUrl = "http://www.mb3admin.com/admin/";
|
private const string MbAdminUrl = "http://www.mb3admin.com/admin/";
|
||||||
|
|
||||||
public UsageReporter(IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient)
|
public UsageReporter(IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient, IUserManager userManager)
|
||||||
{
|
{
|
||||||
_applicationHost = applicationHost;
|
_applicationHost = applicationHost;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ReportServerUsage(CancellationToken cancellationToken)
|
public Task ReportServerUsage(CancellationToken cancellationToken)
|
||||||
|
@ -38,6 +44,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
{ "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()}
|
{ "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var users = _userManager.Users.ToList();
|
||||||
|
|
||||||
|
data["localusers"] = users.Count(i => !i.ConnectLinkType.HasValue).ToString(CultureInfo.InvariantCulture);
|
||||||
|
data["guests"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest).ToString(CultureInfo.InvariantCulture);
|
||||||
|
data["linkedusers"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.LinkedUser).ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken);
|
return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1556,14 +1556,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
// Types cannot be overridden, so go from the top down until we find a configured content type
|
// Types cannot be overridden, so go from the top down until we find a configured content type
|
||||||
|
|
||||||
var type = GetTopFolderContentType(item);
|
var type = GetInheritedContentType(item);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(type))
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = GetInheritedContentType(item);
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(type))
|
if (!string.IsNullOrWhiteSpace(type))
|
||||||
{
|
{
|
||||||
|
@ -1575,6 +1568,13 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
public string GetInheritedContentType(BaseItem item)
|
public string GetInheritedContentType(BaseItem item)
|
||||||
{
|
{
|
||||||
|
var type = GetTopFolderContentType(item);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(type))
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
return item.Parents
|
return item.Parents
|
||||||
.Select(GetConfiguredContentType)
|
.Select(GetConfiguredContentType)
|
||||||
.LastOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
.LastOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
||||||
|
|
|
@ -1317,5 +1317,6 @@
|
||||||
"NameSeasonUnknown": "Season Unknown",
|
"NameSeasonUnknown": "Season Unknown",
|
||||||
"NameSeasonNumber": "Season {0}",
|
"NameSeasonNumber": "Season {0}",
|
||||||
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)",
|
"LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)",
|
||||||
|
"TabJobs": "Jobs",
|
||||||
"TabSyncJobs": "Sync Jobs"
|
"TabSyncJobs": "Sync Jobs"
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
public DeviceProfile GetDeviceProfile(SyncTarget target)
|
public DeviceProfile GetDeviceProfile(SyncTarget target)
|
||||||
{
|
{
|
||||||
return new DeviceProfile();
|
var caps = _deviceManager.GetCapabilities(target.Id);
|
||||||
|
|
||||||
|
return caps == null || caps.DeviceProfile == null ? new DeviceProfile() : caps.DeviceProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Sync;
|
using MediaBrowser.Controller.Sync;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
|
@ -28,8 +29,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly ITVSeriesManager _tvSeriesManager;
|
private readonly ITVSeriesManager _tvSeriesManager;
|
||||||
|
private readonly IMediaEncoder MediaEncoder;
|
||||||
|
|
||||||
public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager)
|
public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_syncRepo = syncRepo;
|
_syncRepo = syncRepo;
|
||||||
|
@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_tvSeriesManager = tvSeriesManager;
|
_tvSeriesManager = tvSeriesManager;
|
||||||
|
MediaEncoder = mediaEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EnsureJobItems(SyncJob job)
|
public async Task EnsureJobItems(SyncJob job)
|
||||||
|
@ -392,7 +395,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
var options = new VideoOptions
|
var options = new VideoOptions
|
||||||
{
|
{
|
||||||
Context = EncodingContext.Streaming,
|
Context = EncodingContext.Static,
|
||||||
ItemId = item.Id.ToString("N"),
|
ItemId = item.Id.ToString("N"),
|
||||||
DeviceId = jobItem.TargetId,
|
DeviceId = jobItem.TargetId,
|
||||||
Profile = profile,
|
Profile = profile,
|
||||||
|
@ -406,7 +409,10 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
if (streamInfo.PlayMethod == PlayMethod.Transcode)
|
if (streamInfo.PlayMethod == PlayMethod.Transcode)
|
||||||
{
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Converting;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
||||||
|
//jobItem.OutputPath = await MediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -418,12 +424,12 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
|
jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Transcode
|
|
||||||
jobItem.OutputPath = mediaSource.Path;
|
|
||||||
|
|
||||||
jobItem.Progress = 50;
|
jobItem.Progress = 50;
|
||||||
jobItem.Status = SyncJobItemStatus.Transferring;
|
jobItem.Status = SyncJobItemStatus.Transferring;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
@ -433,7 +439,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
var options = new AudioOptions
|
var options = new AudioOptions
|
||||||
{
|
{
|
||||||
Context = EncodingContext.Streaming,
|
Context = EncodingContext.Static,
|
||||||
ItemId = item.Id.ToString("N"),
|
ItemId = item.Id.ToString("N"),
|
||||||
DeviceId = jobItem.TargetId,
|
DeviceId = jobItem.TargetId,
|
||||||
Profile = profile,
|
Profile = profile,
|
||||||
|
@ -447,7 +453,10 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
if (streamInfo.PlayMethod == PlayMethod.Transcode)
|
if (streamInfo.PlayMethod == PlayMethod.Transcode)
|
||||||
{
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Converting;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
||||||
|
jobItem.OutputPath = await MediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -459,12 +468,12 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
|
jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Transcode
|
|
||||||
jobItem.OutputPath = mediaSource.Path;
|
|
||||||
|
|
||||||
jobItem.Progress = 50;
|
jobItem.Progress = 50;
|
||||||
jobItem.Status = SyncJobItemStatus.Transferring;
|
jobItem.Status = SyncJobItemStatus.Transferring;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
|
@ -8,6 +8,7 @@ using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Sync;
|
using MediaBrowser.Controller.Sync;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
|
@ -36,10 +37,11 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
private readonly Func<IDtoService> _dtoService;
|
private readonly Func<IDtoService> _dtoService;
|
||||||
private readonly IApplicationHost _appHost;
|
private readonly IApplicationHost _appHost;
|
||||||
private readonly ITVSeriesManager _tvSeriesManager;
|
private readonly ITVSeriesManager _tvSeriesManager;
|
||||||
|
private readonly Func<IMediaEncoder> MediaEncoder;
|
||||||
|
|
||||||
private ISyncProvider[] _providers = { };
|
private ISyncProvider[] _providers = { };
|
||||||
|
|
||||||
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager)
|
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
|
@ -49,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_tvSeriesManager = tvSeriesManager;
|
_tvSeriesManager = tvSeriesManager;
|
||||||
|
MediaEncoder = mediaEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddParts(IEnumerable<ISyncProvider> providers)
|
public void AddParts(IEnumerable<ISyncProvider> providers)
|
||||||
|
@ -58,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
|
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
|
||||||
{
|
{
|
||||||
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
|
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
|
||||||
|
|
||||||
var user = _userManager.GetUserById(request.UserId);
|
var user = _userManager.GetUserById(request.UserId);
|
||||||
|
|
||||||
|
@ -162,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
|
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
|
||||||
|
|
||||||
var user = _userManager.GetUserById(job.UserId);
|
var user = _userManager.GetUserById(job.UserId);
|
||||||
|
|
||||||
|
@ -392,7 +395,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
await _repo.Update(jobItem).ConfigureAwait(false);
|
await _repo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
||||||
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager);
|
var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, MediaEncoder());
|
||||||
|
|
||||||
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
|
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using MediaBrowser.Common.ScheduledTasks;
|
using MediaBrowser.Common.ScheduledTasks;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Sync;
|
using MediaBrowser.Controller.Sync;
|
||||||
using MediaBrowser.Controller.TV;
|
using MediaBrowser.Controller.TV;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
@ -18,8 +19,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly ITVSeriesManager _tvSeriesManager;
|
private readonly ITVSeriesManager _tvSeriesManager;
|
||||||
|
private readonly IMediaEncoder MediaEncoder;
|
||||||
|
|
||||||
public SyncScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager)
|
public SyncScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager, ITVSeriesManager tvSeriesManager, IMediaEncoder mediaEncoder)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_syncRepo = syncRepo;
|
_syncRepo = syncRepo;
|
||||||
|
@ -27,6 +29,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_tvSeriesManager = tvSeriesManager;
|
_tvSeriesManager = tvSeriesManager;
|
||||||
|
MediaEncoder = mediaEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
@ -49,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager, _tvSeriesManager).Sync(progress,
|
return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager, _tvSeriesManager, MediaEncoder).Sync(progress,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -476,16 +476,13 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
var innerProgress = new ActionableProgress<double>();
|
var innerProgress = new ActionableProgress<double>();
|
||||||
innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
|
innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
|
||||||
|
|
||||||
await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
|
|
||||||
progress.Report(90);
|
|
||||||
|
|
||||||
ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder);
|
ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder);
|
||||||
RegisterSingleInstance(ImageProcessor);
|
RegisterSingleInstance(ImageProcessor);
|
||||||
|
|
||||||
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
|
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
|
||||||
RegisterSingleInstance(TVSeriesManager);
|
RegisterSingleInstance(TVSeriesManager);
|
||||||
|
|
||||||
SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager);
|
SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder);
|
||||||
RegisterSingleInstance(SyncManager);
|
RegisterSingleInstance(SyncManager);
|
||||||
|
|
||||||
DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this);
|
DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this);
|
||||||
|
@ -547,6 +544,9 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository);
|
ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository);
|
||||||
RegisterSingleInstance(ChapterManager);
|
RegisterSingleInstance(ChapterManager);
|
||||||
|
|
||||||
|
await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
|
||||||
|
progress.Report(90);
|
||||||
|
|
||||||
EncodingManager = new EncodingManager(FileSystemManager, Logger,
|
EncodingManager = new EncodingManager(FileSystemManager, Logger,
|
||||||
MediaEncoder, ChapterManager);
|
MediaEncoder, ChapterManager);
|
||||||
RegisterSingleInstance(EncodingManager);
|
RegisterSingleInstance(EncodingManager);
|
||||||
|
@ -591,7 +591,18 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
|
|
||||||
new FFmpegValidator(Logger, ApplicationPaths).Validate(info);
|
new FFmpegValidator(Logger, ApplicationPaths).Validate(info);
|
||||||
|
|
||||||
MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, info.EncoderPath, info.ProbePath, info.Version);
|
MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
|
||||||
|
JsonSerializer,
|
||||||
|
info.EncoderPath,
|
||||||
|
info.ProbePath,
|
||||||
|
info.Version,
|
||||||
|
ServerConfigurationManager,
|
||||||
|
FileSystemManager,
|
||||||
|
LiveTvManager,
|
||||||
|
IsoManager,
|
||||||
|
LibraryManager,
|
||||||
|
ChannelManager,
|
||||||
|
SessionManager);
|
||||||
RegisterSingleInstance(MediaEncoder);
|
RegisterSingleInstance(MediaEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue