create separate media encoding project

pull/702/head
Luke Pulverenti 10 years ago
parent ac81b4e3ca
commit 39ea2adbc5

@ -316,6 +316,7 @@ namespace MediaBrowser.Api.Playback
/// </summary>
/// <param name="state">The state.</param>
/// <param name="videoCodec">The video codec.</param>
/// <param name="isHls">if set to <c>true</c> [is HLS].</param>
/// <returns>System.String.</returns>
protected string GetVideoQualityParam(StreamState state, string videoCodec, bool isHls)
{
@ -340,20 +341,17 @@ namespace MediaBrowser.Api.Playback
break;
}
if (!isHls)
switch (qualitySetting)
{
switch (qualitySetting)
{
case EncodingQuality.HighSpeed:
param += " -crf 23";
break;
case EncodingQuality.HighQuality:
param += " -crf 20";
break;
case EncodingQuality.MaxQuality:
param += " -crf 18";
break;
}
case EncodingQuality.HighSpeed:
param += " -crf 23";
break;
case EncodingQuality.HighQuality:
param += " -crf 20";
break;
case EncodingQuality.MaxQuality:
param += " -crf 18";
break;
}
}
@ -1032,11 +1030,6 @@ namespace MediaBrowser.Api.Playback
{
var hasFixedResolution = state.VideoRequest.HasFixedResolution;
if (isHls)
{
return string.Format(" -b:v {0} -maxrate ({0}*.80) -bufsize {0}", bitrate.Value.ToString(UsCulture));
}
if (string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase))
{
if (hasFixedResolution)
@ -1047,7 +1040,6 @@ namespace MediaBrowser.Api.Playback
// With vpx when crf is used, b:v becomes a max rate
// https://trac.ffmpeg.org/wiki/vpxEncodingGuide
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
//return string.Format(" -minrate:v ({0}*.95) -maxrate:v ({0}*1.05) -bufsize:v {0} -b:v {0}", bitrate.Value.ToString(UsCulture));
}
if (string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
@ -1055,13 +1047,17 @@ namespace MediaBrowser.Api.Playback
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
}
// H264
if (hasFixedResolution)
{
if (isHls)
{
return string.Format(" -b:v {0} -maxrate ({0}*.80) -bufsize {0}", bitrate.Value.ToString(UsCulture));
}
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
}
return string.Format(" -maxrate {0} -bufsize {1}",
bitrate.Value.ToString(UsCulture),
(bitrate.Value * 2).ToString(UsCulture));

@ -200,7 +200,7 @@ namespace MediaBrowser.Api.Playback.Hls
builder.AppendLine("#EXTM3U");
// Pad a little to satisfy the apple hls validator
var paddedBitrate = Convert.ToInt32(bitrate * 1.05);
var paddedBitrate = Convert.ToInt32(bitrate * 1.15);
// Main stream
builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + paddedBitrate.ToString(UsCulture));

@ -266,6 +266,11 @@ namespace MediaBrowser.Api.Playback.Progressive
return result;
}
/// <summary>
/// Gets the length of the estimated content.
/// </summary>
/// <param name="state">The state.</param>
/// <returns>System.Nullable{System.Int64}.</returns>
private long? GetEstimatedContentLength(StreamState state)
{
var totalBitrate = 0;

@ -24,16 +24,23 @@ namespace MediaBrowser.Controller.MediaEncoding
string Version { get; }
/// <summary>
/// Extracts the image.
/// Extracts the audio image.
/// </summary>
/// <param name="path">The path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken);
/// <summary>
/// Extracts the video image.
/// </summary>
/// <param name="inputFiles">The input files.</param>
/// <param name="type">The type.</param>
/// <param name="isAudio">if set to <c>true</c> [is audio].</param>
/// <param name="threedFormat">The threed format.</param>
/// <param name="offset">The offset.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
/// <summary>
/// Extracts the text subtitle.

@ -197,7 +197,7 @@ namespace MediaBrowser.Dlna
throw new ArgumentNullException("headers");
}
return GetProfiles().FirstOrDefault(i => IsMatch(headers, i.Identification));
return GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification));
}
private bool IsMatch(IDictionary<string, string> headers, DeviceIdentification profileInfo)

