Merge pull request #2702 from MediaBrowser/beta

Beta
This commit is contained in:
Luke 2017-06-11 18:05:07 -04:00 committed by GitHub
commit e0c907cc60
143 changed files with 1263 additions and 2735 deletions

View File

@ -33,10 +33,6 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="project.json" />
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BDInfoSettings.cs" /> <Compile Include="BDInfoSettings.cs" />
<Compile Include="BDROM.cs" /> <Compile Include="BDROM.cs" />

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -33,10 +33,6 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="project.json" />
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BigEndianBinaryReader.cs" /> <Compile Include="BigEndianBinaryReader.cs" />
<Compile Include="Ifo\AudioAttributes.cs" /> <Compile Include="Ifo\AudioAttributes.cs" />

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -32,7 +32,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.9\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.4.4.10\lib\net45\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath> <HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
@ -42,9 +42,8 @@
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath> <HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="SimpleInjector, Version=4.0.7.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.7\lib\net45\SimpleInjector.dll</HintPath> <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />

View File

@ -157,6 +157,7 @@ namespace Emby.Common.Implementations.TextEncoding
case "ota": case "ota":
case "tur": case "tur":
return "windows-1254"; return "windows-1254";
case "bgr":
case "rus": case "rus":
return "windows-1251"; return "windows-1251";
case "vie": case "vie":

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.4.9" targetFramework="net46" /> <package id="NLog" version="4.4.10" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" /> <package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
<package id="SharpCompress" version="0.14.0" targetFramework="net462" /> <package id="SharpCompress" version="0.14.0" targetFramework="net462" />
<package id="SimpleInjector" version="4.0.7" targetFramework="net462" /> <package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
</packages> </packages>

View File

@ -70,7 +70,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile new DirectPlayProfile
{ {
Container = "aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac", Container = "aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a",
Type = DlnaProfileType.Audio Type = DlnaProfileType.Audio
} }
}; };

View File

@ -31,42 +31,7 @@ namespace Emby.Dlna.Profiles
{ {
new DirectPlayProfile new DirectPlayProfile
{ {
Container = "mp3", Container = "aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a",
AudioCodec = "mp2,mp3",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "mp4",
AudioCodec = "mp4",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "aac,wav",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "flac",
AudioCodec = "flac",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "asf",
AudioCodec = "wmav2,wmapro,wmavoice",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "ogg",
AudioCodec = "vorbis",
Type = DlnaProfileType.Audio Type = DlnaProfileType.Audio
} }
}; };

View File

@ -30,7 +30,7 @@
<XmlRootAttributes /> <XmlRootAttributes />
<DirectPlayProfiles> <DirectPlayProfiles>
<DirectPlayProfile container="m4v,mpegts,ts,3gp,mov,xvid,vob,mkv,wmv,asf,ogm,ogv,m2v,avi,mpg,mpeg,mp4,webm,wtv,m2ts,dvr-ms" type="Video" /> <DirectPlayProfile container="m4v,mpegts,ts,3gp,mov,xvid,vob,mkv,wmv,asf,ogm,ogv,m2v,avi,mpg,mpeg,mp4,webm,wtv,m2ts,dvr-ms" type="Video" />
<DirectPlayProfile container="aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac" type="Audio" /> <DirectPlayProfile container="aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a" type="Audio" />
</DirectPlayProfiles> </DirectPlayProfiles>
<TranscodingProfiles> <TranscodingProfiles>
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" /> <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" />

View File

@ -35,12 +35,7 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<XmlRootAttributes /> <XmlRootAttributes />
<DirectPlayProfiles> <DirectPlayProfiles>
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" /> <DirectPlayProfile container="aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a" type="Audio" />
<DirectPlayProfile container="mp4" audioCodec="mp4" type="Audio" />
<DirectPlayProfile container="aac,wav" type="Audio" />
<DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
</DirectPlayProfiles> </DirectPlayProfiles>
<TranscodingProfiles> <TranscodingProfiles>
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" /> <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" />

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -130,7 +130,7 @@ namespace Emby.Drawing.ImageMagick
string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase);
} }
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{ {
// Even if the caller specified 100, don't use it because it takes forever // Even if the caller specified 100, don't use it because it takes forever
quality = Math.Min(quality, 99); quality = Math.Min(quality, 99);

View File

@ -126,11 +126,11 @@ namespace Emby.Drawing.Skia
for (int row = 0; row < bitmap.Height; ++row) for (int row = 0; row < bitmap.Height; ++row)
{ {
if (IsAllWhiteRow(bitmap, row)) if (IsAllWhiteRow(bitmap, row))
topmost = row; topmost = row + 1;
else break; else break;
} }
int bottommost = 0; int bottommost = bitmap.Height;
for (int row = bitmap.Height - 1; row >= 0; --row) for (int row = bitmap.Height - 1; row >= 0; --row)
{ {
if (IsAllWhiteRow(bitmap, row)) if (IsAllWhiteRow(bitmap, row))
@ -138,11 +138,11 @@ namespace Emby.Drawing.Skia
else break; else break;
} }
int leftmost = 0, rightmost = 0; int leftmost = 0, rightmost = bitmap.Width;
for (int col = 0; col < bitmap.Width; ++col) for (int col = 0; col < bitmap.Width; ++col)
{ {
if (IsAllWhiteColumn(bitmap, col)) if (IsAllWhiteColumn(bitmap, col))
leftmost = col; leftmost = col + 1;
else else
break; break;
} }
@ -162,13 +162,6 @@ namespace Emby.Drawing.Skia
using (var subset = image.Subset(newRect)) using (var subset = image.Subset(newRect))
{ {
return SKBitmap.FromImage(subset); return SKBitmap.FromImage(subset);
//using (var data = subset.Encode(StripCollageBuilder.GetEncodedFormat(outputPath), 90))
//{
// using (var fileStream = _fileSystem.GetFileStream(outputPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
// {
// data.AsStream().CopyTo(fileStream);
// }
//}
} }
} }
} }
@ -191,7 +184,7 @@ namespace Emby.Drawing.Skia
} }
private string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" }; private string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" };
private SKBitmap Decode(string path, bool forceCleanBitmap = false) private SKBitmap Decode(string path, bool forceCleanBitmap, out SKCodecOrigin origin)
{ {
var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty);
@ -206,6 +199,8 @@ namespace Emby.Drawing.Skia
// decode // decode
codec.GetPixels(bitmap.Info, bitmap.GetPixels()); codec.GetPixels(bitmap.Info, bitmap.GetPixels());
origin = codec.Origin;
return bitmap; return bitmap;
} }
} }
@ -214,7 +209,7 @@ namespace Emby.Drawing.Skia
if (resultBitmap == null) if (resultBitmap == null)
{ {
return Decode(path, true); return Decode(path, true, out origin);
} }
// If we have to resize these they often end up distorted // If we have to resize these they often end up distorted
@ -222,27 +217,128 @@ namespace Emby.Drawing.Skia
{ {
using (resultBitmap) using (resultBitmap)
{ {
return Decode(path, true); return Decode(path, true, out origin);
} }
} }
origin = SKCodecOrigin.TopLeft;
return resultBitmap; return resultBitmap;
} }
private SKBitmap GetBitmap(string path, bool cropWhitespace) private SKBitmap GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, out SKCodecOrigin origin)
{ {
if (cropWhitespace) if (cropWhitespace)
{ {
using (var bitmap = Decode(path)) using (var bitmap = Decode(path, forceAnalyzeBitmap, out origin))
{ {
return CropWhiteSpace(bitmap); return CropWhiteSpace(bitmap);
} }
} }
return Decode(path); return Decode(path, forceAnalyzeBitmap, out origin);
} }
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) private SKBitmap GetBitmap(string path, bool cropWhitespace, bool autoOrient, ImageOrientation? orientation)
{
SKCodecOrigin origin;
if (autoOrient)
{
var bitmap = GetBitmap(path, cropWhitespace, true, out origin);
if (origin != SKCodecOrigin.TopLeft)
{
using (bitmap)
{
return RotateAndFlip(bitmap, origin);
}
}
return bitmap;
}
return GetBitmap(path, cropWhitespace, false, out origin);
}
private SKBitmap RotateAndFlip(SKBitmap original, SKCodecOrigin origin)
{
// these are the origins that represent a 90 degree turn in some fashion
var differentOrientations = new SKCodecOrigin[]
{
SKCodecOrigin.LeftBottom,
SKCodecOrigin.LeftTop,
SKCodecOrigin.RightBottom,
SKCodecOrigin.RightTop
};
// check if we need to turn the image
bool isDifferentOrientation = differentOrientations.Any(o => o == origin);
// define new width/height
var width = isDifferentOrientation ? original.Height : original.Width;
var height = isDifferentOrientation ? original.Width : original.Height;
var bitmap = new SKBitmap(width, height, true);
// todo: the stuff in this switch statement should be rewritten to use pointers
switch (origin)
{
case SKCodecOrigin.LeftBottom:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(y, original.Width - 1 - x, original.GetPixel(x, y));
break;
case SKCodecOrigin.RightTop:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(original.Height - 1 - y, x, original.GetPixel(x, y));
break;
case SKCodecOrigin.RightBottom:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(original.Height - 1 - y, original.Width - 1 - x, original.GetPixel(x, y));
break;
case SKCodecOrigin.LeftTop:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(y, x, original.GetPixel(x, y));
break;
case SKCodecOrigin.BottomLeft:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(x, original.Height - 1 - y, original.GetPixel(x, y));
break;
case SKCodecOrigin.BottomRight:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(original.Width - 1 - x, original.Height - 1 - y, original.GetPixel(x, y));
break;
case SKCodecOrigin.TopRight:
for (var x = 0; x < original.Width; x++)
for (var y = 0; y < original.Height; y++)
bitmap.SetPixel(original.Width - 1 - x, y, original.GetPixel(x, y));
break;
}
return bitmap;
}
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{ {
if (string.IsNullOrWhiteSpace(inputPath)) if (string.IsNullOrWhiteSpace(inputPath))
{ {
@ -260,7 +356,7 @@ namespace Emby.Drawing.Skia
var blur = options.Blur ?? 0; var blur = options.Blur ?? 0;
var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0); var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0);
using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace)) using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace, autoOrient, orientation))
{ {
if (bitmap == null) if (bitmap == null)
{ {
@ -272,7 +368,7 @@ namespace Emby.Drawing.Skia
var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height); var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize); ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize);
if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize)) if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient)
{ {
// Just spit out the original file if all the options are default // Just spit out the original file if all the options are default
return inputPath; return inputPath;

View File

@ -217,14 +217,23 @@ namespace Emby.Drawing
dateModified = tuple.Item2; dateModified = tuple.Item2;
} }
if (options.HasDefaultOptions(originalImagePath)) var photo = item as Photo;
var autoOrient = false;
ImageOrientation? orientation = null;
if (photo != null && photo.Orientation.HasValue && photo.Orientation.Value != ImageOrientation.TopLeft)
{
autoOrient = true;
orientation = photo.Orientation;
}
if (options.HasDefaultOptions(originalImagePath) && !autoOrient)
{ {
// Just spit out the original file if all the options are default // Just spit out the original file if all the options are default
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
} }
ImageSize? originalImageSize = GetSavedImageSize(originalImagePath, dateModified); ImageSize? originalImageSize = GetSavedImageSize(originalImagePath, dateModified);
if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value)) if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value) && !autoOrient)
{ {
// Just spit out the original file if all the options are default // Just spit out the original file if all the options are default
_logger.Info("Returning original image {0}", originalImagePath); _logger.Info("Returning original image {0}", originalImagePath);
@ -243,7 +252,6 @@ namespace Emby.Drawing
if (!_fileSystem.FileExists(cacheFilePath)) if (!_fileSystem.FileExists(cacheFilePath))
{ {
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(cacheFilePath));
var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath)); var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath));
@ -252,13 +260,14 @@ namespace Emby.Drawing
item = _libraryManager().GetItemById(options.ItemId); item = _libraryManager().GetItemById(options.ItemId);
} }
var resultPath =_imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, AutoOrient(item), quality, options, outputFormat); var resultPath = _imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, autoOrient, orientation, quality, options, outputFormat);
if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase)) if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase))
{ {
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
} }
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(cacheFilePath));
CopyFile(tmpPath, cacheFilePath); CopyFile(tmpPath, cacheFilePath);
return new Tuple<string, string, DateTime>(tmpPath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(tmpPath)); return new Tuple<string, string, DateTime>(tmpPath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(tmpPath));
@ -288,17 +297,6 @@ namespace Emby.Drawing
} }
} }
private bool AutoOrient(IHasImages item)
{
var photo = item as Photo;
if (photo != null && photo.Orientation.HasValue)
{
return true;
}
return false;
}
//private static int[][] OPERATIONS = new int[][] { //private static int[][] OPERATIONS = new int[][] {
// TopLeft // TopLeft
//new int[] { 0, NONE}, //new int[] { 0, NONE},

View File

@ -32,7 +32,7 @@ namespace Emby.Drawing
throw new NotImplementedException(); throw new NotImplementedException();
} }
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -41,9 +41,8 @@
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath> <HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="SimpleInjector, Version=4.0.7.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.7\lib\net45\SimpleInjector.dll</HintPath> <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />

View File

@ -332,7 +332,13 @@ namespace Emby.Server.Core.IO
NotifyFilters.Attributes; NotifyFilters.Attributes;
newWatcher.Created += watcher_Changed; newWatcher.Created += watcher_Changed;
newWatcher.Deleted += watcher_Changed;
// Seeing mono crashes on background threads we can't catch, testing if this might help
if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows)
{
newWatcher.Deleted += watcher_Changed;
}
newWatcher.Renamed += watcher_Changed; newWatcher.Renamed += watcher_Changed;
newWatcher.Changed += watcher_Changed; newWatcher.Changed += watcher_Changed;

