Merge pull request #2702 from MediaBrowser/beta

Beta
pull/1154/head
Luke 7 years ago committed by GitHub
commit e0c907cc60

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

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

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

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

@ -32,7 +32,7 @@
</PropertyGroup>
<ItemGroup>
<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 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>
@ -42,9 +42,8 @@
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.7.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.7\lib\net45\SimpleInjector.dll</HintPath>
<Private>True</Private>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />

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

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<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="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>

@ -70,7 +70,7 @@ namespace Emby.Dlna.Profiles
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
}
};

@ -31,42 +31,7 @@ namespace Emby.Dlna.Profiles
{
new DirectPlayProfile
{
Container = "mp3",
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",
Container = "aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a",
Type = DlnaProfileType.Audio
}
};

@ -30,7 +30,7 @@
<XmlRootAttributes />
<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="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>
<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" />

@ -35,12 +35,7 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<XmlRootAttributes />
<DirectPlayProfiles>
<DirectPlayProfile container="mp3" audioCodec="mp2,mp3" 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" />
<DirectPlayProfile container="aac,mp3,mpa,wav,wma,mp2,ogg,oga,webma,ape,opus,flac,m4a" type="Audio" />
</DirectPlayProfiles>
<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" />

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

@ -130,7 +130,7 @@ namespace Emby.Drawing.ImageMagick
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
quality = Math.Min(quality, 99);

@ -126,11 +126,11 @@ namespace Emby.Drawing.Skia
for (int row = 0; row < bitmap.Height; ++row)
{
if (IsAllWhiteRow(bitmap, row))
topmost = row;
topmost = row + 1;
else break;
}
int bottommost = 0;
int bottommost = bitmap.Height;
for (int row = bitmap.Height - 1; row >= 0; --row)
{
if (IsAllWhiteRow(bitmap, row))
@ -138,11 +138,11 @@ namespace Emby.Drawing.Skia
else break;
}
int leftmost = 0, rightmost = 0;
int leftmost = 0, rightmost = bitmap.Width;
for (int col = 0; col < bitmap.Width; ++col)
{
if (IsAllWhiteColumn(bitmap, col))
leftmost = col;
leftmost = col + 1;
else
break;
}
@ -162,13 +162,6 @@ namespace Emby.Drawing.Skia
using (var subset = image.Subset(newRect))
{
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 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);
@ -206,6 +199,8 @@ namespace Emby.Drawing.Skia
// decode
codec.GetPixels(bitmap.Info, bitmap.GetPixels());
origin = codec.Origin;
return bitmap;
}
}
@ -214,7 +209,7 @@ namespace Emby.Drawing.Skia
if (resultBitmap == null)
{
return Decode(path, true);
return Decode(path, true, out origin);
}
// If we have to resize these they often end up distorted
@ -222,27 +217,128 @@ namespace Emby.Drawing.Skia
{
using (resultBitmap)
{
return Decode(path, true);
return Decode(path, true, out origin);
}
}
origin = SKCodecOrigin.TopLeft;
return resultBitmap;
}
private SKBitmap GetBitmap(string path, bool cropWhitespace)
private SKBitmap GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, out SKCodecOrigin origin)
{
if (cropWhitespace)
{
using (var bitmap = Decode(path))
using (var bitmap = Decode(path, forceAnalyzeBitmap, out origin))
{
return CropWhiteSpace(bitmap);
}
}
return Decode(path);
return Decode(path, forceAnalyzeBitmap, out origin);
}
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, 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)
{
if (string.IsNullOrWhiteSpace(inputPath))
{
@ -260,7 +356,7 @@ namespace Emby.Drawing.Skia
var blur = options.Blur ?? 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)
{
@ -272,7 +368,7 @@ namespace Emby.Drawing.Skia
var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
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
return inputPath;

@ -217,14 +217,23 @@ namespace Emby.Drawing
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
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(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
_logger.Info("Returning original image {0}", originalImagePath);
@ -243,7 +252,6 @@ namespace Emby.Drawing
if (!_fileSystem.FileExists(cacheFilePath))
{
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(cacheFilePath));
var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath));
@ -252,13 +260,14 @@ namespace Emby.Drawing
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))
{
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(cacheFilePath));
CopyFile(tmpPath, cacheFilePath);
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[][] {
// TopLeft
//new int[] { 0, NONE},

@ -32,7 +32,7 @@ namespace Emby.Drawing
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();
}

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

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

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