@ -631,7 +631,7 @@ namespace MediaBrowser.Dlna.PlayTo
RendererCommands = TransportCommands.Create(document);
}
internal TransportCommands AvCommands
private TransportCommands AvCommands
{
get;
set;

@ -57,24 +57,6 @@ namespace MediaBrowser.Dlna.Profiles
Type = DlnaProfileType.Video
}
};
CodecProfiles = new[]
{
new CodecProfile
{
Type = CodecType.VideoCodec,
Conditions = new []
{
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.VideoLevel,
Value = "3",
IsRequired = false
}
}
}
};
}
}
}

@ -229,13 +229,6 @@ namespace MediaBrowser.Dlna.Profiles
Property = ProfileConditionValue.VideoBitrate,
Value = "10240000",
IsRequired = false
},
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.VideoLevel,
Value = "3",
IsRequired = false
}
}
},
@ -271,13 +264,6 @@ namespace MediaBrowser.Dlna.Profiles
Property = ProfileConditionValue.VideoBitrate,
Value = "15360000",
IsRequired = false
},
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.VideoLevel,
Value = "3",
IsRequired = false
}
}
},

@ -30,12 +30,5 @@
</TranscodingProfile>
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
<CodecProfile type="VideoCodec">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
</CodecProfiles>
<MediaProfiles />
</Profile>

@ -34,12 +34,5 @@
</TranscodingProfile>
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
<CodecProfile type="VideoCodec">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
</CodecProfiles>
<MediaProfiles />
</Profile>

@ -34,12 +34,5 @@
</TranscodingProfile>
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
<CodecProfile type="VideoCodec">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
</CodecProfiles>
<MediaProfiles />
</Profile>

@ -73,7 +73,6 @@
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="false" />
<ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="10240000" isRequired="false" />
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
<CodecProfile type="VideoCodec" codec="wmv2,wmv3,vc1">
@ -82,7 +81,6 @@
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="false" />
<ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="15360000" isRequired="false" />
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
<CodecProfile type="VideoAudioCodec" codec="ac3,wmav2,wmapro">

@ -32,13 +32,6 @@
</TranscodingProfile>
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
<CodecProfile type="VideoCodec">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
</CodecProfiles>
<MediaProfiles>
<MediaProfile container="avi" type="Video" mimeType="video/x-msvideo">
<Conditions />