View File

@ -2,5 +2,5 @@
<packages> <packages>
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" targetFramework="net462" /> <package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" targetFramework="net462" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" /> <package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
<package id="SimpleInjector" version="4.0.7" targetFramework="net462" /> <package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
</packages> </packages>

View File

@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.Activity
return; return;
} }
if (item.IsThemeMedia) if (e.Item != null && e.Item.IsThemeMedia)
{ {
// Don't report theme song or local trailer playback // Don't report theme song or local trailer playback
return; return;
@ -155,7 +155,7 @@ namespace Emby.Server.Implementations.Activity
return; return;
} }
if (item.IsThemeMedia) if (e.Item != null && e.Item.IsThemeMedia)
{ {
// Don't report theme song or local trailer playback // Don't report theme song or local trailer playback
return; return;

View File

@ -176,7 +176,9 @@ namespace Emby.Server.Implementations.Channels
var internalResult = await GetChannelsInternal(query, cancellationToken).ConfigureAwait(false); var internalResult = await GetChannelsInternal(query, cancellationToken).ConfigureAwait(false);
var dtoOptions = new DtoOptions(); var dtoOptions = new DtoOptions()
{
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray(); .ToArray();
@ -558,7 +560,10 @@ namespace Emby.Server.Implementations.Channels
totalRecordCount = items.Length; totalRecordCount = items.Length;
} }
var dtoOptions = new DtoOptions(); var dtoOptions = new DtoOptions()
{
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false)) var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false))
.ToArray(); .ToArray();
@ -825,7 +830,10 @@ namespace Emby.Server.Implementations.Channels
RefreshIfNeeded(internalResult.Items); RefreshIfNeeded(internalResult.Items);
var dtoOptions = new DtoOptions(); var dtoOptions = new DtoOptions()
{
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray(); .ToArray();
@ -974,7 +982,10 @@ namespace Emby.Server.Implementations.Channels
var internalResult = await GetChannelItemsInternal(query, new Progress<double>(), cancellationToken).ConfigureAwait(false); var internalResult = await GetChannelItemsInternal(query, new Progress<double>(), cancellationToken).ConfigureAwait(false);
var dtoOptions = new DtoOptions(); var dtoOptions = new DtoOptions()
{
Fields = query.Fields.ToList()
};
var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
.ToArray(); .ToArray();
@ -1378,12 +1389,6 @@ namespace Emby.Server.Implementations.Channels
item.SetImagePath(ImageType.Primary, info.ImageUrl); item.SetImagePath(ImageType.Primary, info.ImageUrl);
} }
if (item.SourceType != SourceType.Channel)
{
item.SourceType = SourceType.Channel;
forceUpdate = true;
}
if (isNew) if (isNew)
{ {
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);

View File

@ -199,10 +199,11 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames); AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames); AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "HomePageUrl", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "HomePageUrl", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "VoteCount", "INT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DisplayMediaType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "DisplayMediaType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames);
@ -233,7 +234,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "UnratedType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "UnratedType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsItemByName", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsItemByName", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SourceType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames); AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames);
AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames);
@ -424,9 +424,8 @@ namespace Emby.Server.Implementations.Data
"OfficialRating", "OfficialRating",
"HomePageUrl", "HomePageUrl",
"DisplayMediaType", "DisplayMediaType",
"SortName", "ForcedSortName",
"RunTimeTicks", "RunTimeTicks",
"VoteCount",
"DateCreated", "DateCreated",
"DateModified", "DateModified",
"guid", "guid",
@ -439,7 +438,6 @@ namespace Emby.Server.Implementations.Data
"LockedFields", "LockedFields",
"Studios", "Studios",
"Tags", "Tags",
"SourceType",
"TrailerTypes", "TrailerTypes",
"OriginalTitle", "OriginalTitle",
"PrimaryVersionId", "PrimaryVersionId",
@ -541,9 +539,9 @@ namespace Emby.Server.Implementations.Data
"Genres", "Genres",
"InheritedParentalRatingValue", "InheritedParentalRatingValue",
"SortName", "SortName",
"ForcedSortName",
"RunTimeTicks", "RunTimeTicks",
"HomePageUrl", "HomePageUrl",
"VoteCount",
"DisplayMediaType", "DisplayMediaType",
"DateCreated", "DateCreated",
"DateModified", "DateModified",
@ -563,7 +561,6 @@ namespace Emby.Server.Implementations.Data
"UnratedType", "UnratedType",
"TopParentId", "TopParentId",
"IsItemByName", "IsItemByName",
"SourceType",
"TrailerTypes", "TrailerTypes",
"CriticRating", "CriticRating",
"InheritedTags", "InheritedTags",
@ -815,10 +812,12 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@InheritedParentalRatingValue", item.InheritedParentalRatingValue); saveItemStatement.TryBind("@InheritedParentalRatingValue", item.InheritedParentalRatingValue);
saveItemStatement.TryBind("@SortName", item.SortName); saveItemStatement.TryBind("@SortName", item.SortName);
saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName);
saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks); saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks);
saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl); saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl);
saveItemStatement.TryBind("@VoteCount", item.VoteCount);
saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType); saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType);
saveItemStatement.TryBind("@DateCreated", item.DateCreated); saveItemStatement.TryBind("@DateCreated", item.DateCreated);
saveItemStatement.TryBind("@DateModified", item.DateModified); saveItemStatement.TryBind("@DateModified", item.DateModified);
@ -909,7 +908,6 @@ namespace Emby.Server.Implementations.Data
isByName = dualAccess == null || dualAccess.IsAccessedByName; isByName = dualAccess == null || dualAccess.IsAccessedByName;
} }
saveItemStatement.TryBind("@IsItemByName", isByName); saveItemStatement.TryBind("@IsItemByName", isByName);
saveItemStatement.TryBind("@SourceType", item.SourceType.ToString());
var trailer = item as Trailer; var trailer = item as Trailer;
if (trailer != null && trailer.TrailerTypes.Count > 0) if (trailer != null && trailer.TrailerTypes.Count > 0)
@ -1624,7 +1622,7 @@ namespace Emby.Server.Implementations.Data
{ {
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
{ {
item.SortName = reader.GetString(index); item.ForcedSortName = reader.GetString(index);
} }
index++; index++;
} }
@ -1635,15 +1633,6 @@ namespace Emby.Server.Implementations.Data
} }
index++; index++;
if (HasField(query, ItemFields.VoteCount))
{
if (!reader.IsDBNull(index))
{
item.VoteCount = reader.GetInt32(index);
}
index++;
}
if (HasField(query, ItemFields.DateCreated)) if (HasField(query, ItemFields.DateCreated))
{ {
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
@ -1733,12 +1722,6 @@ namespace Emby.Server.Implementations.Data
index++; index++;
} }
if (!reader.IsDBNull(index))
{
item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(index), true);
}
index++;
if (hasTrailerTypes) if (hasTrailerTypes)
{ {
var trailer = item as Trailer; var trailer = item as Trailer;
@ -2283,7 +2266,7 @@ namespace Emby.Server.Implementations.Data
} }
if (field == ItemFields.SortName) if (field == ItemFields.SortName)
{ {
return new[] { "SortName" }; return new[] { "ForcedSortName" };
} }
if (field == ItemFields.Taglines) if (field == ItemFields.Taglines)
{ {
@ -2306,7 +2289,6 @@ namespace Emby.Server.Implementations.Data
case ItemFields.HomePageUrl: case ItemFields.HomePageUrl:
case ItemFields.Keywords: case ItemFields.Keywords:
case ItemFields.DisplayMediaType: case ItemFields.DisplayMediaType:
case ItemFields.VoteCount:
case ItemFields.CustomRating: case ItemFields.CustomRating:
case ItemFields.ProductionLocations: case ItemFields.ProductionLocations:
case ItemFields.Settings: case ItemFields.Settings:
@ -3872,34 +3854,6 @@ namespace Emby.Server.Implementations.Data
} }
} }
if (query.SourceTypes.Length == 1)
{
whereClauses.Add("SourceType=@SourceType");
if (statement != null)
{
statement.TryBind("@SourceType", query.SourceTypes[0].ToString());
}
}
else if (query.SourceTypes.Length > 1)
{
var inClause = string.Join(",", query.SourceTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add(string.Format("SourceType in ({0})", inClause));
}
if (query.ExcludeSourceTypes.Length == 1)
{
whereClauses.Add("SourceType<>@ExcludeSourceTypes");
if (statement != null)
{
statement.TryBind("@ExcludeSourceTypes", query.ExcludeSourceTypes[0].ToString());
}
}
else if (query.ExcludeSourceTypes.Length > 1)
{
var inClause = string.Join(",", query.ExcludeSourceTypes.Select(i => "'" + i + "'").ToArray());
whereClauses.Add(string.Format("SourceType not in ({0})", inClause));
}
if (query.TrailerTypes.Length > 0) if (query.TrailerTypes.Length > 0)
{ {
var clauses = new List<string>(); var clauses = new List<string>();
@ -5017,14 +4971,6 @@ namespace Emby.Server.Implementations.Data
statement.TryBind("@NameContains", "%" + query.NameContains + "%"); statement.TryBind("@NameContains", "%" + query.NameContains + "%");
} }
} }
if (query.SourceTypes.Length == 1)
{
whereClauses.Add("(select sourcetype from typedbaseitems where guid=ItemId) = @SourceTypes");
if (statement != null)
{
statement.TryBind("@SourceTypes", query.SourceTypes[0].ToString());
}
}
return whereClauses; return whereClauses;
} }

View File

@ -1058,11 +1058,6 @@ namespace Emby.Server.Implementations.Dto
dto.CommunityRating = item.CommunityRating; dto.CommunityRating = item.CommunityRating;
} }
if (fields.Contains(ItemFields.VoteCount))
{
dto.VoteCount = item.VoteCount;
}
//if (item.IsFolder) //if (item.IsFolder)
//{ //{
// var folder = (Folder)item; // var folder = (Folder)item;
@ -1084,7 +1079,10 @@ namespace Emby.Server.Implementations.Dto
if (audio != null) if (audio != null)
{ {
dto.Album = audio.Album; dto.Album = audio.Album;
dto.ExtraType = audio.ExtraType; if (audio.ExtraType.HasValue)
{
dto.ExtraType = audio.ExtraType.Value.ToString();
}
var albumParent = audio.AlbumEntity; var albumParent = audio.AlbumEntity;
@ -1239,7 +1237,10 @@ namespace Emby.Server.Implementations.Dto
dto.Chapters = GetChapterInfoDtos(item); dto.Chapters = GetChapterInfoDtos(item);
} }
dto.ExtraType = video.ExtraType; if (video.ExtraType.HasValue)
{
dto.ExtraType = video.ExtraType.Value.ToString();
}
} }
if (fields.Contains(ItemFields.MediaStreams)) if (fields.Contains(ItemFields.MediaStreams))
@ -1395,7 +1396,7 @@ namespace Emby.Server.Implementations.Dto
} }
} }
if (fields.Contains(ItemFields.SeriesPrimaryImage)) //if (fields.Contains(ItemFields.SeriesPrimaryImage))
{ {
series = series ?? season.Series; series = series ?? season.Series;
if (series != null) if (series != null)
@ -1586,7 +1587,7 @@ namespace Emby.Server.Implementations.Dto
{ {
var imageInfo = item.GetImageInfo(ImageType.Primary, 0); var imageInfo = item.GetImageInfo(ImageType.Primary, 0);
if (imageInfo == null || !imageInfo.IsLocalFile) if (imageInfo == null)
{ {
return null; return null;
} }
@ -1610,6 +1611,11 @@ namespace Emby.Server.Implementations.Dto
} }
else else
{ {
if (!imageInfo.IsLocalFile)
{
return null;
}
try try
{ {
size = _imageProcessor.GetImageSize(imageInfo); size = _imageProcessor.GetImageSize(imageInfo);

View File

@ -31,6 +31,9 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="Activity\ActivityLogEntryPoint.cs" /> <Compile Include="Activity\ActivityLogEntryPoint.cs" />
<Compile Include="Activity\ActivityManager.cs" /> <Compile Include="Activity\ActivityManager.cs" />
<Compile Include="Activity\ActivityRepository.cs" /> <Compile Include="Activity\ActivityRepository.cs" />

View File

@ -38,7 +38,10 @@ namespace Emby.Server.Implementations.Library
// Synology // Synology
"@eaDir", "@eaDir",
"eaDir", "eaDir",
"#recycle" "#recycle",
// Qnap
"@Recycle"
}; };

View File

@ -1292,7 +1292,7 @@ namespace Emby.Server.Implementations.Library
return item; return item;
} }
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query) public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
{ {
if (query.Recursive && query.ParentId.HasValue) if (query.Recursive && query.ParentId.HasValue)
{ {
@ -1305,12 +1305,17 @@ namespace Emby.Server.Implementations.Library
if (query.User != null) if (query.User != null)
{ {
AddUserToQuery(query, query.User); AddUserToQuery(query, query.User, allowExternalContent);
} }
return ItemRepository.GetItemList(query); return ItemRepository.GetItemList(query);
} }
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
{
return GetItemList(query, true);
}
public int GetCount(InternalItemsQuery query) public int GetCount(InternalItemsQuery query)
{ {
if (query.Recursive && query.ParentId.HasValue) if (query.Recursive && query.ParentId.HasValue)
@ -1548,7 +1553,7 @@ namespace Emby.Server.Implementations.Library
query.Parent = null; query.Parent = null;
} }
private void AddUserToQuery(InternalItemsQuery query, User user) private void AddUserToQuery(InternalItemsQuery query, User user, bool allowExternalContent = true)
{ {
if (query.AncestorIds.Length == 0 && if (query.AncestorIds.Length == 0 &&
!query.ParentId.HasValue && !query.ParentId.HasValue &&
@ -1561,7 +1566,8 @@ namespace Emby.Server.Implementations.Library
var userViews = _userviewManager().GetUserViews(new UserViewQuery var userViews = _userviewManager().GetUserViews(new UserViewQuery
{ {
UserId = user.Id.ToString("N"), UserId = user.Id.ToString("N"),
IncludeHidden = true IncludeHidden = true,
IncludeExternalContent = allowExternalContent
}, CancellationToken.None).Result.ToList(); }, CancellationToken.None).Result.ToList();

View File

@ -202,8 +202,7 @@ namespace Emby.Server.Implementations.Library
private bool IsValidUsernameCharacter(char i) private bool IsValidUsernameCharacter(char i)
{ {
return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') || return !char.Equals(i, '<') && !char.Equals(i, '>');
char.Equals(i, '.');
} }
public string MakeValidUsername(string username) public string MakeValidUsername(string username)

View File

@ -280,7 +280,7 @@ namespace Emby.Server.Implementations.Library
} : new string[] { }; } : new string[] { };
return _libraryManager.GetItemList(new InternalItemsQuery(user) var query = new InternalItemsQuery(user)
{ {
IncludeItemTypes = includeItemTypes, IncludeItemTypes = includeItemTypes,
SortOrder = SortOrder.Descending, SortOrder = SortOrder.Descending,
@ -289,11 +289,16 @@ namespace Emby.Server.Implementations.Library
ExcludeItemTypes = excludeItemTypes, ExcludeItemTypes = excludeItemTypes,
IsVirtualItem = false, IsVirtualItem = false,
Limit = limit * 5, Limit = limit * 5,
SourceTypes = parents.Count == 0 ? new[] { SourceType.Library } : new SourceType[] { },
IsPlayed = isPlayed, IsPlayed = isPlayed,
DtoOptions = options DtoOptions = options
};
}, parents); if (parents.Count == 0)
{
return _libraryManager.GetItemList(query, false);
}
return _libraryManager.GetItemList(query, parents);
} }
} }
} }