@ -332,7 +332,13 @@ namespace Emby.Server.Core.IO
NotifyFilters.Attributes;
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.Changed += watcher_Changed;

@ -2,5 +2,5 @@
<packages>
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" 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>

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

@ -176,7 +176,9 @@ namespace Emby.Server.Implementations.Channels
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))
.ToArray();
@ -558,7 +560,10 @@ namespace Emby.Server.Implementations.Channels
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))
.ToArray();
@ -825,7 +830,10 @@ namespace Emby.Server.Implementations.Channels
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))
.ToArray();
@ -974,7 +982,10 @@ namespace Emby.Server.Implementations.Channels
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))
.ToArray();
@ -1378,12 +1389,6 @@ namespace Emby.Server.Implementations.Channels
item.SetImagePath(ImageType.Primary, info.ImageUrl);
}
if (item.SourceType != SourceType.Channel)
{
item.SourceType = SourceType.Channel;
forceUpdate = true;
}
if (isNew)
{
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);

@ -199,10 +199,11 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "HomePageUrl", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "VoteCount", "INT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DisplayMediaType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "DateCreated", "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", "TopParentId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsItemByName", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SourceType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames);
AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames);
@ -424,9 +424,8 @@ namespace Emby.Server.Implementations.Data
"OfficialRating",
"HomePageUrl",
"DisplayMediaType",
"SortName",
"ForcedSortName",
"RunTimeTicks",
"VoteCount",
"DateCreated",
"DateModified",
"guid",
@ -439,7 +438,6 @@ namespace Emby.Server.Implementations.Data
"LockedFields",
"Studios",
"Tags",
"SourceType",
"TrailerTypes",
"OriginalTitle",
"PrimaryVersionId",
@ -541,9 +539,9 @@ namespace Emby.Server.Implementations.Data
"Genres",
"InheritedParentalRatingValue",
"SortName",
"ForcedSortName",
"RunTimeTicks",
"HomePageUrl",
"VoteCount",
"DisplayMediaType",
"DateCreated",
"DateModified",
@ -563,7 +561,6 @@ namespace Emby.Server.Implementations.Data
"UnratedType",
"TopParentId",
"IsItemByName",
"SourceType",
"TrailerTypes",
"CriticRating",
"InheritedTags",
@ -815,10 +812,12 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@InheritedParentalRatingValue", item.InheritedParentalRatingValue);
saveItemStatement.TryBind("@SortName", item.SortName);
saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName);
saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks);
saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl);
saveItemStatement.TryBind("@VoteCount", item.VoteCount);
saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType);
saveItemStatement.TryBind("@DateCreated", item.DateCreated);
saveItemStatement.TryBind("@DateModified", item.DateModified);
@ -909,7 +908,6 @@ namespace Emby.Server.Implementations.Data
isByName = dualAccess == null || dualAccess.IsAccessedByName;
}
saveItemStatement.TryBind("@IsItemByName", isByName);
saveItemStatement.TryBind("@SourceType", item.SourceType.ToString());
var trailer = item as Trailer;
if (trailer != null && trailer.TrailerTypes.Count > 0)
@ -1624,7 +1622,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
item.SortName = reader.GetString(index);
item.ForcedSortName = reader.GetString(index);
}
index++;
}
@ -1635,15 +1633,6 @@ namespace Emby.Server.Implementations.Data
}
index++;
if (HasField(query, ItemFields.VoteCount))
{
if (!reader.IsDBNull(index))
{
item.VoteCount = reader.GetInt32(index);
}
index++;
}
if (HasField(query, ItemFields.DateCreated))
{
if (!reader.IsDBNull(index))
@ -1733,12 +1722,6 @@ namespace Emby.Server.Implementations.Data
index++;
}
if (!reader.IsDBNull(index))
{
item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(index), true);
}
index++;
if (hasTrailerTypes)
{
var trailer = item as Trailer;
@ -2283,7 +2266,7 @@ namespace Emby.Server.Implementations.Data
}
if (field == ItemFields.SortName)
{
return new[] { "SortName" };
return new[] { "ForcedSortName" };
}
if (field == ItemFields.Taglines)
{
@ -2306,7 +2289,6 @@ namespace Emby.Server.Implementations.Data
case ItemFields.HomePageUrl:
case ItemFields.Keywords:
case ItemFields.DisplayMediaType:
case ItemFields.VoteCount:
case ItemFields.CustomRating:
case ItemFields.ProductionLocations:
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)
{
var clauses = new List<string>();
@ -5017,14 +4971,6 @@ namespace Emby.Server.Implementations.Data
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;
}

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

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

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

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

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

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

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

