unify encodng param creation

This commit is contained in:
Luke Pulverenti 2017-03-19 14:59:05 -04:00
parent 59ac045c6b
commit 38e05b11e2
13 changed files with 180 additions and 295 deletions

View File

@ -3204,6 +3204,40 @@ namespace Emby.Server.Implementations.Data
}
}
private bool IsAlphaNumeric(string str)
{
if (string.IsNullOrWhiteSpace(str))
return false;
for (int i = 0; i < str.Length; i++)
{
if (!(char.IsLetter(str[i])) && (!(char.IsNumber(str[i]))))
return false;
}
return true;
}
private bool IsValidType(string value)
{
return IsAlphaNumeric(value);
}
private bool IsValidMediaType(string value)
{
return IsAlphaNumeric(value);
}
private bool IsValidId(string value)
{
return IsAlphaNumeric(value);
}
private bool IsValidPersonType(string value)
{
return IsAlphaNumeric(value);
}
private List<string> GetWhereClauses(InternalItemsQuery query, IStatement statement, string paramSuffix = "")
{
if (query.IsResumable ?? false)
@ -3423,9 +3457,9 @@ namespace Emby.Server.Implementations.Data
statement.TryBind("@ChannelId", query.ChannelIds[0]);
}
}
if (query.ChannelIds.Length > 1)
else if (query.ChannelIds.Length > 1)
{
var inClause = string.Join(",", query.ChannelIds.Select(i => "'" + i + "'").ToArray());
var inClause = string.Join(",", query.ChannelIds.Where(IsValidId).Select(i => "'" + i + "'").ToArray());
whereClauses.Add(string.Format("ChannelId in ({0})", inClause));
}
@ -4157,17 +4191,18 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("(IsVirtualItem=0 OR PremiereDate < DATETIME('now'))");
}
}
if (query.MediaTypes.Length == 1)
var queryMediaTypes = query.MediaTypes.Where(IsValidMediaType).ToArray();
if (queryMediaTypes.Length == 1)
{
whereClauses.Add("MediaType=@MediaTypes");
if (statement != null)
{
statement.TryBind("@MediaTypes", query.MediaTypes[0]);
statement.TryBind("@MediaTypes", queryMediaTypes[0]);
}
}
if (query.MediaTypes.Length > 1)
else if (queryMediaTypes.Length > 1)
{
var val = string.Join(",", query.MediaTypes.Select(i => "'" + i + "'").ToArray());
var val = string.Join(",", queryMediaTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add("MediaType in (" + val + ")");
}
@ -4273,7 +4308,9 @@ namespace Emby.Server.Implementations.Data
//var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0;
var enableItemsByName = query.IncludeItemsByName ?? false;
if (query.TopParentIds.Length == 1)
var queryTopParentIds = query.TopParentIds.Where(IsValidId).ToArray();
if (queryTopParentIds.Length == 1)
{
if (enableItemsByName)
{
@ -4289,12 +4326,12 @@ namespace Emby.Server.Implementations.Data
}
if (statement != null)
{
statement.TryBind("@TopParentId", query.TopParentIds[0]);
statement.TryBind("@TopParentId", queryTopParentIds[0]);
}
}
if (query.TopParentIds.Length > 1)
else if (queryTopParentIds.Length > 1)
{
var val = string.Join(",", query.TopParentIds.Select(i => "'" + i + "'").ToArray());
var val = string.Join(",", queryTopParentIds.Select(i => "'" + i + "'").ToArray());
if (enableItemsByName)
{
@ -4544,7 +4581,7 @@ namespace Emby.Server.Implementations.Data
return result;
}
return new[] { value };
return new[] { value }.Where(IsValidType);
}
public async Task DeleteItem(Guid id, CancellationToken cancellationToken)
@ -4696,31 +4733,35 @@ namespace Emby.Server.Implementations.Data
statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToGuidParamValue());
}
}
if (query.PersonTypes.Count == 1)
var queryPersonTypes = query.PersonTypes.Where(IsValidPersonType).ToList();
if (queryPersonTypes.Count == 1)
{
whereClauses.Add("PersonType=@PersonType");
if (statement != null)
{
statement.TryBind("@PersonType", query.PersonTypes[0]);
statement.TryBind("@PersonType", queryPersonTypes[0]);
}
}
if (query.PersonTypes.Count > 1)
else if (queryPersonTypes.Count > 1)
{
var val = string.Join(",", query.PersonTypes.Select(i => "'" + i + "'").ToArray());
var val = string.Join(",", queryPersonTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add("PersonType in (" + val + ")");
}
if (query.ExcludePersonTypes.Count == 1)
var queryExcludePersonTypes = query.ExcludePersonTypes.Where(IsValidPersonType).ToList();
if (queryExcludePersonTypes.Count == 1)
{
whereClauses.Add("PersonType<>@PersonType");
if (statement != null)
{
statement.TryBind("@PersonType", query.ExcludePersonTypes[0]);
statement.TryBind("@PersonType", queryExcludePersonTypes[0]);
}
}
if (query.ExcludePersonTypes.Count > 1)
else if (queryExcludePersonTypes.Count > 1)
{
var val = string.Join(",", query.ExcludePersonTypes.Select(i => "'" + i + "'").ToArray());
var val = string.Join(",", queryExcludePersonTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add("PersonType not in (" + val + ")");
}

View File

@ -85,7 +85,6 @@
<Compile Include="FileOrganization\OrganizerScheduledTask.cs" />
<Compile Include="FileOrganization\TvFolderOrganizer.cs" />
<Compile Include="HttpServer\FileWriter.cs" />
<Compile Include="HttpServer\GetSwaggerResource.cs" />
<Compile Include="HttpServer\HttpListenerHost.cs" />
<Compile Include="HttpServer\HttpResultFactory.cs" />
<Compile Include="HttpServer\LoggerUtils.cs" />
@ -103,7 +102,6 @@
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
<Compile Include="HttpServer\StreamWriter.cs" />
<Compile Include="HttpServer\SwaggerService.cs" />
<Compile Include="Images\BaseDynamicImageProvider.cs" />
<Compile Include="IO\FileRefresher.cs" />
<Compile Include="IO\MbLinkShortcutHandler.cs" />

View File

@ -1,17 +0,0 @@
using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer
{
/// <summary>
/// Class GetDashboardResource
/// </summary>
[Route("/swagger-ui/{ResourceName*}", "GET")]
public class GetSwaggerResource
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string ResourceName { get; set; }
}
}

View File

@ -1,47 +0,0 @@
using MediaBrowser.Controller;
using MediaBrowser.Controller.Net;
using System.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer
{
public class SwaggerService : IService, IRequiresRequest
{
private readonly IServerApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem;
public SwaggerService(IServerApplicationPaths appPaths, IFileSystem fileSystem, IHttpResultFactory resultFactory)
{
_appPaths = appPaths;
_fileSystem = fileSystem;
_resultFactory = resultFactory;
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get(GetSwaggerResource request)
{
var swaggerDirectory = Path.Combine(_appPaths.ApplicationResourcesPath, "swagger-ui");
var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', _fileSystem.DirectorySeparatorChar));
return _resultFactory.GetStaticFileResult(Request, requestedFile).Result;
}
/// <summary>
/// Gets or sets the result factory.
/// </summary>
/// <value>The result factory.</value>
private readonly IHttpResultFactory _resultFactory;
/// <summary>
/// Gets or sets the request context.
/// </summary>
/// <value>The request context.</value>
public IRequest Request { get; set; }
}
}

View File

@ -6,11 +6,8 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using System;
using System.IO;
using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Playback.Progressive
@ -95,116 +92,7 @@ namespace MediaBrowser.Api.Playback.Progressive
{
var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
// Get the output codec name
var videoCodec = EncodingHelper.GetVideoEncoder(state, encodingOptions);
var format = string.Empty;
var keyFrame = string.Empty;
if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase))
{
// Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js
format = " -f mp4 -movflags frag_keyframe+empty_moov";
}
var threads = EncodingHelper.GetNumberOfThreads(state, encodingOptions, string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase));
var inputModifier = EncodingHelper.GetInputModifier(state, encodingOptions);
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7}{8} -y \"{9}\"",
inputModifier,
EncodingHelper.GetInputArgument(state, encodingOptions),
keyFrame,
EncodingHelper.GetMapArgs(state),
GetVideoArguments(state, videoCodec),
threads,
EncodingHelper.GetProgressiveVideoAudioArguments(state, encodingOptions),
EncodingHelper.GetSubtitleEmbedArguments(state),
format,
outputPath
).Trim();
}
/// <summary>
/// Gets video arguments to pass to ffmpeg
/// </summary>
/// <param name="state">The state.</param>
/// <param name="videoCodec">The video codec.</param>
/// <returns>System.String.</returns>
private string GetVideoArguments(StreamState state, string videoCodec)
{
var args = "-codec:v:0 " + videoCodec;
if (state.EnableMpegtsM2TsMode)
{
args += " -mpegts_m2ts_mode 1";
}
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (state.VideoStream != null && EncodingHelper.IsH264(state.VideoStream) && string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
{
args += " -bsf:v h264_mp4toannexb";
}
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
{
args += " -copyts -avoid_negative_ts disabled -start_at_zero";
}
if (!state.RunTimeTicks.HasValue)
{
args += " -flags -global_header -fflags +genpts";
}
return args;
}
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
5.ToString(UsCulture));
args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
var hasCopyTs = false;
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
var outputSizeParam = EncodingHelper.GetOutputSizeParam(state, videoCodec);
args += outputSizeParam;
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
}
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
{
if (!hasCopyTs)
{
args += " -copyts";
}
args += " -avoid_negative_ts disabled -start_at_zero";
}
var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
var qualityParam = EncodingHelper.GetVideoQualityParam(state, videoCodec, encodingOptions, GetDefaultH264Preset());
if (!string.IsNullOrEmpty(qualityParam))
{
args += " " + qualityParam.Trim();
}
// This is for internal graphical subs
if (hasGraphicalSubs)
{
args += EncodingHelper.GetGraphicalSubtitleParam(state, videoCodec);
}
if (!state.RunTimeTicks.HasValue)
{
args += " -flags -global_header";
}
return args;
return EncodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, outputPath, GetDefaultH264Preset());
}
}
}