@ -36,12 +36,5 @@
</TranscodingProfile>
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
<CodecProfile type="VideoCodec">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
</Conditions>
</CodecProfile>
</CodecProfiles>
<MediaProfiles />
</Profile>

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Server.Implementations.BdInfo
namespace MediaBrowser.MediaEncoding.BdInfo
{
/// <summary>
/// Class BdInfoExaminer

@ -6,17 +6,15 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.MediaEncoder
namespace MediaBrowser.MediaEncoding.Encoder
{
/// <summary>
/// Class MediaEncoder
@ -53,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// The FF probe resource pool
/// </summary>
private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2);
private readonly IFileSystem _fileSystem;
public string FFMpegPath { get; private set; }
@ -62,7 +61,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
public string Version { get; private set; }
public MediaEncoder(ILogger logger, IApplicationPaths appPaths,
IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IFileSystem fileSystem)
IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version,
IFileSystem fileSystem)
{
_logger = logger;
_appPaths = appPaths;
@ -85,7 +85,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <summary>
/// The _semaphoreLocks
/// </summary>
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
new ConcurrentDictionary<string, SemaphoreSlim>();
/// <summary>
/// Gets the lock.
@ -106,10 +107,10 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, InputType type, bool isAudio,
CancellationToken cancellationToken)
CancellationToken cancellationToken)
{
return GetMediaInfoInternal(GetInputArgument(inputFiles, type), !isAudio,
GetProbeSizeArgument(type), cancellationToken);
GetProbeSizeArgument(type), cancellationToken);
}
/// <summary>
@ -172,8 +173,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <returns>Task{MediaInfoResult}.</returns>
/// <exception cref="System.ApplicationException"></exception>
private async Task<InternalMediaInfoResult> GetMediaInfoInternal(string inputPath, bool extractChapters,
string probeSizeArgument,
CancellationToken cancellationToken)
string probeSizeArgument,
CancellationToken cancellationToken)
{
var args = extractChapters
? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
@ -191,7 +192,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
RedirectStandardError = true,
FileName = FFProbePath,
Arguments = string.Format(args,
probeSizeArgument, inputPath).Trim(),
probeSizeArgument, inputPath).Trim(),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
@ -225,7 +226,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
{
process.BeginErrorReadLine();
result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
result =
_jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
}
catch
{
@ -295,7 +297,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <param name="language">The language.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, string language, CancellationToken cancellationToken)
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, string language,
CancellationToken cancellationToken)
{
var semaphore = GetLock(outputPath);
@ -340,33 +343,35 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
var encodingParam = string.IsNullOrEmpty(language) ? string.Empty :
GetSubtitleLanguageEncodingParam(language) + " ";
var encodingParam = string.IsNullOrEmpty(language)
? string.Empty
: GetSubtitleLanguageEncodingParam(language) + " ";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
StartInfo = new ProcessStartInfo
{
RedirectStandardOutput = false,
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false,
FileName = FFMpegPath,
Arguments =
string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
}
};
RedirectStandardOutput = false,
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false,
FileName = FFMpegPath,
Arguments =
string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
}
};
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-convert-" + Guid.NewGuid() + ".txt");
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read,
true);
try
{
@ -525,7 +530,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentException">Must use inputPath list overload</exception>
public async Task ExtractTextSubtitle(string[] inputFiles, InputType type, int subtitleStreamIndex, bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
public async Task ExtractTextSubtitle(string[] inputFiles, InputType type, int subtitleStreamIndex,
bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
{
var semaphore = GetLock(outputPath);
@ -535,7 +541,9 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
{
if (!File.Exists(outputPath))
{
await ExtractTextSubtitleInternal(GetInputArgument(inputFiles, type), subtitleStreamIndex, copySubtitleStream, outputPath, cancellationToken).ConfigureAwait(false);
await
ExtractTextSubtitleInternal(GetInputArgument(inputFiles, type), subtitleStreamIndex,
copySubtitleStream, outputPath, cancellationToken).ConfigureAwait(false);
}
}
finally
@ -559,7 +567,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
/// or
/// cancellationToken</exception>
/// <exception cref="System.ApplicationException"></exception>
private async Task ExtractTextSubtitleInternal(string inputPath, int subtitleStreamIndex, bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
private async Task ExtractTextSubtitleInternal(string inputPath, int subtitleStreamIndex,
bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(inputPath))
{
@ -571,11 +580,13 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
throw new ArgumentNullException("outputPath");
}
string processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s ass \"{2}\"", inputPath, subtitleStreamIndex, outputPath);
string processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s ass \"{2}\"", inputPath,
subtitleStreamIndex, outputPath);
if (copySubtitleStream)
{
processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s copy \"{2}\"", inputPath, subtitleStreamIndex, outputPath);
processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s copy \"{2}\"", inputPath,
subtitleStreamIndex, outputPath);
}
var process = new Process
@ -600,7 +611,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-extract-" + Guid.NewGuid() + ".txt");
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read,
true);
try
{
@ -715,7 +727,18 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
}
public async Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio,
public Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken)
{
return ExtractImage(new[] { path }, InputType.File, true, null, null, cancellationToken);
}
public Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat,
TimeSpan? offset, CancellationToken cancellationToken)
{
return ExtractImage(inputFiles, type, false, threedFormat, offset, cancellationToken);
}
private async Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio,
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
{
var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool;
@ -773,7 +796,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail\" -f image2 \"{1}\"", inputPath, "-", vf) :
var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=80\" -f image2 \"{1}\"", inputPath, "-", vf) :
string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf);
var probeSize = GetProbeSizeArgument(type);
@ -834,7 +857,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
_logger.ErrorException("Error killing process", ex);
}
}
resourcePool.Release();
var exitCode = ranToCompletion ? process.ExitCode : -1;

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MediaBrowser.MediaEncoding</RootNamespace>
<AssemblyName>MediaBrowser.MediaEncoding</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BDInfo">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath>
</Reference>
<Reference Include="DvdLib">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BdInfo\BdInfoExaminer.cs" />
<Compile Include="Encoder\MediaEncoder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MediaBrowser.MediaEncoding")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MediaBrowser.MediaEncoding")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("05f49ab9-2a90-4332-9d41-7817a9cccd90")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
</packages>