@ -136,6 +136,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]";
httpOptions.RequestContent = requestBody;
double wideAspect = 1.77777778;
var primaryImageCategory = "Logo";
using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false))
{
StreamReader innerReader = new StreamReader(innerResponse.Content);
@ -167,13 +170,25 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
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 imagesWithoutText = allImages.Where(i => string.Equals(i.text, "no", StringComparison.OrdinalIgnoreCase)).ToList();
double desiredAspect = IsMovie(programEntry) ? 0.666666667 : wideAspect;
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.primaryImage = GetProgramImage(ApiUrl, imagesWithText, "Logo", true, 600) ??
GetProgramImage(ApiUrl, allImages, "Logo", true, 600);
programEntry.backdropImage = GetProgramImage(ApiUrl, imagesWithoutText, true, wideAspect);
//programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false);
//programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
// GetProgramImage(ApiUrl, data, "Banner-LO", false) ??
@ -220,9 +235,14 @@ namespace Emby.Server.Implementations.LiveTv.Listings
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)
{
//_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
DateTime startAt = GetDate(programInfo.airDateTime);
DateTime endAt = startAt.AddSeconds(programInfo.duration);
ProgramAudio audioType = ProgramAudio.Stereo;
@ -276,9 +296,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
IsRepeat = repeat,
IsSeries = showType.IndexOf("series", StringComparison.OrdinalIgnoreCase) != -1,
ImageUrl = details.primaryImage,
ThumbImageUrl = details.thumbImage,
IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase),
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
};
@ -378,49 +399,18 @@ namespace Emby.Server.Implementations.LiveTv.Listings
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;
var matches = images
.Where(i => string.Equals(i.category, category, StringComparison.OrdinalIgnoreCase))
.ToList();
if (matches.Count == 0)
{
if (!returnDefaultImage)
{
return null;
}
matches = images;
}
var matches = images;
var match = matches.FirstOrDefault(i =>
{
if (!string.IsNullOrWhiteSpace(i.width))
{
int value;
if (int.TryParse(i.width, out value))
{
return value <= desiredWidth;
}
}
matches = matches
.OrderBy(i => Math.Abs(desiredAspect - GetApsectRatio(i)))
.ThenByDescending(GetSizeOrder)
.ToList();
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();
}
}
var match = matches.FirstOrDefault();
if (match == null)
{
@ -444,6 +434,31 @@ namespace Emby.Server.Implementations.LiveTv.Listings
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(
ListingsProviderInfo info,
List<string> programIds,
@ -1188,6 +1203,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public bool hasImageArtwork { get; set; }
public string primaryImage { get; set; }
public string thumbImage { get; set; }
public string backdropImage { get; set; }
public string bannerImage { get; set; }
public string imageID { get; set; }
public string md5 { get; set; }

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

@ -679,8 +679,7 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo
{
Path = info.ImagePath,
Type = ImageType.Primary,
IsPlaceholder = true
Type = ImageType.Primary
}, 0);
}
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
@ -688,8 +687,46 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo
{
Path = info.ImageUrl,
Type = ImageType.Primary,
IsPlaceholder = true
Type = ImageType.Primary
}, 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);
}
}

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

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

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

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

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