View File

@ -2270,11 +2270,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
writer.WriteElementString("studio", studio); writer.WriteElementString("studio", studio);
} }
if (item.VoteCount.HasValue)
{
writer.WriteElementString("votes", item.VoteCount.Value.ToString(CultureInfo.InvariantCulture));
}
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteEndDocument(); writer.WriteEndDocument();
} }

View File

@ -136,6 +136,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]";
httpOptions.RequestContent = requestBody; httpOptions.RequestContent = requestBody;
double wideAspect = 1.77777778;
var primaryImageCategory = "Logo";
using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false)) using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false))
{ {
StreamReader innerReader = new StreamReader(innerResponse.Content); StreamReader innerReader = new StreamReader(innerResponse.Content);
@ -167,13 +170,25 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{ {
var programEntry = programDict[schedule.programID]; var programEntry = programDict[schedule.programID];
var allImages = (images[imageIndex].data ?? new List<ScheduleDirect.ImageData>()).OrderByDescending(GetSizeOrder).ToList(); var allImages = (images[imageIndex].data ?? new List<ScheduleDirect.ImageData>()).ToList();
var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList(); var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList();
var imagesWithoutText = allImages.Where(i => string.Equals(i.text, "no", StringComparison.OrdinalIgnoreCase)).ToList();
programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, "Logo", true, 600) ?? double desiredAspect = IsMovie(programEntry) ? 0.666666667 : wideAspect;
GetProgramImage(ApiUrl, allImages, "Logo", true, 600);
programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, true, desiredAspect) ??
GetProgramImage(ApiUrl, allImages, true, desiredAspect);
programEntry.thumbImage = GetProgramImage(ApiUrl, imagesWithText, true, wideAspect);
// Don't supply the same image twice
if (string.Equals(programEntry.primaryImage, programEntry.thumbImage, StringComparison.Ordinal))
{
programEntry.thumbImage = null;
}
programEntry.backdropImage = GetProgramImage(ApiUrl, imagesWithoutText, true, wideAspect);
//programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false);
//programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ?? //programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ?? // GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
// GetProgramImage(ApiUrl, data, "Banner-LO", false) ?? // GetProgramImage(ApiUrl, data, "Banner-LO", false) ??
@ -220,9 +235,14 @@ namespace Emby.Server.Implementations.LiveTv.Listings
return channelNumber; return channelNumber;
} }
private bool IsMovie(ScheduleDirect.ProgramDetails programInfo)
{
var showType = programInfo.showType ?? string.Empty;
return showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1;
}
private ProgramInfo GetProgram(string channelId, ScheduleDirect.Program programInfo, ScheduleDirect.ProgramDetails details) private ProgramInfo GetProgram(string channelId, ScheduleDirect.Program programInfo, ScheduleDirect.ProgramDetails details)
{ {
//_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
DateTime startAt = GetDate(programInfo.airDateTime); DateTime startAt = GetDate(programInfo.airDateTime);
DateTime endAt = startAt.AddSeconds(programInfo.duration); DateTime endAt = startAt.AddSeconds(programInfo.duration);
ProgramAudio audioType = ProgramAudio.Stereo; ProgramAudio audioType = ProgramAudio.Stereo;
@ -276,9 +296,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
IsRepeat = repeat, IsRepeat = repeat,
IsSeries = showType.IndexOf("series", StringComparison.OrdinalIgnoreCase) != -1, IsSeries = showType.IndexOf("series", StringComparison.OrdinalIgnoreCase) != -1,
ImageUrl = details.primaryImage, ImageUrl = details.primaryImage,
ThumbImageUrl = details.thumbImage,
IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase), IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase),
IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1, IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1,
IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1, IsMovie = IsMovie(details),
Etag = programInfo.md5 Etag = programInfo.md5
}; };
@ -378,49 +399,18 @@ namespace Emby.Server.Implementations.LiveTv.Listings
return date; return date;
} }
private string GetProgramImage(string apiUrl, List<ScheduleDirect.ImageData> images, string category, bool returnDefaultImage, int desiredWidth) private string GetProgramImage(string apiUrl, List<ScheduleDirect.ImageData> images, bool returnDefaultImage, double desiredAspect)
{ {
string url = null; string url = null;
var matches = images var matches = images;
.Where(i => string.Equals(i.category, category, StringComparison.OrdinalIgnoreCase))
matches = matches
.OrderBy(i => Math.Abs(desiredAspect - GetApsectRatio(i)))
.ThenByDescending(GetSizeOrder)
.ToList(); .ToList();
if (matches.Count == 0) var match = matches.FirstOrDefault();
{
if (!returnDefaultImage)
{
return null;
}
matches = images;
}
var match = matches.FirstOrDefault(i =>
{
if (!string.IsNullOrWhiteSpace(i.width))
{
int value;
if (int.TryParse(i.width, out value))
{
return value <= desiredWidth;
}
}
return false;
});
if (match == null)
{
// Get the second lowest quality image, when possible
if (matches.Count > 1)
{
match = matches[matches.Count - 2];
}
else
{
match = matches.FirstOrDefault();
}
}
if (match == null) if (match == null)
{ {
@ -444,6 +434,31 @@ namespace Emby.Server.Implementations.LiveTv.Listings
return url; return url;
} }
private double GetApsectRatio(ScheduleDirect.ImageData i)
{
int width = 0;
int height = 0;
if (!string.IsNullOrWhiteSpace(i.width))
{
int.TryParse(i.width, out width);
}
if (!string.IsNullOrWhiteSpace(i.height))
{
int.TryParse(i.height, out height);
}
if (height == 0 || width == 0)
{
return 0;
}
double result = width;
result /= height;
return result;
}
private async Task<List<ScheduleDirect.ShowImages>> GetImageForPrograms( private async Task<List<ScheduleDirect.ShowImages>> GetImageForPrograms(
ListingsProviderInfo info, ListingsProviderInfo info,
List<string> programIds, List<string> programIds,
@ -1188,6 +1203,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public bool hasImageArtwork { get; set; } public bool hasImageArtwork { get; set; }
public string primaryImage { get; set; } public string primaryImage { get; set; }
public string thumbImage { get; set; } public string thumbImage { get; set; }
public string backdropImage { get; set; }
public string bannerImage { get; set; } public string bannerImage { get; set; }
public string imageID { get; set; } public string imageID { get; set; }
public string md5 { get; set; } public string md5 { get; set; }

View File

@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.LiveTv
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly ILogger _logger; private readonly ILogger _logger;
const int AnalyzeDurationMs = 2000; const int AnalyzeDurationMs = 1000;
public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger) public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger)
{ {

View File

@ -679,8 +679,7 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo item.SetImage(new ItemImageInfo
{ {
Path = info.ImagePath, Path = info.ImagePath,
Type = ImageType.Primary, Type = ImageType.Primary
IsPlaceholder = true
}, 0); }, 0);
} }
else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
@ -688,8 +687,46 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo item.SetImage(new ItemImageInfo
{ {
Path = info.ImageUrl, Path = info.ImageUrl,
Type = ImageType.Primary, Type = ImageType.Primary
IsPlaceholder = true }, 0);
}
}
if (!item.HasImage(ImageType.Thumb))
{
if (!string.IsNullOrWhiteSpace(info.ThumbImageUrl))
{
item.SetImage(new ItemImageInfo
{
Path = info.ThumbImageUrl,
Type = ImageType.Thumb
}, 0);
}
}
if (!item.HasImage(ImageType.Logo))
{
if (!string.IsNullOrWhiteSpace(info.LogoImageUrl))
{
item.SetImage(new ItemImageInfo
{
Path = info.LogoImageUrl,
Type = ImageType.Logo
}, 0);
}
}
if (!item.HasImage(ImageType.Backdrop))
{
if (!string.IsNullOrWhiteSpace(info.BackdropImageUrl))
{
item.SetImage(new ItemImageInfo
{
Path = info.BackdropImageUrl,
Type = ImageType.Backdrop
}, 0); }, 0);
} }
} }

View File

@ -422,6 +422,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
SupportsTranscoding = true, SupportsTranscoding = true,
IsInfiniteStream = true, IsInfiniteStream = true,
IgnoreDts = true, IgnoreDts = true,
//SupportsProbing = false,
//AnalyzeDurationMs = 2000000
//IgnoreIndex = true, //IgnoreIndex = true,
//ReadAtNativeFramerate = true //ReadAtNativeFramerate = true
}; };

View File

@ -117,7 +117,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
else else
{ {
await _multicastStream.CopyUntilCancelled(response.Content, () => Resolve(openTaskCompletionSource), cancellationToken).ConfigureAwait(false); Resolve(openTaskCompletionSource);
await _multicastStream.CopyUntilCancelled(response.Content, null, cancellationToken).ConfigureAwait(false);
} }
} }
} }

View File

@ -235,10 +235,18 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
} }
else else
{ {
numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last()); try
if (!IsValidChannelNumber(numberString))
{ {
numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last());
if (!IsValidChannelNumber(numberString))
{
numberString = null;
}
}
catch
{
// Seeing occasional argument exception here
numberString = null; numberString = null;
} }
} }

View File