View File

@ -134,7 +134,6 @@ namespace MediaBrowser.Api.Playback
public string MimeType { get; set; }
public bool EstimateContentLength { get; set; }
public bool EnableMpegtsM2TsMode { get; set; }
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
public long? EncodingDurationTicks { get; set; }

View File

@ -1773,6 +1773,114 @@ namespace MediaBrowser.Controller.MediaEncoding
return args;
}
public string GetProgressiveVideoFullCommandLine(EncodingJobInfo state, EncodingOptions encodingOptions, string outputPath, string defaultH264Preset)
{
// Get the output codec name
var videoCodec = GetVideoEncoder(state, encodingOptions);
var format = string.Empty;
var keyFrame = string.Empty;
if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase) &&
state.BaseRequest.Context == EncodingContext.Streaming)
{
// Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js
format = " -f mp4 -movflags frag_keyframe+empty_moov";
}
var threads = GetNumberOfThreads(state, encodingOptions, string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase));
var inputModifier = GetInputModifier(state, encodingOptions);
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7}{8} -y \"{9}\"",
inputModifier,
GetInputArgument(state, encodingOptions),
keyFrame,
GetMapArgs(state),
GetProgressiveVideoArguments(state, encodingOptions, videoCodec, defaultH264Preset),
threads,
GetProgressiveVideoAudioArguments(state, encodingOptions),
GetSubtitleEmbedArguments(state),
format,
outputPath
).Trim();
}
public string GetProgressiveVideoArguments(EncodingJobInfo state, EncodingOptions encodingOptions, string videoCodec, string defaultH264Preset)
{
var args = "-codec:v:0 " + videoCodec;
if (state.EnableMpegtsM2TsMode)
{
args += " -mpegts_m2ts_mode 1";
}
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (state.VideoStream != null && IsH264(state.VideoStream) && string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
{
args += " -bsf:v h264_mp4toannexb";
}
if (state.RunTimeTicks.HasValue && state.BaseRequest.CopyTimestamps)
{
args += " -copyts -avoid_negative_ts disabled -start_at_zero";
}
if (!state.RunTimeTicks.HasValue)
{
args += " -flags -global_header -fflags +genpts";
}
return args;
}
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
5.ToString(_usCulture));
args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.BaseRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
var hasCopyTs = false;
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
var outputSizeParam = GetOutputSizeParam(state, videoCodec);
args += outputSizeParam;
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
}
if (state.RunTimeTicks.HasValue && state.BaseRequest.CopyTimestamps)
{
if (!hasCopyTs)
{
args += " -copyts";
}
args += " -avoid_negative_ts disabled -start_at_zero";
}
var qualityParam = GetVideoQualityParam(state, videoCodec, encodingOptions, defaultH264Preset);
if (!string.IsNullOrEmpty(qualityParam))
{
args += " " + qualityParam.Trim();
}
// This is for internal graphical subs
if (hasGraphicalSubs)
{
args += GetGraphicalSubtitleParam(state, videoCodec);
}
if (!state.RunTimeTicks.HasValue)
{
args += " -flags -global_header";
}
return args;
}
public string GetProgressiveVideoAudioArguments(EncodingJobInfo state, EncodingOptions encodingOptions)
{
// If the video doesn't have an audio stream, return a default.

View File

@ -53,6 +53,8 @@ namespace MediaBrowser.Controller.MediaEncoding
public string InputContainer { get; set; }
public IsoType? IsoType { get; set; }
public bool EnableMpegtsM2TsMode { get; set; }
public BaseEncodingJobOptions BaseRequest { get; set; }
public long? StartTimeTicks

View File

@ -14,7 +14,6 @@ namespace MediaBrowser.Controller.MediaEncoding
public string AudioCodec { get; set; }
public DeviceProfile DeviceProfile { get; set; }
public EncodingContext Context { get; set; }
public bool ReadInputAtNativeFramerate { get; set; }
@ -214,9 +213,12 @@ namespace MediaBrowser.Controller.MediaEncoding
[ApiMember(Name = "VideoStreamIndex", Description = "Optional. The index of the video stream to use. If omitted the first video stream will be used.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? VideoStreamIndex { get; set; }
public EncodingContext Context { get; set; }
public BaseEncodingJobOptions()
{
EnableAutoStreamCopy = true;
Context = EncodingContext.Streaming;
}
}
}

View File

@ -17,7 +17,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
}
protected override Task<string> GetCommandLineArguments(EncodingJob state)
protected override string GetCommandLineArguments(EncodingJob state)
{
var audioTranscodeParams = new List<string>();
@ -78,7 +78,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
mapArgs,
metadata).Trim();
return Task.FromResult(result);
return result;
}
protected override string GetOutputFileExtension(EncodingJob state)