@ -338,7 +338,7 @@ namespace Emby.Server.Implementations.Session
}
}
info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource);
info.Item = GetItemInfo(libraryItem, mediaSource);
info.Item.RunTimeTicks = runtimeTicks;
}
@ -813,7 +813,7 @@ namespace Emby.Server.Implementations.Session
mediaSource = await GetMediaSource(hasMediaSources, info.MediaSourceId, info.LiveStreamId).ConfigureAwait(false);
}
info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource);
info.Item = GetItemInfo(libraryItem, mediaSource);
}
else
{
@ -1637,165 +1637,65 @@ namespace Emby.Server.Implementations.Session
return dto;
}
private DtoOptions _itemInfoDtoOptions;
/// <summary>
/// Converts a BaseItem to a BaseItemInfo
/// </summary>
/// <param name="item">The item.</param>
/// <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)
private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
var info = new BaseItemInfo
{
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 (info.PrimaryImageTag != null)
{
info.PrimaryImageItemId = GetDtoId(item);
}
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;
info.SeriesName = recording.Name;
if (string.IsNullOrWhiteSpace(info.Name))
{
info.Name = recording.Name;
}
}
}
var audio = item as Audio;
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;
}
}
}
var dtoOptions = _itemInfoDtoOptions;
if (backropItem == null)
if (_itemInfoDtoOptions == null)
{
if (episode != null)
dtoOptions = new DtoOptions
{
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();
}
AddProgramRecordingInfo = false
};
dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
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 info = _dtoService.GetBaseItemDto(item, dtoOptions);
if (mediaSource != null)
{
@ -1837,7 +1737,7 @@ namespace Emby.Server.Implementations.Session
//ReportNowViewingItem(sessionId, info);
}
public void ReportNowViewingItem(string sessionId, BaseItemInfo item)
public void ReportNowViewingItem(string sessionId, BaseItemDto item)
{
//var session = GetSession(sessionId);

@ -206,15 +206,16 @@ namespace MediaBrowser.Api
var newLockData = request.LockData ?? false;
var isLockedChanged = item.IsLocked != newLockData;
UpdateItem(request, item);
await item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
// Do this first so that metadata savers can pull the updates from the database.
if (request.People != null)
{
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)
{
var folder = (Folder)item;
@ -243,7 +244,6 @@ namespace MediaBrowser.Api
item.DisplayMediaType = request.DisplayMediaType;
item.CommunityRating = request.CommunityRating;
item.VoteCount = request.VoteCount;
item.HomePageUrl = request.HomePageUrl;
item.IndexNumber = request.IndexNumber;
item.ParentIndexNumber = request.ParentIndexNumber;

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

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

@ -106,6 +106,13 @@ namespace MediaBrowser.Api.Playback
}
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);
@ -137,7 +144,7 @@ namespace MediaBrowser.Api.Playback
}
}
return ToOptimizedResult(result);
return result;
}
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);
}
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;
}
@ -322,6 +357,19 @@ namespace MediaBrowser.Api.Playback
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.IsRemote && forceDirectPlayRemoteMediaSource)