@ -23,6 +23,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Threading; using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Dto;
namespace Emby.Server.Implementations.Notifications namespace Emby.Server.Implementations.Notifications
{ {
@ -260,7 +261,7 @@ namespace Emby.Server.Implementations.Notifications
var item = e.MediaInfo; var item = e.MediaInfo;
if ( item.IsThemeMedia) if (e.Item != null && e.Item.IsThemeMedia)
{ {
// Don't report theme song or local trailer playback // Don't report theme song or local trailer playback
return; return;
@ -430,7 +431,7 @@ namespace Emby.Server.Implementations.Notifications
return name; return name;
} }
public static string GetItemName(BaseItemInfo item) public static string GetItemName(BaseItemDto item)
{ {
var name = item.Name; var name = item.Name;

View File

@ -26,5 +26,3 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -338,7 +338,7 @@ namespace Emby.Server.Implementations.Session
} }
} }
info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); info.Item = GetItemInfo(libraryItem, mediaSource);
info.Item.RunTimeTicks = runtimeTicks; info.Item.RunTimeTicks = runtimeTicks;
} }
@ -813,7 +813,7 @@ namespace Emby.Server.Implementations.Session
mediaSource = await GetMediaSource(hasMediaSources, info.MediaSourceId, info.LiveStreamId).ConfigureAwait(false); mediaSource = await GetMediaSource(hasMediaSources, info.MediaSourceId, info.LiveStreamId).ConfigureAwait(false);
} }
info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); info.Item = GetItemInfo(libraryItem, mediaSource);
} }
else else
{ {
@ -1637,165 +1637,65 @@ namespace Emby.Server.Implementations.Session
return dto; return dto;
} }
private DtoOptions _itemInfoDtoOptions;
/// <summary> /// <summary>
/// Converts a BaseItem to a BaseItemInfo /// Converts a BaseItem to a BaseItemInfo
/// </summary> /// </summary>
/// <param name="item">The item.</param> private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
/// <param name="chapterOwner">The chapter owner.</param>
/// <param name="mediaSource">The media source.</param>
/// <returns>BaseItemInfo.</returns>
/// <exception cref="System.ArgumentNullException">item</exception>
private BaseItemInfo GetItemInfo(BaseItem item, BaseItem chapterOwner, MediaSourceInfo mediaSource)
{ {
if (item == null) if (item == null)
{ {
throw new ArgumentNullException("item"); throw new ArgumentNullException("item");
} }
var info = new BaseItemInfo var dtoOptions = _itemInfoDtoOptions;
{
Id = GetDtoId(item),
Name = item.Name,
MediaType = item.MediaType,
Type = item.GetClientTypeName(),
RunTimeTicks = item.RunTimeTicks,
IndexNumber = item.IndexNumber,
ParentIndexNumber = item.ParentIndexNumber,
PremiereDate = item.PremiereDate,
ProductionYear = item.ProductionYear,
IsThemeMedia = item.IsThemeMedia
};
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary); if (_itemInfoDtoOptions == null)
if (info.PrimaryImageTag != null)
{ {
info.PrimaryImageItemId = GetDtoId(item); dtoOptions = new DtoOptions
}
var episode = item as Episode;
if (episode != null)
{
info.IndexNumberEnd = episode.IndexNumberEnd;
}
var hasSeries = item as IHasSeries;
if (hasSeries != null)
{
info.SeriesName = hasSeries.SeriesName;
}
var recording = item as ILiveTvRecording;
if (recording != null)
{
if (recording.IsSeries)
{ {
info.Name = recording.EpisodeTitle; AddProgramRecordingInfo = false
info.SeriesName = recording.Name; };
if (string.IsNullOrWhiteSpace(info.Name)) dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo);
{ dtoOptions.Fields.Remove(ItemFields.SyncInfo);
info.Name = recording.Name; dtoOptions.Fields.Remove(ItemFields.CanDelete);
} dtoOptions.Fields.Remove(ItemFields.CanDownload);
} dtoOptions.Fields.Remove(ItemFields.ChildCount);
dtoOptions.Fields.Remove(ItemFields.CustomRating);
dtoOptions.Fields.Remove(ItemFields.DateLastMediaAdded);
dtoOptions.Fields.Remove(ItemFields.DateLastRefreshed);
dtoOptions.Fields.Remove(ItemFields.DateLastSaved);
dtoOptions.Fields.Remove(ItemFields.DisplayMediaType);
dtoOptions.Fields.Remove(ItemFields.DisplayPreferencesId);
dtoOptions.Fields.Remove(ItemFields.Etag);
dtoOptions.Fields.Remove(ItemFields.ExternalEtag);
dtoOptions.Fields.Remove(ItemFields.IndexOptions);
dtoOptions.Fields.Remove(ItemFields.InheritedParentalRatingValue);
dtoOptions.Fields.Remove(ItemFields.ItemCounts);
dtoOptions.Fields.Remove(ItemFields.Keywords);
dtoOptions.Fields.Remove(ItemFields.MediaSourceCount);
dtoOptions.Fields.Remove(ItemFields.MediaStreams);
dtoOptions.Fields.Remove(ItemFields.MediaSources);
dtoOptions.Fields.Remove(ItemFields.People);
dtoOptions.Fields.Remove(ItemFields.PlayAccess);
dtoOptions.Fields.Remove(ItemFields.People);
dtoOptions.Fields.Remove(ItemFields.ProductionLocations);
dtoOptions.Fields.Remove(ItemFields.RecursiveItemCount);
dtoOptions.Fields.Remove(ItemFields.RemoteTrailers);
dtoOptions.Fields.Remove(ItemFields.SeasonUserData);
dtoOptions.Fields.Remove(ItemFields.SeriesGenres);
dtoOptions.Fields.Remove(ItemFields.Settings);
dtoOptions.Fields.Remove(ItemFields.SortName);
dtoOptions.Fields.Remove(ItemFields.Tags);
dtoOptions.Fields.Remove(ItemFields.ThemeSongIds);
dtoOptions.Fields.Remove(ItemFields.ThemeVideoIds);
_itemInfoDtoOptions = dtoOptions;
} }
var audio = item as Audio; var info = _dtoService.GetBaseItemDto(item, dtoOptions);
if (audio != null)
{
info.Album = audio.Album;
info.Artists = audio.Artists;
if (info.PrimaryImageTag == null)
{
var album = audio.AlbumEntity;
if (album != null && album.HasImage(ImageType.Primary))
{
info.PrimaryImageTag = GetImageCacheTag(album, ImageType.Primary);
if (info.PrimaryImageTag != null)
{
info.PrimaryImageItemId = GetDtoId(album);
}
}
}
}
var musicVideo = item as MusicVideo;
if (musicVideo != null)
{
info.Album = musicVideo.Album;
info.Artists = musicVideo.Artists.ToList();
}
var backropItem = item.HasImage(ImageType.Backdrop) ? item : null;
var thumbItem = item.HasImage(ImageType.Thumb) ? item : null;
var logoItem = item.HasImage(ImageType.Logo) ? item : null;
if (thumbItem == null)
{
if (episode != null)
{
var series = episode.Series;
if (series != null && series.HasImage(ImageType.Thumb))
{
thumbItem = series;
}
}
}
if (backropItem == null)
{
if (episode != null)
{
var series = episode.Series;
if (series != null && series.HasImage(ImageType.Backdrop))
{
backropItem = series;
}
}
}
if (backropItem == null)
{
backropItem = item.GetParents().FirstOrDefault(i => i.HasImage(ImageType.Backdrop));
}
if (thumbItem == null)
{
thumbItem = item.GetParents().FirstOrDefault(i => i.HasImage(ImageType.Thumb));
}
if (logoItem == null)
{
logoItem = item.GetParents().FirstOrDefault(i => i.HasImage(ImageType.Logo));
}
if (thumbItem != null)
{
info.ThumbImageTag = GetImageCacheTag(thumbItem, ImageType.Thumb);
info.ThumbItemId = GetDtoId(thumbItem);
}
if (backropItem != null)
{
info.BackdropImageTag = GetImageCacheTag(backropItem, ImageType.Backdrop);
info.BackdropItemId = GetDtoId(backropItem);
}
if (logoItem != null)
{
info.LogoImageTag = GetImageCacheTag(logoItem, ImageType.Logo);
info.LogoItemId = GetDtoId(logoItem);
}
if (chapterOwner != null)
{
info.ChapterImagesItemId = chapterOwner.Id.ToString("N");
info.Chapters = _dtoService.GetChapterInfoDtos(chapterOwner).ToList();
}
if (mediaSource != null) if (mediaSource != null)
{ {
@ -1837,7 +1737,7 @@ namespace Emby.Server.Implementations.Session
//ReportNowViewingItem(sessionId, info); //ReportNowViewingItem(sessionId, info);
} }
public void ReportNowViewingItem(string sessionId, BaseItemInfo item) public void ReportNowViewingItem(string sessionId, BaseItemDto item)
{ {
//var session = GetSession(sessionId); //var session = GetSession(sessionId);

View File

@ -206,15 +206,16 @@ namespace MediaBrowser.Api
var newLockData = request.LockData ?? false; var newLockData = request.LockData ?? false;
var isLockedChanged = item.IsLocked != newLockData; var isLockedChanged = item.IsLocked != newLockData;
UpdateItem(request, item); // Do this first so that metadata savers can pull the updates from the database.
await item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
if (request.People != null) if (request.People != null)
{ {
await _libraryManager.UpdatePeople(item, request.People.Select(x => new PersonInfo { Name = x.Name, Role = x.Role, Type = x.Type }).ToList()); await _libraryManager.UpdatePeople(item, request.People.Select(x => new PersonInfo { Name = x.Name, Role = x.Role, Type = x.Type }).ToList());
} }
UpdateItem(request, item);
await item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
if (isLockedChanged && item.IsFolder) if (isLockedChanged && item.IsFolder)
{ {
var folder = (Folder)item; var folder = (Folder)item;
@ -243,7 +244,6 @@ namespace MediaBrowser.Api
item.DisplayMediaType = request.DisplayMediaType; item.DisplayMediaType = request.DisplayMediaType;
item.CommunityRating = request.CommunityRating; item.CommunityRating = request.CommunityRating;
item.VoteCount = request.VoteCount;
item.HomePageUrl = request.HomePageUrl; item.HomePageUrl = request.HomePageUrl;
item.IndexNumber = request.IndexNumber; item.IndexNumber = request.IndexNumber;
item.ParentIndexNumber = request.ParentIndexNumber; item.ParentIndexNumber = request.ParentIndexNumber;

View File

@ -27,6 +27,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Api.Library namespace MediaBrowser.Api.Library
{ {
@ -675,7 +676,6 @@ namespace MediaBrowser.Api.Library
Limit = 0, Limit = 0,
Recursive = true, Recursive = true,
IsVirtualItem = false, IsVirtualItem = false,
SourceTypes = new[] { SourceType.Library },
IsFavorite = request.IsFavorite, IsFavorite = request.IsFavorite,
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
{ {
@ -831,6 +831,11 @@ namespace MediaBrowser.Api.Library
: (Folder)_libraryManager.RootFolder) : (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id); : _libraryManager.GetItemById(request.Id);
if (item == null)
{
throw new ResourceNotFoundException("Item not found.");
}
while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.GetParent() != null) while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
{ {
item = item.GetParent(); item = item.GetParent();
@ -875,6 +880,11 @@ namespace MediaBrowser.Api.Library
: (Folder)_libraryManager.RootFolder) : (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id); : _libraryManager.GetItemById(request.Id);
if (item == null)
{
throw new ResourceNotFoundException("Item not found.");
}
while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.GetParent() != null) while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
{ {
item = item.GetParent(); item = item.GetParent();

View File

@ -783,7 +783,6 @@ namespace MediaBrowser.Api.Playback
state.OutputContainer = (container ?? string.Empty).TrimStart('.'); state.OutputContainer = (container ?? string.Empty).TrimStart('.');
state.OutputAudioBitrate = EncodingHelper.GetAudioBitrateParam(state.Request, state.AudioStream); state.OutputAudioBitrate = EncodingHelper.GetAudioBitrateParam(state.Request, state.AudioStream);
state.OutputAudioSampleRate = request.AudioSampleRate;
state.OutputAudioCodec = state.Request.AudioCodec; state.OutputAudioCodec = state.Request.AudioCodec;

View File

@ -106,6 +106,13 @@ namespace MediaBrowser.Api.Playback
} }
public async Task<object> Post(OpenMediaSource request) public async Task<object> Post(OpenMediaSource request)
{
var result = await OpenMediaSource(request).ConfigureAwait(false);
return ToOptimizedResult(result);
}
private async Task<LiveStreamResponse> OpenMediaSource(OpenMediaSource request)
{ {
var authInfo = _authContext.GetAuthorizationInfo(Request); var authInfo = _authContext.GetAuthorizationInfo(Request);
@ -137,7 +144,7 @@ namespace MediaBrowser.Api.Playback
} }
} }
return ToOptimizedResult(result); return result;
} }
public void Post(CloseMediaSource request) public void Post(CloseMediaSource request)
@ -172,6 +179,34 @@ namespace MediaBrowser.Api.Playback
SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId, request.EnableDirectPlay, request.ForceDirectPlayRemoteMediaSource, request.EnableDirectStream, request.EnableTranscoding, request.AllowVideoStreamCopy, request.AllowAudioStreamCopy); SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId, request.EnableDirectPlay, request.ForceDirectPlayRemoteMediaSource, request.EnableDirectStream, request.EnableTranscoding, request.AllowVideoStreamCopy, request.AllowAudioStreamCopy);
} }
if (request.AutoOpenLiveStream)
{
var mediaSource = string.IsNullOrWhiteSpace(request.MediaSourceId) ? info.MediaSources.FirstOrDefault() : info.MediaSources.FirstOrDefault(i => string.Equals(i.Id, request.MediaSourceId, StringComparison.Ordinal));
if (mediaSource != null && mediaSource.RequiresOpening && string.IsNullOrWhiteSpace(mediaSource.LiveStreamId))
{
var openStreamResult = await OpenMediaSource(new OpenMediaSource
{
AudioStreamIndex = request.AudioStreamIndex,
DeviceProfile = request.DeviceProfile,
EnableDirectPlay = request.EnableDirectPlay,
EnableDirectStream = request.EnableDirectStream,
ForceDirectPlayRemoteMediaSource = request.ForceDirectPlayRemoteMediaSource,
ItemId = request.Id,
MaxAudioChannels = request.MaxAudioChannels,
MaxStreamingBitrate = request.MaxStreamingBitrate,
PlaySessionId = info.PlaySessionId,
StartTimeTicks = request.StartTimeTicks,
SubtitleStreamIndex = request.SubtitleStreamIndex,
UserId = request.UserId,
OpenToken = mediaSource.OpenToken
}).ConfigureAwait(false);
info.MediaSources = new List<MediaSourceInfo> { openStreamResult.MediaSource };
}
}
return info; return info;
} }
@ -322,6 +357,19 @@ namespace MediaBrowser.Api.Playback
mediaSource.SupportsTranscoding = false; mediaSource.SupportsTranscoding = false;
} }
if (item is Audio)
{
Logger.Info("User policy for {0}. EnableAudioPlaybackTranscoding: {1}", user.Name, user.Policy.EnableAudioPlaybackTranscoding);
}
else
{
Logger.Info("User policy for {0}. EnablePlaybackRemuxing: {1} EnableVideoPlaybackTranscoding: {2} EnableAudioPlaybackTranscoding: {3}",
user.Name,
user.Policy.EnablePlaybackRemuxing,
user.Policy.EnableVideoPlaybackTranscoding,
user.Policy.EnableAudioPlaybackTranscoding);
}
if (mediaSource.SupportsDirectPlay) if (mediaSource.SupportsDirectPlay)
{ {
if (mediaSource.IsRemote && forceDirectPlayRemoteMediaSource) if (mediaSource.IsRemote && forceDirectPlayRemoteMediaSource)

View File

@ -250,248 +250,6 @@ namespace MediaBrowser.Api.Playback
public DeviceProfile DeviceProfile { get; set; } public DeviceProfile DeviceProfile { get; set; }
public int? TotalOutputBitrate
{
get
{
return (OutputAudioBitrate ?? 0) + (OutputVideoBitrate ?? 0);
}
}
public int? OutputWidth
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
VideoRequest.Width,
VideoRequest.Height,
VideoRequest.MaxWidth,
VideoRequest.MaxHeight);
return Convert.ToInt32(newSize.Width);
}
if (VideoRequest == null)
{
return null;
}
return VideoRequest.MaxWidth ?? VideoRequest.Width;
}
}
public int? OutputHeight
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
VideoRequest.Width,
VideoRequest.Height,
VideoRequest.MaxWidth,
VideoRequest.MaxHeight);
return Convert.ToInt32(newSize.Height);
}
if (VideoRequest == null)
{
return null;
}
return VideoRequest.MaxHeight ?? VideoRequest.Height;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetVideoBitDepth
{
get
{
var stream = VideoStream;
return stream == null || !Request.Static ? null : stream.BitDepth;
}
}
/// <summary>
/// Gets the target reference frames.
/// </summary>
/// <value>The target reference frames.</value>
public int? TargetRefFrames
{
get
{
var stream = VideoStream;
return stream == null || !Request.Static ? null : stream.RefFrames;
}
}
public int? TargetVideoStreamCount
{
get
{
if (Request.Static)
{
return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Video, 1);
}
}
public int? TargetAudioStreamCount
{
get
{
if (Request.Static)
{
return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Audio, 1);
}
}
public bool? IsTargetAnamorphic
{
get
{
if (Request.Static)
{
return VideoStream == null ? null : VideoStream.IsAnamorphic;
}
return false;
}
}
public bool? IsTargetInterlaced
{
get
{
if (Request.Static)
{
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
if (DeInterlace)
{
return false;
}
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
}
private int? GetMediaStreamCount(MediaStreamType type, int limit)
{
var count = MediaSource.GetStreamCount(type);
if (count.HasValue)
{
count = Math.Min(count.Value, limit);
}
return count;
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public float? TargetFramerate
{
get
{
var stream = VideoStream;
var requestedFramerate = VideoRequest.MaxFramerate ?? VideoRequest.Framerate;
return requestedFramerate.HasValue && !Request.Static
? requestedFramerate
: stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
}
}
public TransportStreamTimestamp TargetTimestamp
{
get
{
var defaultValue = string.Equals(OutputContainer, "m2ts", StringComparison.OrdinalIgnoreCase) ?
TransportStreamTimestamp.Valid :
TransportStreamTimestamp.None;
return !Request.Static
? defaultValue
: InputTimestamp;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetPacketLength
{
get
{
var stream = VideoStream;
return !Request.Static
? null
: stream == null ? null : stream.PacketLength;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public string TargetVideoProfile
{
get
{
var stream = VideoStream;
return !string.IsNullOrEmpty(VideoRequest.Profile) && !Request.Static
? VideoRequest.Profile
: stream == null ? null : stream.Profile;
}
}
public string TargetVideoCodecTag
{
get
{
var stream = VideoStream;
return !Request.Static
? null
: stream == null ? null : stream.CodecTag;
}
}
public bool? IsTargetAVC
{
get
{
if (Request.Static)
{
return VideoStream == null ? null : VideoStream.IsAVC;
}
return true;
}
}
public TranscodingJob TranscodingJob; public TranscodingJob TranscodingJob;
public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate) public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
{ {

View File

@ -98,7 +98,7 @@ namespace MediaBrowser.Api.Session
[Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")] [Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")]
[Authenticated] [Authenticated]
public class SendPlaystateCommand : IReturnVoid public class SendPlaystateCommand : PlaystateRequest, IReturnVoid
{ {
/// <summary> /// <summary>
/// Gets or sets the id. /// Gets or sets the id.
@ -106,19 +106,6 @@ namespace MediaBrowser.Api.Session
/// <value>The id.</value> /// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; } public string Id { get; set; }
/// <summary>
/// Gets or sets the position to seek to
/// </summary>
[ApiMember(Name = "SeekPositionTicks", Description = "The position to seek to.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public long? SeekPositionTicks { get; set; }
/// <summary>
/// Gets or sets the play command.
/// </summary>
/// <value>The play command.</value>
[ApiMember(Name = "Command", Description = "The command to send - stop, pause, unpause, nexttrack, previoustrack, seek, fullscreen.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public PlaystateCommand Command { get; set; }
} }
[Route("/Sessions/{Id}/System/{Command}", "POST", Summary = "Issues a system command to a client")] [Route("/Sessions/{Id}/System/{Command}", "POST", Summary = "Issues a system command to a client")]
@ -414,13 +401,7 @@ namespace MediaBrowser.Api.Session
public void Post(SendPlaystateCommand request) public void Post(SendPlaystateCommand request)
{ {
var command = new PlaystateRequest var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Result.Id, request.Id, request, CancellationToken.None);
{
Command = request.Command,
SeekPositionTicks = request.SeekPositionTicks
};
var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Result.Id, request.Id, command, CancellationToken.None);
Task.WaitAll(task); Task.WaitAll(task);
} }

View File

@ -100,7 +100,6 @@ namespace MediaBrowser.Api
config.EnableSimpleArtistDetection = true; config.EnableSimpleArtistDetection = true;
config.EnableNormalizedItemByNameIds = true; config.EnableNormalizedItemByNameIds = true;
config.DisableLiveTvChannelUserDataName = true; config.DisableLiveTvChannelUserDataName = true;
config.EnableSimpleSortNameHandling = true;
} }
public void Post(UpdateStartupConfiguration request) public void Post(UpdateStartupConfiguration request)

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -72,9 +72,6 @@
<Name>MediaBrowser.Model</Name> <Name>MediaBrowser.Model</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<ItemGroup /> <ItemGroup />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View File

@ -58,7 +58,7 @@ namespace MediaBrowser.Common.Updates
} }
else if (updateLevel == PackageVersionClass.Beta) else if (updateLevel == PackageVersionClass.Beta)
{ {
obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray(); obj = obj.Where(i => i.prerelease && i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray();
} }
else if (updateLevel == PackageVersionClass.Dev) else if (updateLevel == PackageVersionClass.Dev)
{ {
@ -81,7 +81,7 @@ namespace MediaBrowser.Common.Updates
{ {
if (updateLevel == PackageVersionClass.Beta) if (updateLevel == PackageVersionClass.Beta)
{ {
return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase); return i.prerelease && i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase);
} }
if (updateLevel == PackageVersionClass.Dev) if (updateLevel == PackageVersionClass.Dev)
{ {

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -35,7 +35,6 @@ namespace MediaBrowser.Controller.Channels
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.Channel; } get { return SourceType.Channel; }
set { }
} }
protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query) protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)

View File

@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Drawing
/// <summary> /// <summary>
/// Encodes the image. /// Encodes the image.
/// </summary> /// </summary>
string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat outputFormat); string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
/// <summary> /// <summary>
/// Creates the image collage. /// Creates the image collage.

View File

@ -87,7 +87,7 @@ namespace MediaBrowser.Controller.Entities
private List<Guid> _childrenIds = null; private List<Guid> _childrenIds = null;
private readonly object _childIdsLock = new object(); private readonly object _childIdsLock = new object();
protected override IEnumerable<BaseItem> LoadChildren() protected override List<BaseItem> LoadChildren()
{ {
lock (_childIdsLock) lock (_childIdsLock)
{ {

View File

@ -131,7 +131,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// Creates the name of the sort. /// Creates the name of the sort.
/// </summary> /// </summary>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
protected override string CreateSortNameInternal() protected override string CreateSortName()
{ {
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "") return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name; + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;

View File

@ -90,7 +90,7 @@ namespace MediaBrowser.Controller.Entities.Audio
} }
[IgnoreDataMember] [IgnoreDataMember]
protected override IEnumerable<BaseItem> ActualChildren public override IEnumerable<BaseItem> Children
{ {
get get
{ {
@ -99,7 +99,7 @@ namespace MediaBrowser.Controller.Entities.Audio
return new List<BaseItem>(); return new List<BaseItem>();
} }
return base.ActualChildren; return base.Children;
} }
} }

View File

@ -54,7 +54,6 @@ namespace MediaBrowser.Controller.Entities
ImageInfos = new List<ItemImageInfo>(); ImageInfos = new List<ItemImageInfo>();
InheritedTags = new List<string>(); InheritedTags = new List<string>();
ProductionLocations = new List<string>(); ProductionLocations = new List<string>();
SourceType = SourceType.Library;
} }
public static readonly char[] SlugReplaceChars = { '?', '/', '&' }; public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
@ -187,15 +186,10 @@ namespace MediaBrowser.Controller.Entities
} }
set set
{ {
var isSortNameDefault = IsSortNameDefault(SortName);
_name = value; _name = value;
if (isSortNameDefault) // lazy load this again
{ _sortName = null;
// lazy load this again
SortName = null;
}
} }
} }
@ -279,7 +273,18 @@ namespace MediaBrowser.Controller.Entities
public virtual string Path { get; set; } public virtual string Path { get; set; }
[IgnoreDataMember] [IgnoreDataMember]
public virtual SourceType SourceType { get; set; } public virtual SourceType SourceType
{
get
{
if (!string.IsNullOrWhiteSpace(ChannelId))
{
return SourceType.Channel;
}
return SourceType.Library;
}
}
/// <summary> /// <summary>
/// Returns the folder containing the item. /// Returns the folder containing the item.
@ -586,6 +591,7 @@ namespace MediaBrowser.Controller.Entities
} }
} }
private string _forcedSortName;
/// <summary> /// <summary>
/// Gets or sets the name of the forced sort. /// Gets or sets the name of the forced sort.
/// </summary> /// </summary>
@ -593,42 +599,8 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public string ForcedSortName public string ForcedSortName
{ {
get get { return _forcedSortName; }
{ set { _forcedSortName = value; _sortName = null; }
var sortName = SortName;
if (string.IsNullOrWhiteSpace(sortName))
{
return null;
}
if (string.Equals(sortName, CreateSortName(), StringComparison.OrdinalIgnoreCase))
{
return null;
}
return sortName;
}
set
{
if (string.IsNullOrWhiteSpace(value))
{
SortName = null;
}
else
{
var newValue = CreateSortNameFromCustomValue(value);
if (string.Equals(newValue, CreateSortName(), StringComparison.OrdinalIgnoreCase))
{
SortName = null;
}
else
{
SortName = newValue;
}
}
}
} }
private string _sortName; private string _sortName;
@ -643,7 +615,15 @@ namespace MediaBrowser.Controller.Entities
{ {
if (_sortName == null) if (_sortName == null)
{ {
_sortName = CreateSortName(); if (!string.IsNullOrWhiteSpace(ForcedSortName))
{
// Need the ToLower because that's what CreateSortName does
_sortName = ModifySortChunks(ForcedSortName).ToLower();
}
else
{
_sortName = CreateSortName();
}
} }
return _sortName; return _sortName;
} }
@ -653,31 +633,6 @@ namespace MediaBrowser.Controller.Entities
} }
} }
private string CreateSortNameFromCustomValue(string value)
{
return string.IsNullOrWhiteSpace(value) ? null : NormalizeCustomSortName(value);
}
protected virtual string NormalizeCustomSortName(string value)
{
if (ConfigurationManager.Configuration.EnableSimpleSortNameHandling)
{
return value.RemoveDiacritics().ToLower();
}
return ModifySortChunks(value).ToLower();
}
public bool IsSortNameDefault(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return true;
}
return string.Equals(CreateSortNameFromCustomValue(value), CreateSortName(), StringComparison.OrdinalIgnoreCase);
}
public string GetInternalMetadataPath() public string GetInternalMetadataPath()
{ {
var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath; var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath;
@ -699,22 +654,14 @@ namespace MediaBrowser.Controller.Entities
return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
} }
protected string CreateSortName()
{
if (string.IsNullOrWhiteSpace(Name))
{
return null;
}
return CreateSortNameInternal();
}
/// <summary> /// <summary>
/// Creates the name of the sort. /// Creates the name of the sort.
/// </summary> /// </summary>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
protected virtual string CreateSortNameInternal() protected virtual string CreateSortName()
{ {
if (Name == null) return null; //some items may not have name filled in properly
if (!EnableAlphaNumericSorting) if (!EnableAlphaNumericSorting)
{ {
return Name.TrimStart(); return Name.TrimStart();
@ -951,13 +898,6 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember] [IgnoreDataMember]
public float? CommunityRating { get; set; } public float? CommunityRating { get; set; }
/// <summary>
/// Gets or sets the community rating vote count.
/// </summary>
/// <value>The community rating vote count.</value>
[IgnoreDataMember]
public int? VoteCount { get; set; }
/// <summary> /// <summary>
/// Gets or sets the run time ticks. /// Gets or sets the run time ticks.
/// </summary> /// </summary>
@ -1367,6 +1307,7 @@ namespace MediaBrowser.Controller.Entities
public void AfterMetadataRefresh() public void AfterMetadataRefresh()
{ {
_sortName = null;
} }
/// <summary> /// <summary>
@ -2253,6 +2194,8 @@ namespace MediaBrowser.Controller.Entities
/// </summary> /// </summary>
public virtual bool BeforeMetadataRefresh() public virtual bool BeforeMetadataRefresh()
{ {
_sortName = null;
var hasChanges = false; var hasChanges = false;
if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path)) if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path))

View File

@ -311,12 +311,12 @@ namespace MediaBrowser.Controller.Entities
/// </summary> /// </summary>
/// <value>The actual children.</value> /// <value>The actual children.</value>
[IgnoreDataMember] [IgnoreDataMember]
protected override IEnumerable<BaseItem> ActualChildren public override IEnumerable<BaseItem> Children
{ {
get { return GetActualChildren(); } get { return GetActualChildren(); }
} }
private IEnumerable<BaseItem> GetActualChildren() public IEnumerable<BaseItem> GetActualChildren()
{ {
return GetPhysicalFolders(true).SelectMany(c => c.Children); return GetPhysicalFolders(true).SelectMany(c => c.Children);
} }

View File

@ -185,7 +185,7 @@ namespace MediaBrowser.Controller.Entities
item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType()); item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType());
} }
if (ActualChildren.Any(i => i.Id == item.Id)) if (Children.Any(i => i.Id == item.Id))
{ {
throw new ArgumentException(string.Format("A child with the Id {0} already exists.", item.Id)); throw new ArgumentException(string.Format("A child with the Id {0} already exists.", item.Id));
} }
@ -243,7 +243,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary> /// </summary>
/// <value>The actual children.</value> /// <value>The actual children.</value>
[IgnoreDataMember] [IgnoreDataMember]
protected virtual IEnumerable<BaseItem> ActualChildren public virtual IEnumerable<BaseItem> Children
{ {
get get
{ {
@ -251,16 +251,6 @@ namespace MediaBrowser.Controller.Entities
} }
} }
/// <summary>
/// thread-safe access to the actual children of this folder - without regard to user
/// </summary>
/// <value>The children.</value>
[IgnoreDataMember]
public IEnumerable<BaseItem> Children
{
get { return ActualChildren.ToList(); }
}
/// <summary> /// <summary>
/// thread-safe access to all recursive children of this folder - without regard to user /// thread-safe access to all recursive children of this folder - without regard to user
/// </summary> /// </summary>
@ -301,7 +291,7 @@ namespace MediaBrowser.Controller.Entities
/// Loads our children. Validation will occur externally. /// Loads our children. Validation will occur externally.
/// We want this sychronous. /// We want this sychronous.
/// </summary> /// </summary>
protected virtual IEnumerable<BaseItem> LoadChildren() protected virtual List<BaseItem> LoadChildren()
{ {
//Logger.Debug("Loading children from {0} {1} {2}", GetType().Name, Id, Path); //Logger.Debug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
//just load our children from the repo - the library will be validated and maintained in other processes //just load our children from the repo - the library will be validated and maintained in other processes
@ -330,7 +320,9 @@ namespace MediaBrowser.Controller.Entities
{ {
var dictionary = new Dictionary<Guid, BaseItem>(); var dictionary = new Dictionary<Guid, BaseItem>();
foreach (var child in ActualChildren) var childrenList = Children.ToList();
foreach (var child in childrenList)
{ {
var id = child.Id; var id = child.Id;
if (dictionary.ContainsKey(id)) if (dictionary.ContainsKey(id))
@ -466,7 +458,7 @@ namespace MediaBrowser.Controller.Entities
if (recursive) if (recursive)
{ {
await ValidateSubFolders(ActualChildren.OfType<Folder>().ToList(), directoryService, progress, cancellationToken).ConfigureAwait(false); await ValidateSubFolders(Children.ToList().OfType<Folder>().ToList(), directoryService, progress, cancellationToken).ConfigureAwait(false);
} }
progress.Report(20); progress.Report(20);
@ -494,7 +486,7 @@ namespace MediaBrowser.Controller.Entities
private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken) private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{ {
var children = ActualChildren.ToList(); var children = Children.ToList();
var percentages = new Dictionary<Guid, double>(children.Count); var percentages = new Dictionary<Guid, double>(children.Count);
var numComplete = 0; var numComplete = 0;
@ -668,7 +660,7 @@ namespace MediaBrowser.Controller.Entities
/// Get our children from the repo - stubbed for now /// Get our children from the repo - stubbed for now
/// </summary> /// </summary>
/// <returns>IEnumerable{BaseItem}.</returns> /// <returns>IEnumerable{BaseItem}.</returns>
protected IEnumerable<BaseItem> GetCachedChildren() protected List<BaseItem> GetCachedChildren()
{ {
return ItemRepository.GetItemList(new InternalItemsQuery return ItemRepository.GetItemList(new InternalItemsQuery
{ {

View File

@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Entities
/// <value>The date last saved.</value> /// <value>The date last saved.</value>
DateTime DateLastSaved { get; set; } DateTime DateLastSaved { get; set; }
SourceType SourceType { get; set; } SourceType SourceType { get; }
/// <summary> /// <summary>
/// Gets or sets the date last refreshed. /// Gets or sets the date last refreshed.

View File

@ -148,9 +148,8 @@ namespace MediaBrowser.Controller.Entities
} }
public string[] PresetViews { get; set; } public string[] PresetViews { get; set; }
public SourceType[] SourceTypes { get; set; }
public SourceType[] ExcludeSourceTypes { get; set; }
public TrailerType[] TrailerTypes { get; set; } public TrailerType[] TrailerTypes { get; set; }
public SourceType[] SourceTypes { get; set; }
public DayOfWeek[] AirDays { get; set; } public DayOfWeek[] AirDays { get; set; }
public SeriesStatus[] SeriesStatuses { get; set; } public SeriesStatus[] SeriesStatuses { get; set; }
@ -215,9 +214,8 @@ namespace MediaBrowser.Controller.Entities
ExcludeTags = new string[] { }; ExcludeTags = new string[] { };
ExcludeInheritedTags = new string[] { }; ExcludeInheritedTags = new string[] { };
PresetViews = new string[] { }; PresetViews = new string[] { };
SourceTypes = new SourceType[] { };
ExcludeSourceTypes = new SourceType[] { };
TrailerTypes = new TrailerType[] { }; TrailerTypes = new TrailerType[] { };
SourceTypes = new SourceType[] { };
AirDays = new DayOfWeek[] { }; AirDays = new DayOfWeek[] { };
SeriesStatuses = new SeriesStatus[] { }; SeriesStatuses = new SeriesStatus[] { };
OrderBy = new List<Tuple<string, SortOrder>>(); OrderBy = new List<Tuple<string, SortOrder>>();

View File

@ -11,13 +11,11 @@ namespace MediaBrowser.Controller.Entities
public int? MaxListOrder { get; set; } public int? MaxListOrder { get; set; }
public Guid AppearsInItemId { get; set; } public Guid AppearsInItemId { get; set; }
public string NameContains { get; set; } public string NameContains { get; set; }
public SourceType[] SourceTypes { get; set; }
public InternalPeopleQuery() public InternalPeopleQuery()
{ {
PersonTypes = new List<string>(); PersonTypes = new List<string>();
ExcludePersonTypes = new List<string>(); ExcludePersonTypes = new List<string>();
SourceTypes = new SourceType[] { };
} }
} }
} }

View File

@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return new List<BaseItem>(); return new List<BaseItem>();
} }
protected override IEnumerable<BaseItem> LoadChildren() protected override List<BaseItem> LoadChildren()
{ {
if (IsLegacyBoxSet) if (IsLegacyBoxSet)
{ {

View File

@ -237,7 +237,7 @@ namespace MediaBrowser.Controller.Entities.TV
/// Creates the name of the sort. /// Creates the name of the sort.
/// </summary> /// </summary>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
protected override string CreateSortNameInternal() protected override string CreateSortName()
{ {
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "") return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "")
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name; + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;

View File

@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.Entities.TV
/// Creates the name of the sort. /// Creates the name of the sort.
/// </summary> /// </summary>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
protected override string CreateSortNameInternal() protected override string CreateSortName()
{ {
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name; return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
} }

View File

@ -18,7 +18,7 @@ namespace MediaBrowser.Controller.Entities
{ {
private List<Guid> _childrenIds = null; private List<Guid> _childrenIds = null;
private readonly object _childIdsLock = new object(); private readonly object _childIdsLock = new object();
protected override IEnumerable<BaseItem> LoadChildren() protected override List<BaseItem> LoadChildren()
{ {
lock (_childIdsLock) lock (_childIdsLock)
{ {

View File

@ -633,14 +633,17 @@ namespace MediaBrowser.Controller.Entities
if (info.Path.StartsWith("Http", StringComparison.OrdinalIgnoreCase)) if (info.Path.StartsWith("Http", StringComparison.OrdinalIgnoreCase))
{ {
info.Protocol = MediaProtocol.Http; info.Protocol = MediaProtocol.Http;
info.SupportsDirectStream = false;
} }
else if (info.Path.StartsWith("Rtmp", StringComparison.OrdinalIgnoreCase)) else if (info.Path.StartsWith("Rtmp", StringComparison.OrdinalIgnoreCase))
{ {
info.Protocol = MediaProtocol.Rtmp; info.Protocol = MediaProtocol.Rtmp;
info.SupportsDirectStream = false;
} }
else if (info.Path.StartsWith("Rtsp", StringComparison.OrdinalIgnoreCase)) else if (info.Path.StartsWith("Rtsp", StringComparison.OrdinalIgnoreCase))
{ {
info.Protocol = MediaProtocol.Rtsp; info.Protocol = MediaProtocol.Rtsp;
info.SupportsDirectStream = false;
} }
else else
{ {

View File

@ -527,6 +527,8 @@ namespace MediaBrowser.Controller.Library
/// <returns>QueryResult&lt;BaseItem&gt;.</returns> /// <returns>QueryResult&lt;BaseItem&gt;.</returns>
IEnumerable<BaseItem> GetItemList(InternalItemsQuery query); IEnumerable<BaseItem> GetItemList(InternalItemsQuery query);
IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent);
/// <summary> /// <summary>
/// Gets the items. /// Gets the items.
/// </summary> /// </summary>

View File

@ -1,5 +1,5 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Dto;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -13,7 +13,7 @@ namespace MediaBrowser.Controller.Library
public List<User> Users { get; set; } public List<User> Users { get; set; }
public long? PlaybackPositionTicks { get; set; } public long? PlaybackPositionTicks { get; set; }
public BaseItem Item { get; set; } public BaseItem Item { get; set; }
public BaseItemInfo MediaInfo { get; set; } public BaseItemDto MediaInfo { get; set; }
public string MediaSourceId { get; set; } public string MediaSourceId { get; set; }
public bool IsPaused { get; set; } public bool IsPaused { get; set; }
public bool IsAutomated { get; set; } public bool IsAutomated { get; set; }

View File

@ -43,7 +43,6 @@ namespace MediaBrowser.Controller.LiveTv
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.LiveTV; } get { return SourceType.LiveTV; }
set { }
} }
[IgnoreDataMember] [IgnoreDataMember]

View File

@ -55,7 +55,6 @@ namespace MediaBrowser.Controller.LiveTv
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.LiveTV; } get { return SourceType.LiveTV; }
set { }
} }
[IgnoreDataMember] [IgnoreDataMember]
@ -89,7 +88,7 @@ namespace MediaBrowser.Controller.LiveTv
} }
} }
protected override string CreateSortNameInternal() protected override string CreateSortName()
{ {
if (!string.IsNullOrEmpty(Number)) if (!string.IsNullOrEmpty(Number))
{ {

View File

@ -65,7 +65,6 @@ namespace MediaBrowser.Controller.LiveTv
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.LiveTV; } get { return SourceType.LiveTV; }
set { }
} }
/// <summary> /// <summary>

View File

@ -42,7 +42,6 @@ namespace MediaBrowser.Controller.LiveTv
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.LiveTV; } get { return SourceType.LiveTV; }
set { }
} }
[IgnoreDataMember] [IgnoreDataMember]

View File

@ -107,8 +107,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The image URL.</value> /// <value>The image URL.</value>
public string ImageUrl { get; set; } public string ImageUrl { get; set; }
public string ThumbImageUrl { get; set; }
public string LogoImageUrl { get; set; } public string LogoImageUrl { get; set; }
public string BackdropImageUrl { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this instance has image. /// Gets or sets a value indicating whether this instance has image.
/// </summary> /// </summary>

View File

@ -30,7 +30,6 @@ namespace MediaBrowser.Controller.LiveTv
public override SourceType SourceType public override SourceType SourceType
{ {
get { return SourceType.LiveTV; } get { return SourceType.LiveTV; }
set { }
} }
} }
} }

View File

@ -36,10 +36,6 @@
<PropertyGroup> <PropertyGroup>
<RunPostBuildEvent>Always</RunPostBuildEvent> <RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="project.json" />
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\SharedVersion.cs"> <Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link> <Link>Properties\SharedVersion.cs</Link>

View File

@ -1604,7 +1604,7 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
// Only do this for video files due to sometimes unpredictable codec names coming from BDInfo // Only do this for video files due to sometimes unpredictable codec names coming from BDInfo
if (state.RunTimeTicks.HasValue && state.VideoType == VideoType.VideoFile && string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType)) if (state.VideoType == VideoType.VideoFile && state.RunTimeTicks.HasValue && string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType))
{ {
foreach (var stream in state.MediaSource.MediaStreams) foreach (var stream in state.MediaSource.MediaStreams)
{ {
@ -1806,6 +1806,20 @@ namespace MediaBrowser.Controller.MediaEncoding
break; break;
} }
} }
else if (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
{
switch (state.MediaSource.VideoStream.Codec.ToLower())
{
case "avc":
case "h264":
if (_mediaEncoder.SupportsDecoder("h264_cuvid"))
{
return "-c:v h264_cuvid ";
}
break;
}
}
} }
// leave blank so ffmpeg will decide // leave blank so ffmpeg will decide