@ -94,7 +94,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
using (var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false))
using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false))
{
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{

@ -113,8 +113,6 @@ namespace MediaBrowser.Providers.MediaInfo
{
cancellationToken.ThrowIfCancellationRequested();
cancellationToken.ThrowIfCancellationRequested();
var idString = item.Id.ToString("N");
var cachePath = Path.Combine(_appPaths.CachePath,
"ffprobe-video",

@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.MediaInfo
var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, item.LocationType == LocationType.Remote, item.VideoType, item.IsoType, isoMount, item.PlayableStreamFileNames, out type);
var stream = await _mediaEncoder.ExtractImage(inputPath, type, false, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
var stream = await _mediaEncoder.ExtractVideoImage(inputPath, type, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
return new DynamicImageResponse
{

@ -249,17 +249,24 @@ namespace MediaBrowser.Server.Implementations.IO
// Creating a FileSystemWatcher over the LAN can take hundreds of milliseconds, so wrap it in a Task to do them all in parallel
Task.Run(() =>
{
var newWatcher = new FileSystemWatcher(path, "*") { IncludeSubdirectories = true, InternalBufferSize = 32767 };
try
{
var newWatcher = new FileSystemWatcher(path, "*")
{
IncludeSubdirectories = true,
InternalBufferSize = 32767
};
newWatcher.Created += watcher_Changed;
newWatcher.Deleted += watcher_Changed;
newWatcher.Renamed += watcher_Changed;
newWatcher.Changed += watcher_Changed;
newWatcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
newWatcher.Error += watcher_Error;
newWatcher.Created += watcher_Changed;
newWatcher.Deleted += watcher_Changed;
newWatcher.Renamed += watcher_Changed;
newWatcher.Changed += watcher_Changed;
newWatcher.Error += watcher_Error;
try
{
if (_fileSystemWatchers.TryAdd(path, newWatcher))
{
newWatcher.EnableRaisingEvents = true;
@ -272,11 +279,7 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
catch (IOException ex)
{
Logger.ErrorException("Error watching path: {0}", ex, path);
}
catch (PlatformNotSupportedException ex)
catch (Exception ex)
{
Logger.ErrorException("Error watching path: {0}", ex, path);
}
@ -346,7 +349,9 @@ namespace MediaBrowser.Server.Implementations.IO
{
try
{
OnWatcherChanged(e);
Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath);
ReportFileSystemChanged(e.FullPath);
}
catch (Exception ex)
{
@ -354,13 +359,6 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
private void OnWatcherChanged(FileSystemEventArgs e)
{
Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath);
ReportFileSystemChanged(e.FullPath);
}
public void ReportFileSystemChanged(string path)
{
if (string.IsNullOrEmpty(path))
@ -370,12 +368,9 @@ namespace MediaBrowser.Server.Implementations.IO
var filename = Path.GetFileName(path);
// Ignore certain files
if (!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase))
{
return;
}
var monitorPath = !(!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase));
// Ignore certain files
var tempIgnorePaths = _tempIgnoredPaths.Keys.ToList();
// If the parent of an ignored path has a change event, ignore that too
@ -416,12 +411,15 @@ namespace MediaBrowser.Server.Implementations.IO
}))
{
return;
monitorPath = false;
}
// Avoid implicitly captured closure
var affectedPath = path;
_affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath);
if (monitorPath)
{
// Avoid implicitly captured closure
var affectedPath = path;
_affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath);
}
lock (_timerLock)
{

@ -48,14 +48,6 @@
<Reference Include="Alchemy">
<HintPath>..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll</HintPath>
</Reference>
<Reference Include="BDInfo, Version=1.0.5167.21152, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath>
</Reference>
<Reference Include="DvdLib, Version=1.0.5167.21152, Culture=neutral, PublicKeyToken=7a2f3f5ec8d93575, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
</Reference>
<Reference Include="Mono.Nat, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Mono.Nat.1.2.3\lib\Net40\Mono.Nat.dll</HintPath>
@ -105,7 +97,6 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="BdInfo\BdInfoExaminer.cs" />
<Compile Include="Channels\ChannelImageProvider.cs" />
<Compile Include="Channels\ChannelItemImageProvider.cs" />
<Compile Include="Channels\ChannelManager.cs" />
@ -191,7 +182,6 @@
<Compile Include="LiveTv\RefreshChannelsScheduledTask.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
<Compile Include="MediaEncoder\EncodingManager.cs" />
<Compile Include="MediaEncoder\MediaEncoder.cs" />
<Compile Include="News\NewsEntryPoint.cs" />
<Compile Include="News\NewsService.cs" />
<Compile Include="Persistence\SqliteChapterRepository.cs" />

@ -178,7 +178,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
using (var stream = await _encoder.ExtractImage(inputPath, type, false, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false))
using (var stream = await _encoder.ExtractVideoImage(inputPath, type, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false))
{
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{

@ -37,6 +37,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var createTableCommand
= "create table if not exists mediastreams ";
// Add PixelFormat column
createTableCommand += "(ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PRIMARY KEY (ItemId, StreamIndex))";
string[] queries = {

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Alchemy" version="2.2.1" targetFramework="net45" />
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.3" targetFramework="net45" />
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.91.3" targetFramework="net45" />

@ -33,13 +33,14 @@ using MediaBrowser.Controller.Sorting;
using MediaBrowser.Controller.Themes;
using MediaBrowser.Dlna;
using MediaBrowser.Dlna.PlayTo;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.MediaEncoding.Encoder;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Updates;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Implementations.BdInfo;
using MediaBrowser.Server.Implementations.Channels;
using MediaBrowser.Server.Implementations.Collections;
using MediaBrowser.Server.Implementations.Configuration;
@ -815,7 +816,10 @@ namespace MediaBrowser.ServerApplication
// Server implementations
list.Add(typeof(ServerApplicationPaths).Assembly);
// Dlna implementations
// MediaEncoding
list.Add(typeof(MediaEncoder).Assembly);
// Dlna
list.Add(typeof(PlayToServerEntryPoint).Assembly);
list.AddRange(Assemblies.GetAssembliesWithParts());

@ -195,6 +195,10 @@
<Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
<Name>MediaBrowser.Dlna</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
<Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
<Name>MediaBrowser.MediaEncoding</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>

@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ServerApplicat
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Dlna", "MediaBrowser.Dlna\MediaBrowser.Dlna.csproj", "{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -247,6 +249,20 @@ Global
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Win32.ActiveCfg = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x64.ActiveCfg = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Win32.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x64.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Win32.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x64.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save