@ -250,248 +250,6 @@ namespace MediaBrowser.Api.Playback
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 override void ReportTranscodingProgress(TimeSpan? transcodingPosition, float? framerate, double? percentComplete, long? bytesTranscoded, int? bitRate)
{

@ -98,7 +98,7 @@ namespace MediaBrowser.Api.Session
[Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")]
[Authenticated]
public class SendPlaystateCommand : IReturnVoid
public class SendPlaystateCommand : PlaystateRequest, IReturnVoid
{
/// <summary>
/// Gets or sets the id.
@ -106,19 +106,6 @@ namespace MediaBrowser.Api.Session
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
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")]
@ -414,13 +401,7 @@ namespace MediaBrowser.Api.Session
public void Post(SendPlaystateCommand request)
{
var command = new PlaystateRequest
{
Command = request.Command,
SeekPositionTicks = request.SeekPositionTicks
};
var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Result.Id, request.Id, command, CancellationToken.None);
var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Result.Id, request.Id, request, CancellationToken.None);
Task.WaitAll(task);
}

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

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

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

@ -58,7 +58,7 @@ namespace MediaBrowser.Common.Updates
}
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)
{
@ -81,7 +81,7 @@ namespace MediaBrowser.Common.Updates
{
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)
{

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

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

@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Drawing
/// <summary>
/// Encodes the image.
/// </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>
/// Creates the image collage.

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

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

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

@ -54,7 +54,6 @@ namespace MediaBrowser.Controller.Entities
ImageInfos = new List<ItemImageInfo>();
InheritedTags = new List<string>();
ProductionLocations = new List<string>();
SourceType = SourceType.Library;
}
public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
@ -187,15 +186,10 @@ namespace MediaBrowser.Controller.Entities
}
set
{
var isSortNameDefault = IsSortNameDefault(SortName);
_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; }
[IgnoreDataMember]
public virtual SourceType SourceType { get; set; }
public virtual SourceType SourceType
{
get
{
if (!string.IsNullOrWhiteSpace(ChannelId))
{
return SourceType.Channel;
}
return SourceType.Library;
}
}
/// <summary>
/// Returns the folder containing the item.
@ -586,6 +591,7 @@ namespace MediaBrowser.Controller.Entities
}
}
private string _forcedSortName;
/// <summary>
/// Gets or sets the name of the forced sort.
/// </summary>
@ -593,42 +599,8 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public string ForcedSortName
{
get
{
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;
}
}
}
get { return _forcedSortName; }
set { _forcedSortName = value; _sortName = null; }
}
private string _sortName;
@ -643,7 +615,15 @@ namespace MediaBrowser.Controller.Entities
{
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;
}
@ -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()
{
var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath;
@ -699,22 +654,14 @@ namespace MediaBrowser.Controller.Entities
return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
}
protected string CreateSortName()
{
if (string.IsNullOrWhiteSpace(Name))
{
return null;
}
return CreateSortNameInternal();
}
/// <summary>
/// Creates the name of the sort.
/// </summary>
/// <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)
{
return Name.TrimStart();
@ -951,13 +898,6 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
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>
/// Gets or sets the run time ticks.
/// </summary>
@ -1367,6 +1307,7 @@ namespace MediaBrowser.Controller.Entities
public void AfterMetadataRefresh()
{
_sortName = null;
}
/// <summary>
@ -2253,6 +2194,8 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public virtual bool BeforeMetadataRefresh()
{
_sortName = null;
var hasChanges = false;
if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path))

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