View File

@ -8,6 +8,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Drawing;
namespace MediaBrowser.Controller.MediaEncoding namespace MediaBrowser.Controller.MediaEncoding
{ {
@ -134,7 +135,6 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? OutputAudioBitrate; public int? OutputAudioBitrate;
public int? OutputAudioChannels; public int? OutputAudioChannels;
public int? OutputAudioSampleRate;
public bool DeInterlace { get; set; } public bool DeInterlace { get; set; }
public bool IsVideoRequest { get; set; } public bool IsVideoRequest { get; set; }
public TranscodingJobType TranscodingType { get; set; } public TranscodingJobType TranscodingType { get; set; }
@ -173,6 +173,97 @@ namespace MediaBrowser.Controller.MediaEncoding
return false; return false;
} }
public int? TotalOutputBitrate
{
get
{
return (OutputAudioBitrate ?? 0) + (OutputVideoBitrate ?? 0);
}
}
public int? OutputWidth
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
BaseRequest.Width,
BaseRequest.Height,
BaseRequest.MaxWidth,
BaseRequest.MaxHeight);
return Convert.ToInt32(newSize.Width);
}
if (!IsVideoRequest)
{
return null;
}
return BaseRequest.MaxWidth ?? BaseRequest.Width;
}
}
public int? OutputHeight
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
BaseRequest.Width,
BaseRequest.Height,
BaseRequest.MaxWidth,
BaseRequest.MaxHeight);
return Convert.ToInt32(newSize.Height);
}
if (!IsVideoRequest)
{
return null;
}
return BaseRequest.MaxHeight ?? BaseRequest.Height;
}
}
public int? OutputAudioSampleRate
{
get
{
if (BaseRequest.Static || string.Equals(OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (AudioStream != null)
{
return AudioStream.SampleRate;
}
}
else if (BaseRequest.AudioSampleRate.HasValue)
{
// Don't exceed what the encoder supports
// Seeing issues of attempting to encode to 88200
return Math.Min(44100, BaseRequest.AudioSampleRate.Value);
}
return null;
}
}
/// <summary> /// <summary>
/// Predicts the audio sample rate that will be in the output stream /// Predicts the audio sample rate that will be in the output stream
/// </summary> /// </summary>
@ -189,6 +280,180 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
} }
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetVideoBitDepth
{
get
{
var stream = VideoStream;
return stream == null || !BaseRequest.Static ? null : stream.BitDepth;
}
}
/// <summary>
/// Gets the target reference frames.
/// </summary>
/// <value>The target reference frames.</value>
public int? TargetRefFrames
{
get
{
var stream = VideoStream;
return stream == null || !BaseRequest.Static ? null : stream.RefFrames;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public float? TargetFramerate
{
get
{
var stream = VideoStream;
var requestedFramerate = BaseRequest.MaxFramerate ?? BaseRequest.Framerate;
return requestedFramerate.HasValue && !BaseRequest.Static
? requestedFramerate
: stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
}
}
public TransportStreamTimestamp TargetTimestamp
{
get
{
var defaultValue = string.Equals(OutputContainer, "m2ts", StringComparison.OrdinalIgnoreCase) ?
TransportStreamTimestamp.Valid :
TransportStreamTimestamp.None;
return !BaseRequest.Static
? defaultValue
: InputTimestamp;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetPacketLength
{
get
{
var stream = VideoStream;
return !BaseRequest.Static
? null
: stream == null ? null : stream.PacketLength;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public string TargetVideoProfile
{
get
{
var stream = VideoStream;
return !string.IsNullOrEmpty(BaseRequest.Profile) && !BaseRequest.Static
? BaseRequest.Profile
: stream == null ? null : stream.Profile;
}
}
public string TargetVideoCodecTag
{
get
{
var stream = VideoStream;
return !BaseRequest.Static
? null
: stream == null ? null : stream.CodecTag;
}
}
public bool? IsTargetAnamorphic
{
get
{
if (BaseRequest.Static)
{
return VideoStream == null ? null : VideoStream.IsAnamorphic;
}
return false;
}
}
public bool? IsTargetInterlaced
{
get
{
if (BaseRequest.Static)
{
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
if (DeInterlace)
{
return false;
}
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
}
public bool? IsTargetAVC
{
get
{
if (BaseRequest.Static)
{
return VideoStream == null ? null : VideoStream.IsAVC;
}
return false;
}
}
public int? TargetVideoStreamCount
{
get
{
if (BaseRequest.Static)
{
return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Video, 1);
}
}
public int? TargetAudioStreamCount
{
get
{
if (BaseRequest.Static)
{
return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Audio, 1);
}
}
private int? GetMediaStreamCount(MediaStreamType type, int limit)
{
var count = MediaSource.GetStreamCount(type);
if (count.HasValue)
{
count = Math.Min(count.Value, limit);
}
return count;
}
protected void DisposeIsoMount() protected void DisposeIsoMount()
{ {
if (IsoMount != null) if (IsoMount != null)

View File

@ -74,7 +74,7 @@ namespace MediaBrowser.Controller.Playlists
return true; return true;
} }
protected override IEnumerable<BaseItem> LoadChildren() protected override List<BaseItem> LoadChildren()
{ {
// Save a trip to the database // Save a trip to the database
return new List<BaseItem>(); return new List<BaseItem>();

View File

@ -1,7 +1,7 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Events; using MediaBrowser.Model.Events;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using MediaBrowser.Model.Users; using MediaBrowser.Model.Users;
@ -249,7 +249,7 @@ namespace MediaBrowser.Controller.Session
/// </summary> /// </summary>
/// <param name="sessionId">The session identifier.</param> /// <param name="sessionId">The session identifier.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
void ReportNowViewingItem(string sessionId, BaseItemInfo item); void ReportNowViewingItem(string sessionId, BaseItemDto item);
/// <summary> /// <summary>
/// Authenticates the new session. /// Authenticates the new session.

View File

@ -1,4 +1,4 @@
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -100,13 +100,13 @@ namespace MediaBrowser.Controller.Session
/// Gets or sets the name of the now viewing item. /// Gets or sets the name of the now viewing item.
/// </summary> /// </summary>
/// <value>The name of the now viewing item.</value> /// <value>The name of the now viewing item.</value>
public BaseItemInfo NowViewingItem { get; set; } public BaseItemDto NowViewingItem { get; set; }
/// <summary> /// <summary>
/// Gets or sets the now playing item. /// Gets or sets the now playing item.
/// </summary> /// </summary>
/// <value>The now playing item.</value> /// <value>The now playing item.</value>
public BaseItemInfo NowPlayingItem { get; set; } public BaseItemDto NowPlayingItem { get; set; }
public BaseItem FullNowPlayingItem { get; set; } public BaseItem FullNowPlayingItem { get; set; }

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -40,27 +40,12 @@ namespace MediaBrowser.LocalMetadata.Images
{ {
var parentPath = _fileSystem.GetDirectoryName(item.Path); var parentPath = _fileSystem.GetDirectoryName(item.Path);
var parentPathFiles = directoryService.GetFileSystemEntries(parentPath) var parentPathFiles = directoryService.GetFiles(parentPath)
.ToList(); .ToList();
var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(item.Path); var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(item.Path);
var files = GetFilesFromParentFolder(nameWithoutExtension, parentPathFiles); return GetFilesFromParentFolder(nameWithoutExtension, parentPathFiles);
if (files.Count > 0)
{
return files;
}
var metadataPath = Path.Combine(parentPath, "metadata");
if (parentPathFiles.Any(i => string.Equals(i.FullName, metadataPath, StringComparison.OrdinalIgnoreCase)))
{
var filesInMetadataFolder = _fileSystem.GetFiles(metadataPath, BaseItem.SupportedImageExtensions, false, false);
return GetFilesFromParentFolder(nameWithoutExtension, filesInMetadataFolder);
}
return new List<LocalImageInfo>();
} }
private List<LocalImageInfo> GetFilesFromParentFolder(string filenameWithoutExtension, IEnumerable<FileSystemMetadata> parentPathFiles) private List<LocalImageInfo> GetFilesFromParentFolder(string filenameWithoutExtension, IEnumerable<FileSystemMetadata> parentPathFiles)

View File

@ -44,24 +44,15 @@
<Compile Include="Images\LocalImageProvider.cs" /> <Compile Include="Images\LocalImageProvider.cs" />
<Compile Include="Parsers\BaseItemXmlParser.cs" /> <Compile Include="Parsers\BaseItemXmlParser.cs" />
<Compile Include="Parsers\BoxSetXmlParser.cs" /> <Compile Include="Parsers\BoxSetXmlParser.cs" />
<Compile Include="Parsers\EpisodeXmlParser.cs" />
<Compile Include="Parsers\GameSystemXmlParser.cs" /> <Compile Include="Parsers\GameSystemXmlParser.cs" />
<Compile Include="Parsers\GameXmlParser.cs" /> <Compile Include="Parsers\GameXmlParser.cs" />
<Compile Include="Parsers\MovieXmlParser.cs" />
<Compile Include="Parsers\MusicVideoXmlParser.cs" />
<Compile Include="Parsers\PlaylistXmlParser.cs" /> <Compile Include="Parsers\PlaylistXmlParser.cs" />
<Compile Include="Parsers\SeriesXmlParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\BoxSetXmlProvider.cs" /> <Compile Include="Providers\BoxSetXmlProvider.cs" />
<Compile Include="Providers\EpisodeXmlProvider.cs" />
<Compile Include="Providers\FolderXmlProvider.cs" /> <Compile Include="Providers\FolderXmlProvider.cs" />
<Compile Include="Providers\GameSystemXmlProvider.cs" /> <Compile Include="Providers\GameSystemXmlProvider.cs" />
<Compile Include="Providers\GameXmlProvider.cs" /> <Compile Include="Providers\GameXmlProvider.cs" />
<Compile Include="Providers\MovieXmlProvider.cs" />
<Compile Include="Providers\MusicVideoXmlProvider.cs" />
<Compile Include="Providers\PlaylistXmlProvider.cs" /> <Compile Include="Providers\PlaylistXmlProvider.cs" />
<Compile Include="Providers\SeriesXmlProvider.cs" />
<Compile Include="Providers\VideoXmlProvider.cs" />
<Compile Include="Savers\BaseXmlSaver.cs" /> <Compile Include="Savers\BaseXmlSaver.cs" />
<Compile Include="Savers\BoxSetXmlSaver.cs" /> <Compile Include="Savers\BoxSetXmlSaver.cs" />
<Compile Include="Savers\FolderXmlSaver.cs" /> <Compile Include="Savers\FolderXmlSaver.cs" />

View File

@ -598,20 +598,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
break; break;
} }
case "VoteCount":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int num;
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
{
item.VoteCount = num;
}
}
break;
}
case "CollectionNumber": case "CollectionNumber":
var tmdbCollection = reader.ReadElementContentAsString(); var tmdbCollection = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(tmdbCollection)) if (!string.IsNullOrWhiteSpace(tmdbCollection))

View File

@ -17,9 +17,16 @@ namespace MediaBrowser.LocalMetadata.Parsers
{ {
case "CollectionItems": case "CollectionItems":
using (var subReader = reader.ReadSubtree()) if (!reader.IsEmptyElement)
{ {
FetchFromCollectionItemsNode(subReader, item); using (var subReader = reader.ReadSubtree())
{
FetchFromCollectionItemsNode(subReader, item);
}
}
else
{
reader.Read();
} }
break; break;
@ -45,15 +52,22 @@ namespace MediaBrowser.LocalMetadata.Parsers
{ {
case "CollectionItem": case "CollectionItem":
{ {
using (var subReader = reader.ReadSubtree()) if (!reader.IsEmptyElement)
{ {
var child = GetLinkedChild(subReader); using (var subReader = reader.ReadSubtree())
if (child != null)
{ {
list.Add(child); var child = GetLinkedChild(subReader);
if (child != null)
{
list.Add(child);
}
} }
} }
else
{
reader.Read();
}
break; break;
} }

View File

@ -1,271 +0,0 @@
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Xml;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Parsers
{
/// <summary>
/// Class EpisodeXmlParser
/// </summary>
public class EpisodeXmlParser : BaseItemXmlParser<Episode>
{
private List<LocalImageInfo> _imagesFound;
private readonly IFileSystem _fileSystem;
public EpisodeXmlParser(ILogger logger, IFileSystem fileSystem, IProviderManager providerManager, IXmlReaderSettingsFactory xmlSettings)
: base(logger, providerManager, xmlSettings, fileSystem)
{
_fileSystem = fileSystem;
}
private string _xmlPath;
public void Fetch(MetadataResult<Episode> item,
List<LocalImageInfo> images,
string metadataFile,
CancellationToken cancellationToken)
{
_imagesFound = images;
_xmlPath = metadataFile;
Fetch(item, metadataFile, cancellationToken);
}
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Fetches the data from XML node.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="result">The result.</param>
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Episode> result)
{
var item = result.Item;
switch (reader.Name)
{
case "Episode":
//MB generated metadata is within an "Episode" node
using (var subTree = reader.ReadSubtree())
{
subTree.MoveToContent();
// Loop through each element
while (subTree.Read())
{
if (subTree.NodeType == XmlNodeType.Element)
{
FetchDataFromXmlNode(subTree, result);
}
}
}
break;
case "filename":
{
var filename = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(filename))
{
// Strip off everything but the filename. Some metadata tools like MetaBrowser v1.0 will have an 'episodes' prefix
// even though it's actually using the metadata folder.
filename = Path.GetFileName(filename);
var parentFolder = _fileSystem.GetDirectoryName(_xmlPath);
filename = Path.Combine(parentFolder, filename);
var file = _fileSystem.GetFileInfo(filename);
if (file.Exists)
{
_imagesFound.Add(new LocalImageInfo
{
Type = ImageType.Primary,
FileInfo = file
});
}
}
break;
}
case "SeasonNumber":
{
var number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
{
int num;
if (int.TryParse(number, out num))
{
item.ParentIndexNumber = num;
}
}
break;
}
case "EpisodeNumber":
{
var number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
{
int num;
if (int.TryParse(number, out num))
{
item.IndexNumber = num;
}
}
break;
}
case "EpisodeNumberEnd":
{
var number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
{
int num;
if (int.TryParse(number, out num))
{
item.IndexNumberEnd = num;
}
}
break;
}
case "absolute_number":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AbsoluteEpisodeNumber = rval;
}
}
break;
}
case "DVD_episodenumber":
{
var number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
{
float num;
if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
{
item.DvdEpisodeNumber = num;
}
}
break;
}
case "DVD_season":
{
var number = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(number))
{
float num;
if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
{
item.DvdSeasonNumber = Convert.ToInt32(num);
}
}
break;
}
case "airsbefore_episode":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AirsBeforeEpisodeNumber = rval;
}
}
break;
}
case "airsafter_season":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AirsAfterSeasonNumber = rval;
}
}
break;
}
case "airsbefore_season":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
int rval;
// int.TryParse is local aware, so it can be probamatic, force us culture
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
{
item.AirsBeforeSeasonNumber = rval;
}
}
break;
}
case "EpisodeName":
{
var name = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(name))
{
item.Name = name;
}
break;
}
default:
base.FetchDataFromXmlNode(reader, result);
break;
}
}
}
}