View File

@ -76,7 +76,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
await AcquireResources(encodingJob, cancellationToken).ConfigureAwait(false);
var commandLineArgs = await GetCommandLineArguments(encodingJob).ConfigureAwait(false);
var commandLineArgs = GetCommandLineArguments(encodingJob);
var process = ProcessFactory.Create(new ProcessOptions
{
@ -265,7 +265,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
}
protected abstract Task<string> GetCommandLineArguments(EncodingJob job);
protected abstract string GetCommandLineArguments(EncodingJob job);
private string GetOutputFilePath(EncodingJob state)
{

View File

@ -36,7 +36,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
public string MimeType { get; set; }
public bool EstimateContentLength { get; set; }
public bool EnableMpegtsM2TsMode { get; set; }
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
public long? EncodingDurationTicks { get; set; }
public string LiveStreamId { get; set; }

View File

@ -18,100 +18,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
}
protected override async Task<string> GetCommandLineArguments(EncodingJob state)
protected override string GetCommandLineArguments(EncodingJob state)
{
// Get the output codec name
var encodingOptions = GetEncodingOptions();
var videoCodec = EncodingHelper.GetVideoEncoder(state, encodingOptions);
var format = string.Empty;
var keyFrame = string.Empty;
if (string.Equals(Path.GetExtension(state.OutputFilePath), ".mp4", StringComparison.OrdinalIgnoreCase) &&
state.Options.Context == EncodingContext.Streaming)
{
// Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js
format = " -f mp4 -movflags frag_keyframe+empty_moov";
}
var threads = EncodingHelper.GetNumberOfThreads(state, encodingOptions, string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase));
var inputModifier = EncodingHelper.GetInputModifier(state, encodingOptions);
var videoArguments = await GetVideoArguments(state, videoCodec).ConfigureAwait(false);
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"",
inputModifier,
EncodingHelper.GetInputArgument(state, encodingOptions),
keyFrame,
EncodingHelper.GetMapArgs(state),
videoArguments,
threads,
EncodingHelper.GetProgressiveVideoAudioArguments(state, encodingOptions),
format,
state.OutputFilePath
).Trim();
}
/// <summary>
/// Gets video arguments to pass to ffmpeg
/// </summary>
/// <param name="state">The state.</param>
/// <param name="videoCodec">The video codec.</param>
/// <returns>System.String.</returns>
private async Task<string> GetVideoArguments(EncodingJob state, string videoCodec)
{
var args = "-codec:v:0 " + videoCodec;
if (state.EnableMpegtsM2TsMode)
{
args += " -mpegts_m2ts_mode 1";
}
var isOutputMkv = string.Equals(state.Options.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
if (state.RunTimeTicks.HasValue)
{
//args += " -copyts -avoid_negative_ts disabled -start_at_zero";
}
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (state.VideoStream != null && EncodingHelper.IsH264(state.VideoStream) && string.Equals(state.Options.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
{
args += " -bsf:v h264_mp4toannexb";
}
return args;
}
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
5.ToString(UsCulture));
args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode;
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
args += EncodingHelper.GetOutputSizeParam(state, videoCodec);
}
var qualityParam = EncodingHelper.GetVideoQualityParam(state, videoCodec, GetEncodingOptions(), "superfast");
if (!string.IsNullOrEmpty(qualityParam))
{
args += " " + qualityParam.Trim();
}
// This is for internal graphical subs
if (hasGraphicalSubs)
{
args += EncodingHelper.GetGraphicalSubtitleParam(state, videoCodec);
}
return args;
return EncodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, state.OutputFilePath, "superfast");
}
protected override string GetOutputFileExtension(EncodingJob state)