@ -185,7 +185,7 @@ namespace MediaBrowser.Controller.Entities
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));
}
@ -243,7 +243,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The actual children.</value>
[IgnoreDataMember]
protected virtual IEnumerable<BaseItem> ActualChildren
public virtual IEnumerable<BaseItem> Children
{
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>
/// thread-safe access to all recursive children of this folder - without regard to user
/// </summary>
@ -301,7 +291,7 @@ namespace MediaBrowser.Controller.Entities
/// Loads our children. Validation will occur externally.
/// We want this sychronous.
/// </summary>
protected virtual IEnumerable<BaseItem> LoadChildren()
protected virtual List<BaseItem> LoadChildren()
{
//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
@ -330,7 +320,9 @@ namespace MediaBrowser.Controller.Entities
{
var dictionary = new Dictionary<Guid, BaseItem>();
foreach (var child in ActualChildren)
var childrenList = Children.ToList();
foreach (var child in childrenList)
{
var id = child.Id;
if (dictionary.ContainsKey(id))
@ -466,7 +458,7 @@ namespace MediaBrowser.Controller.Entities
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);
@ -494,7 +486,7 @@ namespace MediaBrowser.Controller.Entities
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 numComplete = 0;
@ -668,7 +660,7 @@ namespace MediaBrowser.Controller.Entities
/// Get our children from the repo - stubbed for now
/// </summary>
/// <returns>IEnumerable{BaseItem}.</returns>
protected IEnumerable<BaseItem> GetCachedChildren()
protected List<BaseItem> GetCachedChildren()
{
return ItemRepository.GetItemList(new InternalItemsQuery
{

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

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

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

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

@ -1,19 +1,19 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities.TV
{
/// <summary>
/// Class Episode
/// </summary>
public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities.TV
{
/// <summary>
/// Class Episode
/// </summary>
public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
{
public Episode()
{
@ -26,35 +26,35 @@ namespace MediaBrowser.Controller.Entities.TV
public List<Guid> RemoteTrailerIds { get; set; }
public List<MediaUrl> RemoteTrailers { get; set; }
/// <summary>
/// Gets the season in which it aired.
/// </summary>
/// <value>The aired season.</value>
public int? AirsBeforeSeasonNumber { get; set; }
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
/// <summary>
/// Gets or sets the DVD season number.
/// </summary>
/// <value>The DVD season number.</value>
public int? DvdSeasonNumber { get; set; }
/// <summary>
/// Gets or sets the DVD episode number.
/// </summary>
/// <value>The DVD episode number.</value>
public float? DvdEpisodeNumber { get; set; }
/// <summary>
/// Gets or sets the absolute episode number.
/// </summary>
/// <value>The absolute episode number.</value>
public int? AbsoluteEpisodeNumber { get; set; }
/// <summary>
/// This is the ending episode number for double episodes.
/// </summary>
/// <value>The index number.</value>
/// <summary>
/// Gets the season in which it aired.
/// </summary>
/// <value>The aired season.</value>
public int? AirsBeforeSeasonNumber { get; set; }
public int? AirsAfterSeasonNumber { get; set; }
public int? AirsBeforeEpisodeNumber { get; set; }
/// <summary>
/// Gets or sets the DVD season number.
/// </summary>
/// <value>The DVD season number.</value>
public int? DvdSeasonNumber { get; set; }
/// <summary>
/// Gets or sets the DVD episode number.
/// </summary>
/// <value>The DVD episode number.</value>
public float? DvdEpisodeNumber { get; set; }
/// <summary>
/// Gets or sets the absolute episode number.
/// </summary>
/// <value>The absolute episode number.</value>
public int? AbsoluteEpisodeNumber { get; set; }
/// <summary>
/// This is the ending episode number for double episodes.
/// </summary>
/// <value>The index number.</value>
public int? IndexNumberEnd { get; set; }
public string FindSeriesSortName()
@ -62,56 +62,56 @@ namespace MediaBrowser.Controller.Entities.TV
var series = Series;
return series == null ? SeriesName : series.SortName;
}
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{
get
{
return IsStacked || MediaSourceCount > 1;
}
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{
get
{
return IsStacked || MediaSourceCount > 1;
}
}
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember]
public int? AiredSeasonNumber
{
get
{
return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
}
}
[IgnoreDataMember]
public override Folder LatestItemsIndexContainer
{
get
{
return Series;
}
}
[IgnoreDataMember]
public override Guid? DisplayParentId
{
get
{
return SeasonId;
}
}
[IgnoreDataMember]
protected override bool EnableDefaultVideoUserDataKeys
{
get
{
return false;
}
}
[IgnoreDataMember]
public int? AiredSeasonNumber
{
get
{
return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
}
}
[IgnoreDataMember]
public override Folder LatestItemsIndexContainer
{
get
{
return Series;
}
}
[IgnoreDataMember]
public override Guid? DisplayParentId
{
get
{
return SeasonId;
}
}
[IgnoreDataMember]
protected override bool EnableDefaultVideoUserDataKeys
{
get
{
return false;
}
}
public override double? GetDefaultPrimaryImageAspectRatio()
@ -120,64 +120,64 @@ namespace MediaBrowser.Controller.Entities.TV
value /= 9;
return value;
}
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();
var series = Series;
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
{
var seriesUserDataKeys = series.GetUserDataKeys();
var take = seriesUserDataKeys.Count;
if (seriesUserDataKeys.Count > 1)
{
take--;
}
list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
}
return list;
}
/// <summary>
/// This Episode's Series Instance
/// </summary>
/// <value>The series.</value>
[IgnoreDataMember]
public Series Series
{
get
{
}
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();
var series = Series;
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
{
var seriesUserDataKeys = series.GetUserDataKeys();
var take = seriesUserDataKeys.Count;
if (seriesUserDataKeys.Count > 1)
{
take--;
}
list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
}
return list;
}
/// <summary>
/// This Episode's Series Instance
/// </summary>
/// <value>The series.</value>
[IgnoreDataMember]
public Series Series
{
get
{
var seriesId = SeriesId ?? FindSeriesId();
return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
}
}
[IgnoreDataMember]
public Season Season
{
get
{
return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
}
}
[IgnoreDataMember]
public Season Season
{
get
{
var seasonId = SeasonId ?? FindSeasonId();
return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null;
}
}
[IgnoreDataMember]
public bool IsInSeasonFolder
{
get
{
return FindParent<Season>() != null;
}
return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null;
}
}
[IgnoreDataMember]
public bool IsInSeasonFolder
{
get
{
return FindParent<Season>() != null;
}
}
[IgnoreDataMember]
public string SeriesPresentationUniqueKey { get; set; }
[IgnoreDataMember]
[IgnoreDataMember]
public string SeriesName { get; set; }
[IgnoreDataMember]
@ -187,17 +187,17 @@ namespace MediaBrowser.Controller.Entities.TV
{
var series = Series;
return series == null ? null : series.PresentationUniqueKey;
}
public string FindSeasonName()
}
public string FindSeasonName()
{
var season = Season;
if (season == null)
{
if (ParentIndexNumber.HasValue)
{
return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
var season = Season;
if (season == null)
{
if (ParentIndexNumber.HasValue)
{
return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
}
return "Season Unknown";
}
@ -231,92 +231,92 @@ namespace MediaBrowser.Controller.Entities.TV
}
return season == null ? (Guid?)null : season.Id;
}
/// <summary>
/// Creates the name of the sort.
/// </summary>
/// <returns>System.String.</returns>
protected override string CreateSortNameInternal()
{
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "")
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
}
/// <summary>
/// Determines whether [contains episode number] [the specified number].
/// </summary>
/// <param name="number">The number.</param>
/// <returns><c>true</c> if [contains episode number] [the specified number]; otherwise, <c>false</c>.</returns>
public bool ContainsEpisodeNumber(int number)
{
if (IndexNumber.HasValue)
{
if (IndexNumberEnd.HasValue)
{
return number >= IndexNumber.Value && number <= IndexNumberEnd.Value;
}
return IndexNumber.Value == number;
}
return false;
}
[IgnoreDataMember]
public override bool SupportsRemoteImageDownloading
{
get
{
if (IsMissingEpisode)
{
return false;
}
return true;
}
}
[IgnoreDataMember]
public bool IsMissingEpisode
{
get
{
return LocationType == LocationType.Virtual && !IsUnaired;
}
}
[IgnoreDataMember]
public bool IsVirtualUnaired
{
get { return LocationType == LocationType.Virtual && IsUnaired; }
}
[IgnoreDataMember]
}
/// <summary>
/// Creates the name of the sort.
/// </summary>
/// <returns>System.String.</returns>
protected override string CreateSortName()
{
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "")
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
}
/// <summary>
/// Determines whether [contains episode number] [the specified number].
/// </summary>
/// <param name="number">The number.</param>
/// <returns><c>true</c> if [contains episode number] [the specified number]; otherwise, <c>false</c>.</returns>
public bool ContainsEpisodeNumber(int number)
{
if (IndexNumber.HasValue)
{
if (IndexNumberEnd.HasValue)
{
return number >= IndexNumber.Value && number <= IndexNumberEnd.Value;
}
return IndexNumber.Value == number;
}
return false;
}
[IgnoreDataMember]
public override bool SupportsRemoteImageDownloading
{
get
{
if (IsMissingEpisode)
{
return false;
}
return true;
}
}
[IgnoreDataMember]
public bool IsMissingEpisode
{
get
{
return LocationType == LocationType.Virtual && !IsUnaired;
}
}
[IgnoreDataMember]
public bool IsVirtualUnaired
{
get { return LocationType == LocationType.Virtual && IsUnaired; }
}
[IgnoreDataMember]
public Guid? SeasonId { get; set; }
[IgnoreDataMember]
public Guid? SeriesId { get; set; }
public Guid? FindSeriesId()
{
var series = FindParent<Series>();
var series = FindParent<Series>();
return series == null ? (Guid?)null : series.Id;
}
public override IEnumerable<Guid> GetAncestorIds()
{
var list = base.GetAncestorIds().ToList();
var seasonId = SeasonId;
if (seasonId.HasValue && !list.Contains(seasonId.Value))
{
list.Add(seasonId.Value);
}
return list;
}
}
public override IEnumerable<Guid> GetAncestorIds()
{
var list = base.GetAncestorIds().ToList();
var seasonId = SeasonId;
if (seasonId.HasValue && !list.Contains(seasonId.Value))
{
list.Add(seasonId.Value);
}
return list;
}
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
{
return new[] {
@ -327,60 +327,60 @@ namespace MediaBrowser.Controller.Entities.TV
}
}.Concat(GetLocalMetadataFilesToDelete());
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.Series;
}
public EpisodeInfo GetLookupInfo()
{
var id = GetItemLookupInfo<EpisodeInfo>();
var series = Series;
if (series != null)
{
id.SeriesProviderIds = series.ProviderIds;
}
id.IsMissingEpisode = IsMissingEpisode;
id.IndexNumberEnd = IndexNumberEnd;
id.IsVirtualUnaired = IsVirtualUnaired;
return id;
}
public override bool BeforeMetadataRefresh()
{
var hasChanges = base.BeforeMetadataRefresh();
try
{
if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
{
hasChanges = true;
}
}
catch (Exception ex)
{
Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
}
if (!ParentIndexNumber.HasValue)
{
var season = Season;
if (season != null)
{
if (season.ParentIndexNumber.HasValue)
{
ParentIndexNumber = season.ParentIndexNumber;
hasChanges = true;
}
}
}
return hasChanges;
}
}
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.Series;
}
public EpisodeInfo GetLookupInfo()
{
var id = GetItemLookupInfo<EpisodeInfo>();
var series = Series;
if (series != null)
{
id.SeriesProviderIds = series.ProviderIds;
}
id.IsMissingEpisode = IsMissingEpisode;
id.IndexNumberEnd = IndexNumberEnd;
id.IsVirtualUnaired = IsVirtualUnaired;
return id;
}
public override bool BeforeMetadataRefresh()
{
var hasChanges = base.BeforeMetadataRefresh();
try
{
if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
{
hasChanges = true;
}
}
catch (Exception ex)
{
Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
}
if (!ParentIndexNumber.HasValue)
{
var season = Season;
if (season != null)
{
if (season.ParentIndexNumber.HasValue)
{
ParentIndexNumber = season.ParentIndexNumber;
hasChanges = true;
}
}
}
return hasChanges;
}
}
}

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

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

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

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

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

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

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

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

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

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

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

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