View File

@ -1,65 +0,0 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System.Xml;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Parsers
{
/// <summary>
/// Class EpisodeXmlParser
/// </summary>
public class BaseVideoXmlParser<T> : BaseItemXmlParser<T>
where T : Video
{
/// <summary>
/// Fetches the data from XML node.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="result">The result.</param>
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<T> result)
{
var item = result.Item;
switch (reader.Name)
{
case "TmdbCollectionName":
{
var val = reader.ReadElementContentAsString();
var movie = item as Movie;
if (!string.IsNullOrWhiteSpace(val) && movie != null)
{
movie.CollectionName = val;
}
break;
}
default:
base.FetchDataFromXmlNode(reader, result);
break;
}
}
public BaseVideoXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)
{
}
}
public class MovieXmlParser : BaseVideoXmlParser<Movie>
{
public MovieXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)
{
}
}
public class VideoXmlParser : BaseVideoXmlParser<Video>
{
public VideoXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)
{
}
}
}

View File

@ -1,51 +0,0 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System;
using System.Xml;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Parsers
{
public class MusicVideoXmlParser : BaseVideoXmlParser<MusicVideo>
{
/// <summary>
/// Fetches the data from XML node.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="result">The result.</param>
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<MusicVideo> result)
{
var item = result.Item;
switch (reader.Name)
{
case "Artist":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
var artists = val.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
item.Artists.AddRange(artists);
}
break;
}
case "Album":
item.Album = reader.ReadElementContentAsString();
break;
default:
base.FetchDataFromXmlNode(reader, result);
break;
}
}
public MusicVideoXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)
{
}
}
}

View File

@ -1,102 +0,0 @@
using System;
using System.Xml;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Parsers
{
/// <summary>
/// Class SeriesXmlParser
/// </summary>
public class SeriesXmlParser : BaseItemXmlParser<Series>
{
/// <summary>
/// Fetches the data from XML node.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="result">The result.</param>
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Series> result)
{
var item = result.Item;
switch (reader.Name)
{
case "Series":
//MB generated metadata is within a "Series" node
using (var subTree = reader.ReadSubtree())
{
subTree.MoveToContent();
// Loop through each element
while (subTree.Read())
{
if (subTree.NodeType == XmlNodeType.Element)
{
FetchDataFromXmlNode(subTree, result);
}
}
}
break;
case "id":
string id = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(id))
{
item.SetProviderId(MetadataProviders.Tvdb, id);
}
break;
case "Airs_DayOfWeek":
{
item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
break;
}
case "Airs_Time":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
item.AirTime = val;
}
break;
}
case "Status":
{
var status = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(status))
{
SeriesStatus seriesStatus;
if (Enum.TryParse(status, true, out seriesStatus))
{
item.Status = seriesStatus;
}
else
{
Logger.Info("Unrecognized series status: " + status);
}
}
break;
}
default:
base.FetchDataFromXmlNode(reader, result);
break;
}
}
public SeriesXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)
{
}
}
}