@ -1604,7 +1604,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// 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)
{
@ -1806,6 +1806,20 @@ namespace MediaBrowser.Controller.MediaEncoding
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

@ -8,6 +8,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Drawing;
namespace MediaBrowser.Controller.MediaEncoding
{
@ -134,7 +135,6 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? OutputAudioBitrate;
public int? OutputAudioChannels;
public int? OutputAudioSampleRate;
public bool DeInterlace { get; set; }
public bool IsVideoRequest { get; set; }
public TranscodingJobType TranscodingType { get; set; }
@ -173,6 +173,97 @@ namespace MediaBrowser.Controller.MediaEncoding
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>
/// Predicts the audio sample rate that will be in the output stream
/// </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()
{
if (IsoMount != null)

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

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

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

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

@ -40,27 +40,12 @@ namespace MediaBrowser.LocalMetadata.Images
{
var parentPath = _fileSystem.GetDirectoryName(item.Path);
var parentPathFiles = directoryService.GetFileSystemEntries(parentPath)
var parentPathFiles = directoryService.GetFiles(parentPath)
.ToList();
var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(item.Path);
var files = 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>();
return GetFilesFromParentFolder(nameWithoutExtension, parentPathFiles);
}
private List<LocalImageInfo> GetFilesFromParentFolder(string filenameWithoutExtension, IEnumerable<FileSystemMetadata> parentPathFiles)

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

@ -598,20 +598,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
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":
var tmdbCollection = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(tmdbCollection))

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

@ -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;
}
}
}
}

@ -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)
{
}
}
}

@ -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)
{
}
}
}

@ -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)
{
}
}
}

@ -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);
}
}
}

@ -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;
}
}
}

@ -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);
}
}
}

@ -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;
}
}
}
}

@ -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);
}
}
}

@ -109,7 +109,6 @@ namespace MediaBrowser.LocalMetadata.Savers
"TvDbId",
"Type",
"TVRageId",
"VoteCount",
"Website",
"Zap2ItId",
"CollectionItems",
@ -407,10 +406,6 @@ namespace MediaBrowser.LocalMetadata.Savers
{
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))
{

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

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

@ -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)
{
var ticks = transcodingPosition.HasValue ? transcodingPosition.Value.Ticks : (long?)null;

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

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

Loading…
Cancel
Save