View File

@ -1,50 +0,0 @@
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
public class EpisodeXmlProvider : BaseXmlProvider<Episode>
{
private readonly ILogger _logger;
private readonly IProviderManager _providerManager;
private readonly IXmlReaderSettingsFactory _xmlSettings;
public EpisodeXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlSettings)
: base(fileSystem)
{
_logger = logger;
_providerManager = providerManager;
_xmlSettings = xmlSettings;
}
protected override void Fetch(MetadataResult<Episode> result, string path, CancellationToken cancellationToken)
{
var images = new List<LocalImageInfo>();
var chapters = new List<ChapterInfo>();
new EpisodeXmlParser(_logger, FileSystem, _providerManager, _xmlSettings).Fetch(result, images, path, cancellationToken);
result.Images = images;
}
protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
var metadataPath = FileSystem.GetDirectoryName(info.Path);
metadataPath = Path.Combine(metadataPath, "metadata");
var metadataFile = Path.Combine(metadataPath, Path.ChangeExtension(Path.GetFileName(info.Path), ".xml"));
return directoryService.GetFile(metadataFile);
}
}
}

View File

@ -1,62 +0,0 @@
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
using System.IO;
using System.Threading;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
public class MovieXmlProvider : BaseXmlProvider<Movie>
{
private readonly ILogger _logger;
private readonly IProviderManager _providerManager;
protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
public MovieXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(fileSystem)
{
_logger = logger;
_providerManager = providerManager;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
protected override void Fetch(MetadataResult<Movie> result, string path, CancellationToken cancellationToken)
{
new MovieXmlParser(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
}
protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
return GetXmlFileInfo(info, FileSystem);
}
public static FileSystemMetadata GetXmlFileInfo(ItemInfo info, IFileSystem fileSystem)
{
var fileInfo = fileSystem.GetFileSystemInfo(info.Path);
var directoryInfo = fileInfo.IsDirectory ? fileInfo : fileSystem.GetDirectoryInfo(fileSystem.GetDirectoryName(info.Path));
var directoryPath = directoryInfo.FullName;
var specificFile = Path.Combine(directoryPath, fileSystem.GetFileNameWithoutExtension(info.Path) + ".xml");
var file = fileSystem.GetFileInfo(specificFile);
// In a mixed folder, only {moviename}.xml is supported
if (info.IsInMixedFolder)
{
return file;
}
// If in it's own folder, prefer movie.xml, but allow the specific file as well
var movieFile = fileSystem.GetFileInfo(Path.Combine(directoryPath, "movie.xml"));
return movieFile.Exists ? movieFile : file;
}
}
}

View File

@ -1,37 +0,0 @@
using System.Threading;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
class MusicVideoXmlProvider : BaseXmlProvider<MusicVideo>
{
private readonly ILogger _logger;
private readonly IProviderManager _providerManager;
protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
public MusicVideoXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(fileSystem)
{
_logger = logger;
_providerManager = providerManager;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
protected override void Fetch(MetadataResult<MusicVideo> result, string path, CancellationToken cancellationToken)
{
new MusicVideoXmlParser(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
}
protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
}
}
}

View File

@ -1,50 +0,0 @@
using System.IO;
using System.Threading;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
/// <summary>
/// Class SeriesProviderFromXml
/// </summary>
public class SeriesXmlProvider : BaseXmlProvider<Series>, IHasOrder
{
private readonly ILogger _logger;
private readonly IProviderManager _providerManager;
protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
public SeriesXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(fileSystem)
{
_logger = logger;
_providerManager = providerManager;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
protected override void Fetch(MetadataResult<Series> result, string path, CancellationToken cancellationToken)
{
new SeriesXmlParser(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
}
protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
}
public override int Order
{
get
{
// After Xbmc
return 1;
}
}
}
}

View File

@ -1,37 +0,0 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
using System.Threading;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
class VideoXmlProvider : BaseXmlProvider<Video>
{
private readonly ILogger _logger;
private readonly IProviderManager _providerManager;
protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
public VideoXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(fileSystem)
{
_logger = logger;
_providerManager = providerManager;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
protected override void Fetch(MetadataResult<Video> result, string path, CancellationToken cancellationToken)
{
new VideoXmlParser(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
}
protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
}
}
}

View File

@ -109,7 +109,6 @@ namespace MediaBrowser.LocalMetadata.Savers
"TvDbId", "TvDbId",
"Type", "Type",
"TVRageId", "TVRageId",
"VoteCount",
"Website", "Website",
"Zap2ItId", "Zap2ItId",
"CollectionItems", "CollectionItems",
@ -407,10 +406,6 @@ namespace MediaBrowser.LocalMetadata.Savers
{ {
writer.WriteElementString("Rating", item.CommunityRating.Value.ToString(UsCulture)); writer.WriteElementString("Rating", item.CommunityRating.Value.ToString(UsCulture));
} }
if (item.VoteCount.HasValue)
{
writer.WriteElementString("VoteCount", item.VoteCount.Value.ToString(UsCulture));
}
if (item.ProductionYear.HasValue && !(item is Person)) if (item.ProductionYear.HasValue && !(item is Person))
{ {

View File

@ -1,17 +0,0 @@
{
"frameworks":{
"netstandard1.6":{
"dependencies":{
"NETStandard.Library":"1.6.0",
}
},
".NETPortable,Version=v4.5,Profile=Profile7":{
"buildOptions": {
"define": [ ]
},
"frameworkAssemblies":{
}
}
}
}

View File

@ -90,7 +90,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
"h264_qsv", "h264_qsv",
"hevc_qsv", "hevc_qsv",
"mpeg2_qsv", "mpeg2_qsv",
"vc1_qsv" "vc1_qsv",
"h264_cuvid"
}; };
foreach (var codec in required) foreach (var codec in required)

View File

@ -150,248 +150,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
} }
} }
public int? TotalOutputBitrate
{
get
{
return (OutputAudioBitrate ?? 0) + (OutputVideoBitrate ?? 0);
}
}
public int? OutputWidth
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
Options.Width,
Options.Height,
Options.MaxWidth,
Options.MaxHeight);
return Convert.ToInt32(newSize.Width);
}
if (!IsVideoRequest)
{
return null;
}
return Options.MaxWidth ?? Options.Width;
}
}
public int? OutputHeight
{
get
{
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
{
var size = new ImageSize
{
Width = VideoStream.Width.Value,
Height = VideoStream.Height.Value
};
var newSize = DrawingUtils.Resize(size,
Options.Width,
Options.Height,
Options.MaxWidth,
Options.MaxHeight);
return Convert.ToInt32(newSize.Height);
}
if (!IsVideoRequest)
{
return null;
}
return Options.MaxHeight ?? Options.Height;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetVideoBitDepth
{
get
{
var stream = VideoStream;
return stream == null || !Options.Static ? null : stream.BitDepth;
}
}
/// <summary>
/// Gets the target reference frames.
/// </summary>
/// <value>The target reference frames.</value>
public int? TargetRefFrames
{
get
{
var stream = VideoStream;
return stream == null || !Options.Static ? null : stream.RefFrames;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public float? TargetFramerate
{
get
{
var stream = VideoStream;
var requestedFramerate = Options.MaxFramerate ?? Options.Framerate;
return requestedFramerate.HasValue && !Options.Static
? requestedFramerate
: stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate;
}
}
public TransportStreamTimestamp TargetTimestamp
{
get
{
var defaultValue = string.Equals(OutputContainer, "m2ts", StringComparison.OrdinalIgnoreCase) ?
TransportStreamTimestamp.Valid :
TransportStreamTimestamp.None;
return !Options.Static
? defaultValue
: InputTimestamp;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetPacketLength
{
get
{
var stream = VideoStream;
return !Options.Static
? null
: stream == null ? null : stream.PacketLength;
}
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public string TargetVideoProfile
{
get
{
var stream = VideoStream;
return !string.IsNullOrEmpty(Options.Profile) && !Options.Static
? Options.Profile
: stream == null ? null : stream.Profile;
}
}
public string TargetVideoCodecTag
{
get
{
var stream = VideoStream;
return !Options.Static
? null
: stream == null ? null : stream.CodecTag;
}
}
public bool? IsTargetAnamorphic
{
get
{
if (Options.Static)
{
return VideoStream == null ? null : VideoStream.IsAnamorphic;
}
return false;
}
}
public bool? IsTargetInterlaced
{
get
{
if (Options.Static)
{
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
if (DeInterlace)
{
return false;
}
return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced;
}
}
public bool? IsTargetAVC
{
get
{
if (Options.Static)
{
return VideoStream == null ? null : VideoStream.IsAVC;
}
return false;
}
}
public int? TargetVideoStreamCount
{
get
{
if (Options.Static)
{
return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Video, 1);
}
}
public int? TargetAudioStreamCount
{
get
{
if (Options.Static)
{
return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
}
return GetMediaStreamCount(MediaStreamType.Audio, 1);
}
}
private int? GetMediaStreamCount(MediaStreamType type, int limit)
{
var count = MediaSource.GetStreamCount(type);
if (count.HasValue)
{
count = Math.Min(count.Value, limit);
}
return count;
}
public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate) public override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
{ {
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null; var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;

View File

@ -105,7 +105,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
//state.OutputContainer = (container ?? string.Empty).TrimStart('.'); //state.OutputContainer = (container ?? string.Empty).TrimStart('.');
state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(state.Options, state.AudioStream); state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(state.Options, state.AudioStream);
state.OutputAudioSampleRate = request.AudioSampleRate;
state.OutputAudioCodec = state.Options.AudioCodec; state.OutputAudioCodec = state.Options.AudioCodec;

Some files were not shown because too many files have changed in this diff Show More