diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs
index 9c9e14ec6b..87b97863bd 100644
--- a/Emby.Common.Implementations/BaseApplicationHost.cs
+++ b/Emby.Common.Implementations/BaseApplicationHost.cs
@@ -161,12 +161,6 @@ namespace Emby.Common.Implementations
/// The name.
public abstract string Name { get; }
- ///
- /// Gets a value indicating whether this instance is running as service.
- ///
- /// true if this instance is running as service; otherwise, false.
- public abstract bool IsRunningAsService { get; }
-
protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
protected IEnvironmentInfo EnvironmentInfo { get; private set; }
diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
index 78070a5d91..3fe20f6596 100644
--- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs
+++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
@@ -20,10 +20,13 @@ namespace Emby.Common.Implementations.IO
private readonly List _shortcutHandlers = new List();
private bool EnableFileSystemRequestConcat = true;
- public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars, bool enableFileSystemRequestConcat)
+ private string _tempPath;
+
+ public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars, bool enableFileSystemRequestConcat, string tempPath)
{
Logger = logger;
_supportsAsyncFileStreams = supportsAsyncFileStreams;
+ _tempPath = tempPath;
EnableFileSystemRequestConcat = enableFileSystemRequestConcat;
SetInvalidFileNameChars(enableManagedInvalidFileNameChars);
}
@@ -487,18 +490,37 @@ namespace Emby.Common.Implementations.IO
throw new ArgumentNullException("file2");
}
- var temp1 = Path.GetTempFileName();
+ var temp1 = Path.Combine(_tempPath, Guid.NewGuid().ToString("N"));
// Copying over will fail against hidden files
SetHidden(file1, false);
SetHidden(file2, false);
+ Directory.CreateDirectory(_tempPath);
CopyFile(file1, temp1, true);
CopyFile(file2, file1, true);
CopyFile(temp1, file2, true);
}
+ public bool AreEqual(string path1, string path2)
+ {
+ if (path1 == null && path2 == null)
+ {
+ return true;
+ }
+
+ if (path1 == null || path2 == null)
+ {
+ return false;
+ }
+
+ path1 = path1.TrimEnd(DirectorySeparatorChar);
+ path2 = path2.TrimEnd(DirectorySeparatorChar);
+
+ return string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase);
+ }
+
public bool ContainsSubPath(string parentPath, string path)
{
if (string.IsNullOrEmpty(parentPath))
@@ -656,21 +678,7 @@ namespace Emby.Common.Implementations.IO
private IEnumerable ToMetadata(string parentPath, IEnumerable infos)
{
- return infos.Select(i =>
- {
- try
- {
- return GetFileSystemMetadata(i);
- }
- catch (PathTooLongException)
- {
- // Can't log using the FullName because it will throw the PathTooLongExceptiona again
- //Logger.Warn("Path too long: {0}", i.FullName);
- Logger.Warn("File or directory path too long. Parent folder: {0}", parentPath);
- return null;
- }
-
- }).Where(i => i != null);
+ return infos.Select(GetFileSystemMetadata);
}
public string[] ReadAllLines(string path)
diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs
index 5718cbd09f..2251a8f58c 100644
--- a/Emby.Dlna/ContentDirectory/ControlHandler.cs
+++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs
@@ -260,7 +260,7 @@ namespace Emby.Dlna.ContentDirectory
{
totalCount = 1;
- if (item.IsFolder || serverItem.StubType.HasValue)
+ if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue)
{
var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount).ConfigureAwait(false));
@@ -285,7 +285,7 @@ namespace Emby.Dlna.ContentDirectory
var childItem = i.Item;
var displayStubType = i.StubType;
- if (childItem.IsFolder || displayStubType.HasValue)
+ if (childItem.IsDisplayedAsFolder || displayStubType.HasValue)
{
var childCount = (await GetUserItems(childItem, displayStubType, user, sortCriteria, null, 0).ConfigureAwait(false))
.TotalRecordCount;
@@ -381,7 +381,7 @@ namespace Emby.Dlna.ContentDirectory
foreach (var i in childrenResult.Items)
{
- if (i.IsFolder)
+ if (i.IsDisplayedAsFolder)
{
var childCount = (await GetChildrenSorted(i, user, searchCriteria, sortCriteria, null, 0).ConfigureAwait(false))
.TotalRecordCount;
diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs
index 3e47362f65..ca4c3b9122 100644
--- a/Emby.Dlna/Didl/DidlBuilder.cs
+++ b/Emby.Dlna/Didl/DidlBuilder.cs
@@ -176,6 +176,18 @@ namespace Emby.Dlna.Didl
return new NullLogger();
}
+ private string GetMimeType(string input)
+ {
+ var mime = MimeTypes.GetMimeType(input);
+
+ if (string.Equals(mime, "video/mp2t", StringComparison.OrdinalIgnoreCase))
+ {
+ mime = "video/mpeg";
+ }
+
+ return mime;
+ }
+
private void AddVideoResource(DlnaOptions options, XmlWriter writer, IHasMediaSources video, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
if (streamInfo == null)
@@ -360,7 +372,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
- ? MimeTypes.GetMimeType(filename)
+ ? GetMimeType(filename)
: mediaProfile.MimeType;
writer.WriteAttributeString("protocolInfo", String.Format(
@@ -481,7 +493,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
- ? MimeTypes.GetMimeType(filename)
+ ? GetMimeType(filename)
: mediaProfile.MimeType;
var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container,
@@ -674,7 +686,7 @@ namespace Emby.Dlna.Didl
writer.WriteStartElement("upnp", "class", NS_UPNP);
- if (item.IsFolder || stubType.HasValue)
+ if (item.IsDisplayedAsFolder || stubType.HasValue)
{
string classType = null;
@@ -760,7 +772,7 @@ namespace Emby.Dlna.Didl
// Seeing some LG models locking up due content with large lists of people
// The actual issue might just be due to processing a more metadata than it can handle
- var limit = 10;
+ var limit = 6;
foreach (var actor in people)
{
@@ -1007,7 +1019,7 @@ namespace Emby.Dlna.Didl
writer.WriteAttributeString("protocolInfo", String.Format(
"http-get:*:{0}:{1}",
- MimeTypes.GetMimeType("file." + format),
+ GetMimeType("file." + format),
contentFeatures
));
diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs
index 4daaa50464..020038422a 100644
--- a/Emby.Dlna/DlnaManager.cs
+++ b/Emby.Dlna/DlnaManager.cs
@@ -595,6 +595,7 @@ namespace Emby.Dlna
new LinksysDMA2100Profile(),
new LgTvProfile(),
new Foobar2000Profile(),
+ new SharpSmartTvProfile(),
new MediaMonkeyProfile(),
//new Windows81Profile(),
//new WindowsMediaCenterProfile(),
diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj
index c83aaecab2..a8c05a5272 100644
--- a/Emby.Dlna/Emby.Dlna.csproj
+++ b/Emby.Dlna/Emby.Dlna.csproj
@@ -92,6 +92,7 @@
+
@@ -148,7 +149,9 @@
RSSDP
-
+
+
+
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs
index f6be479898..e222980102 100644
--- a/Emby.Dlna/PlayTo/Device.cs
+++ b/Emby.Dlna/PlayTo/Device.cs
@@ -112,7 +112,7 @@ namespace Emby.Dlna.PlayTo
private int GetInactiveTimerIntervalMs()
{
- return 20000;
+ return 30000;
}
public void Start()
@@ -440,6 +440,11 @@ namespace Emby.Dlna.PlayTo
{
var transportState = await GetTransportInfo().ConfigureAwait(false);
+ if (_disposed)
+ {
+ return;
+ }
+
DateLastActivity = DateTime.UtcNow;
if (transportState.HasValue)
@@ -530,6 +535,11 @@ namespace Emby.Dlna.PlayTo
private async Task GetVolume()
{
+ if (_disposed)
+ {
+ return;
+ }
+
var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume");
if (command == null)
return;
@@ -563,6 +573,11 @@ namespace Emby.Dlna.PlayTo
private async Task GetMute()
{
+ if (_disposed)
+ {
+ return;
+ }
+
var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMute");
if (command == null)
return;
@@ -793,6 +808,11 @@ namespace Emby.Dlna.PlayTo
private async Task GetAVProtocolAsync()
{
+ if (_disposed)
+ {
+ return;
+ }
+
var avService = GetAvTransportService();
if (avService == null)
return;
@@ -807,6 +827,11 @@ namespace Emby.Dlna.PlayTo
private async Task GetRenderingProtocolAsync()
{
+ if (_disposed)
+ {
+ return;
+ }
+
var avService = GetServiceRenderingControl();
if (avService == null)
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 4ad62216e4..3c07e95dbb 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -149,6 +149,11 @@ namespace Emby.Dlna.PlayTo
async void _device_MediaChanged(object sender, MediaChangedEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
var streamInfo = await StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
@@ -176,6 +181,11 @@ namespace Emby.Dlna.PlayTo
async void _device_PlaybackStopped(object sender, PlaybackStoppedEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
var streamInfo = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager)
@@ -239,6 +249,11 @@ namespace Emby.Dlna.PlayTo
async void _device_PlaybackStart(object sender, PlaybackStartEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
@@ -258,6 +273,11 @@ namespace Emby.Dlna.PlayTo
async void _device_PlaybackProgress(object sender, PlaybackProgressEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs
index a93f7da14e..962a982c18 100644
--- a/Emby.Dlna/PlayTo/PlayToManager.cs
+++ b/Emby.Dlna/PlayTo/PlayToManager.cs
@@ -43,6 +43,7 @@ namespace Emby.Dlna.PlayTo
private readonly List _nonRendererUrls = new List();
private DateTime _lastRendererClear;
+ private bool _disposed;
public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory)
{
@@ -70,6 +71,11 @@ namespace Emby.Dlna.PlayTo
async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
var info = e.Argument;
string usn;
@@ -121,6 +127,11 @@ namespace Emby.Dlna.PlayTo
}
}
+ if (_disposed)
+ {
+ return;
+ }
+
_logger.Debug("Logging session activity from location {0}", location);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
.ConfigureAwait(false);
@@ -129,6 +140,11 @@ namespace Emby.Dlna.PlayTo
if (controller == null)
{
+ if (_disposed)
+ {
+ return;
+ }
+
string serverAddress;
if (info.LocalIpAddress == null)
{
@@ -187,6 +203,11 @@ namespace Emby.Dlna.PlayTo
catch (Exception ex)
{
_logger.ErrorException("Error creating PlayTo device.", ex);
+
+ lock (_nonRendererUrls)
+ {
+ _nonRendererUrls.Add(location);
+ }
}
}
@@ -202,6 +223,7 @@ namespace Emby.Dlna.PlayTo
public void Dispose()
{
+ _disposed = true;
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
}
}
diff --git a/Emby.Dlna/Profiles/DefaultProfile.cs b/Emby.Dlna/Profiles/DefaultProfile.cs
index ff30f2e158..c670f268ee 100644
--- a/Emby.Dlna/Profiles/DefaultProfile.cs
+++ b/Emby.Dlna/Profiles/DefaultProfile.cs
@@ -64,7 +64,7 @@ namespace Emby.Dlna.Profiles
{
new DirectPlayProfile
{
- Container = "m4v,ts,mkv,avi,mpg,mpeg,mp4",
+ Container = "m4v,ts,mpegts,mkv,avi,mpg,mpeg,mp4,mov",
VideoCodec = "h264",
AudioCodec = "aac,mp3,ac3",
Type = DlnaProfileType.Video
@@ -72,7 +72,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp3,wma,aac,wav",
+ Container = "mp3,wma,aac,wav,flac",
Type = DlnaProfileType.Audio
}
};
diff --git a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
index d494a7bfca..89e0697c16 100644
--- a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
+++ b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
@@ -23,7 +23,7 @@ namespace Emby.Dlna.Profiles
{
Match = HeaderMatchType.Substring,
Name = "User-Agent",
- Value ="XiP"
+ Value ="Zip_"
}
}
};
@@ -63,22 +63,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp3",
- AudioCodec = "mp3",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "alac",
- AudioCodec = "alac",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "flac",
- AudioCodec = "flac",
+ Container = "mp3,alac,flac",
Type = DlnaProfileType.Audio
},
diff --git a/Emby.Dlna/Profiles/LgTvProfile.cs b/Emby.Dlna/Profiles/LgTvProfile.cs
index f7cf7b9a19..71f684ec48 100644
--- a/Emby.Dlna/Profiles/LgTvProfile.cs
+++ b/Emby.Dlna/Profiles/LgTvProfile.cs
@@ -67,7 +67,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "aac,ac3,mp3,dca,dts",
Type = DlnaProfileType.Video
@@ -203,7 +203,15 @@ namespace Emby.Dlna.Profiles
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
index 4a4ecdc589..2b31ab55f0 100644
--- a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
+++ b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
@@ -26,12 +26,20 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "avi,mp4,mkv,ts",
+ Container = "avi,mp4,mkv,ts,m4v",
Type = DlnaProfileType.Video
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
index f3d7f59512..63c7e3a8e0 100644
--- a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
+++ b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264",
AudioCodec = "aac,ac3,mp3,pcm",
Type = DlnaProfileType.Video
@@ -208,6 +208,12 @@ namespace Emby.Dlna.Profiles
Container = "ts",
OrgPn = "MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO",
MimeType = "video/vnd.dlna.mpeg-tts"
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/PopcornHourProfile.cs b/Emby.Dlna/Profiles/PopcornHourProfile.cs
index 0095c80a28..d13b5c6ade 100644
--- a/Emby.Dlna/Profiles/PopcornHourProfile.cs
+++ b/Emby.Dlna/Profiles/PopcornHourProfile.cs
@@ -38,7 +38,7 @@ namespace Emby.Dlna.Profiles
{
new DirectPlayProfile
{
- Container = "mp4,mov",
+ Container = "mp4,mov,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "aac"
@@ -201,7 +201,15 @@ namespace Emby.Dlna.Profiles
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
index 5acdde327b..c582cb52e3 100644
--- a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -43,7 +43,7 @@ namespace Emby.Dlna.Profiles
AudioCodec = "ac3",
VideoCodec = "h264",
Type = DlnaProfileType.Video,
- EstimateContentLength = true
+ EstimateContentLength = false
},
new TranscodingProfile
{
@@ -77,7 +77,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "mp3,aac",
Type = DlnaProfileType.Video
@@ -335,6 +335,12 @@ namespace Emby.Dlna.Profiles
Container = "flac",
MimeType = "audio/x-flac",
Type = DlnaProfileType.Audio
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SharpSmartTvProfile.cs b/Emby.Dlna/Profiles/SharpSmartTvProfile.cs
new file mode 100644
index 0000000000..b49ad01977
--- /dev/null
+++ b/Emby.Dlna/Profiles/SharpSmartTvProfile.cs
@@ -0,0 +1,120 @@
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace Emby.Dlna.Profiles
+{
+ [XmlRoot("Profile")]
+ public class SharpSmartTvProfile : DefaultProfile
+ {
+ public SharpSmartTvProfile()
+ {
+ Name = "Sharp Smart TV";
+
+ RequiresPlainFolders = true;
+ RequiresPlainVideoItems = true;
+
+ Identification = new DeviceIdentification
+ {
+ Manufacturer = "Sharp",
+
+ Headers = new[]
+ {
+ new HttpHeaderInfo
+ {
+ Name = "User-Agent",
+ Value = "Sharp",
+ Match = HeaderMatchType.Substring
+ }
+ }
+ };
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ AudioCodec = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video,
+ AudioCodec = "ac3,aac,mp3,dts,dca",
+ VideoCodec = "h264",
+ EnableMpegtsM2TsMode = true
+ },
+
+ new TranscodingProfile
+ {
+ Container = "jpeg",
+ Type = DlnaProfileType.Photo
+ }
+ };
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Container = "m4v,mkv,avi,mov,mp4",
+ VideoCodec = "h264,mpeg4",
+ AudioCodec = "aac,mp3,ac3,dts,dca",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "asf,wmv",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "mpg,mpeg",
+ VideoCodec = "mpeg2video",
+ AudioCodec = "mp3,aac",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "flv",
+ VideoCodec = "h264",
+ AudioCodec = "mp3,aac",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "mp3,wav",
+ Type = DlnaProfileType.Audio
+ }
+ };
+
+ SubtitleProfiles = new[]
+ {
+ new SubtitleProfile
+ {
+ Format = "srt",
+ Method = SubtitleDeliveryMethod.Embed
+ },
+ new SubtitleProfile
+ {
+ Format = "srt",
+ Method = SubtitleDeliveryMethod.External
+ }
+ };
+
+ ResponseProfiles = new[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
+ }
+ }
+}
diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
index d1305d4246..c67bd85b27 100644
--- a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
+++ b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
@@ -83,7 +83,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "avi,mp4",
+ Container = "avi,mp4,m4v",
VideoCodec = "mpeg4,h264",
AudioCodec = "ac3,aac,mp3,pcm",
Type = DlnaProfileType.Video
@@ -248,6 +248,13 @@ namespace Emby.Dlna.Profiles
Type = DlnaProfileType.Video
},
+ new ResponseProfile
+ {
+ Container = "m4v",
+ MimeType = "video/mpeg",
+ Type = DlnaProfileType.Video
+ },
+
new ResponseProfile
{
Container = "mpeg",
diff --git a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
index c21022aa3a..427820a332 100644
--- a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp3",
Type = DlnaProfileType.Video
@@ -211,6 +211,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
index 1bbd40e914..206ca554c3 100644
--- a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -199,6 +199,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
index 019bbafcb4..c618c9990a 100644
--- a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
@@ -79,7 +79,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,eac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -255,6 +255,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
index 910786b839..c30bcfc853 100644
--- a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
@@ -79,7 +79,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,eac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -255,6 +255,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyPs4Profile.cs b/Emby.Dlna/Profiles/SonyPs4Profile.cs
index 44649911dc..8327331846 100644
--- a/Emby.Dlna/Profiles/SonyPs4Profile.cs
+++ b/Emby.Dlna/Profiles/SonyPs4Profile.cs
@@ -63,7 +63,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4,mkv",
+ Container = "mp4,mkv,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "aac,ac3"
@@ -86,7 +86,9 @@ namespace Emby.Dlna.Profiles
{
Container = "mp3",
AudioCodec = "mp3",
- Type = DlnaProfileType.Audio
+ Type = DlnaProfileType.Audio,
+ // Transcoded audio won't be playable at all without this
+ TranscodeSeekInfo = TranscodeSeekInfo.Bytes
},
new TranscodingProfile
{
@@ -253,6 +255,13 @@ namespace Emby.Dlna.Profiles
Container = "wav",
MimeType = "audio/wav",
Type = DlnaProfileType.Audio
+ },
+
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/WdtvLiveProfile.cs b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
index e524816afe..6cef2d9659 100644
--- a/Emby.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
@@ -87,7 +87,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp4,mov",
+ Container = "mp4,mov,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp2,mp3,dca,dts"
diff --git a/Emby.Dlna/Profiles/XboxOneProfile.cs b/Emby.Dlna/Profiles/XboxOneProfile.cs
index 370534a676..8994082ad5 100644
--- a/Emby.Dlna/Profiles/XboxOneProfile.cs
+++ b/Emby.Dlna/Profiles/XboxOneProfile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4,mov,mkv",
+ Container = "mp4,mov,mkv,m4v",
VideoCodec = "h264,mpeg4,mpeg2video",
AudioCodec = "aac,ac3",
Type = DlnaProfileType.Video
@@ -349,6 +349,12 @@ namespace Emby.Dlna.Profiles
Container = "avi",
MimeType = "video/avi",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/Xml/Default.xml b/Emby.Dlna/Profiles/Xml/Default.xml
index 4e29f651ba..b5a5d24b64 100644
--- a/Emby.Dlna/Profiles/Xml/Default.xml
+++ b/Emby.Dlna/Profiles/Xml/Default.xml
@@ -29,8 +29,8 @@
false
-
-
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
index eb63352a3f..556a3d673d 100644
--- a/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
+++ b/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
@@ -5,7 +5,7 @@
Echostar Technologies LLC
http://www.echostar.com
-
+
Emby
@@ -37,9 +37,7 @@
-
-
-
+
diff --git a/Emby.Dlna/Profiles/Xml/LG Smart TV.xml b/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
index dc0e977720..2963e5f383 100644
--- a/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -37,7 +37,7 @@
-
+
@@ -79,7 +79,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml b/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
index 862bede9b4..c9ea6daff3 100644
--- a/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
+++ b/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -34,7 +34,7 @@
-
+
@@ -43,7 +43,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml b/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
index d7b142d84e..b520b2b53a 100644
--- a/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -41,7 +41,7 @@
-
+
@@ -76,6 +76,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml b/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
index 9bc4c2e312..9fa49e94a5 100644
--- a/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
+++ b/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
@@ -29,7 +29,7 @@
false
-
+
@@ -81,7 +81,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml b/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
index 5b2106da54..a3acea8296 100644
--- a/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -40,7 +40,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
@@ -117,6 +117,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sharp Smart TV.xml b/Emby.Dlna/Profiles/Xml/Sharp Smart TV.xml
new file mode 100644
index 0000000000..e367a8c153
--- /dev/null
+++ b/Emby.Dlna/Profiles/Xml/Sharp Smart TV.xml
@@ -0,0 +1,60 @@
+
+
+ Sharp Smart TV
+
+ Sharp
+
+
+
+
+ Emby
+ http://emby.media/
+ Emby Server
+ Emby
+ Emby
+ http://emby.media/
+ false
+ false
+ false
+ Audio,Photo,Video
+ JPEG_SM
+ 480
+ 480
+ 48
+ 48
+ 24000000
+ 24000000
+ 192000
+
+ DMS-1.50
+ http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000
+ 0
+ true
+ true
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
index 154d9a68f7..ee113ef630 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -41,7 +41,7 @@
-
+
@@ -99,6 +99,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index 39d7674a1e..3b234ac36e 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -41,7 +41,7 @@
-
+
@@ -129,6 +129,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index 8b6e88702e..4748b8d2ad 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -41,7 +41,7 @@
-
+
@@ -105,6 +105,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index e76ca2c771..d0ec30a26f 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -41,7 +41,7 @@
-
+
@@ -104,6 +104,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
index ff4aa9cf8e..ba83490b4b 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
@@ -41,7 +41,7 @@
-
+
@@ -104,6 +104,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
index 7ec4ccc907..22131a502c 100644
--- a/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
+++ b/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
@@ -40,12 +40,12 @@
-
+
-
+
@@ -98,6 +98,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/WDTV Live.xml b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
index 96d37e7fb0..1cf3ef5973 100644
--- a/Emby.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/Emby.Dlna/Profiles/Xml/Xbox One.xml b/Emby.Dlna/Profiles/Xml/Xbox One.xml
index 8c13ed8fda..6289847ca4 100644
--- a/Emby.Dlna/Profiles/Xml/Xbox One.xml
+++ b/Emby.Dlna/Profiles/Xml/Xbox One.xml
@@ -39,7 +39,7 @@
-
+
@@ -116,6 +116,9 @@
+
+
+
diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
index 1cd19d010c..3f0e070cac 100644
--- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
@@ -104,7 +104,8 @@ namespace Emby.Dlna.Ssdp
Argument = new UpnpDeviceInfo
{
Location = e.DiscoveredDevice.DescriptionLocation,
- Headers = headers
+ Headers = headers,
+ LocalIpAddress = e.LocalIpAddress
}
};
diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs
index 215ac84924..b9412d0fbb 100644
--- a/Emby.Server.Core/ApplicationHost.cs
+++ b/Emby.Server.Core/ApplicationHost.cs
@@ -326,6 +326,8 @@ namespace Emby.Server.Core
}
}
+ public abstract bool IsRunningAsService { get; }
+
private Assembly GetAssembly(Type type)
{
return type.GetTypeInfo().Assembly;
@@ -489,7 +491,8 @@ namespace Emby.Server.Core
{
var migrations = new List
{
- new LibraryScanMigration(ServerConfigurationManager, TaskManager)
+ new LibraryScanMigration(ServerConfigurationManager, TaskManager),
+ new GuideMigration(ServerConfigurationManager, TaskManager)
};
foreach (var task in migrations)
@@ -1247,7 +1250,6 @@ namespace Emby.Server.Core
HasUpdateAvailable = HasUpdateAvailable,
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
- IsRunningAsService = IsRunningAsService,
SupportsRunningAsService = SupportsRunningAsService,
ServerName = FriendlyName,
LocalAddress = localAddress,
@@ -1476,6 +1478,10 @@ namespace Emby.Server.Core
try
{
AuthorizeServer();
+ }
+ catch (NotImplementedException)
+ {
+
}
catch (Exception ex)
{
diff --git a/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs
index b75de2ff4f..eb3a714652 100644
--- a/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using Mono.Nat;
+using System.Threading.Tasks;
namespace Emby.Server.Core.EntryPoints
{
@@ -106,6 +107,11 @@ namespace Emby.Server.Core.EntryPoints
private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
var info = e.Argument;
string usn;
@@ -169,6 +175,11 @@ namespace Emby.Server.Core.EntryPoints
return;
}
+ if (_disposed)
+ {
+ return;
+ }
+
_logger.Debug("Calling Nat.Handle on " + identifier);
NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp);
}
@@ -185,6 +196,11 @@ namespace Emby.Server.Core.EntryPoints
void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
var device = e.Device;
@@ -208,8 +224,13 @@ namespace Emby.Server.Core.EntryPoints
private List _createdRules = new List();
private List _usnsHandled = new List();
- private void CreateRules(INatDevice device)
+ private async void CreateRules(INatDevice device)
{
+ if (_disposed)
+ {
+ throw new ObjectDisposedException("PortMapper");
+ }
+
// On some systems the device discovered event seems to fire repeatedly
// This check will help ensure we're not trying to port map the same device over and over
@@ -219,12 +240,16 @@ namespace Emby.Server.Core.EntryPoints
{
_createdRules.Add(address);
- CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort);
- CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort);
+ var success = await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false);
+
+ if (success)
+ {
+ await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false);
+ }
}
}
- private async void CreatePortMap(INatDevice device, int privatePort, int publicPort)
+ private async Task CreatePortMap(INatDevice device, int privatePort, int publicPort)
{
_logger.Debug("Creating port map on port {0}", privatePort);
@@ -235,10 +260,14 @@ namespace Emby.Server.Core.EntryPoints
Description = _appHost.Name
}).ConfigureAwait(false);
+
+ return true;
}
catch (Exception ex)
{
_logger.Error("Error creating port map: " + ex.Message);
+
+ return false;
}
}
@@ -249,8 +278,10 @@ namespace Emby.Server.Core.EntryPoints
_logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString());
}
+ private bool _disposed = false;
public void Dispose()
{
+ _disposed = true;
DisposeNat();
}
diff --git a/Emby.Server.Core/IO/LibraryMonitor.cs b/Emby.Server.Core/IO/LibraryMonitor.cs
index 6ed096f441..f0ecb9d892 100644
--- a/Emby.Server.Core/IO/LibraryMonitor.cs
+++ b/Emby.Server.Core/IO/LibraryMonitor.cs
@@ -87,7 +87,7 @@ namespace Emby.Server.Core.IO
public bool IsPathLocked(string path)
{
var lockedPaths = _tempIgnoredPaths.Keys.ToList();
- return lockedPaths.Any(i => string.Equals(i, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i, path));
+ return lockedPaths.Any(i => _fileSystem.AreEqual(i, path) || _fileSystem.ContainsSubPath(i, path));
}
public async void ReportFileSystemChangeComplete(string path, bool refreshPath)
@@ -288,6 +288,13 @@ namespace Emby.Server.Core.IO
{
try
{
+ if (!_fileSystem.DirectoryExists(path))
+ {
+ // Seeing a crash in the mono runtime due to an exception being thrown on a different thread
+ Logger.Info("Skipping realtime monitor for {0} because the path does not exist", path);
+ return;
+ }
+
var newWatcher = new FileSystemWatcher(path, "*")
{
IncludeSubdirectories = true
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 11fd3a872e..d3b2ef7ef7 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -138,7 +138,7 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, item.Name),
+ Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, Notifications.Notifications.GetItemName(item)),
Type = "PlaybackStopped",
ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName),
UserId = user.Id.ToString("N")
@@ -170,7 +170,7 @@ namespace Emby.Server.Implementations.Activity
CreateLogEntry(new ActivityLogEntry
{
- Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, item.Name),
+ Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, Notifications.Notifications.GetItemName(item)),
Type = "PlaybackStart",
ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName),
UserId = user.Id.ToString("N")
@@ -235,10 +235,6 @@ namespace Emby.Server.Implementations.Activity
});
}
- void _logManager_LoggerLoaded(object sender, EventArgs e)
- {
- }
-
void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
{
CreateLogEntry(new ActivityLogEntry
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index f7dc930097..8f03fa7a47 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -343,7 +343,7 @@ namespace Emby.Server.Implementations.Channels
private MediaSourceInfo GetMediaSource(BaseItem item, ChannelMediaInfo info)
{
- var source = info.ToMediaSource();
+ var source = info.ToMediaSource(item.Id);
source.RunTimeTicks = source.RunTimeTicks ?? item.RunTimeTicks;
diff --git a/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
index 170ef07f31..b5639773b4 100644
--- a/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
+++ b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
@@ -9,6 +9,7 @@ using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Security;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Threading;
@@ -17,6 +18,7 @@ namespace Emby.Server.Implementations.Connect
public class ConnectEntryPoint : IServerEntryPoint
{
private ITimer _timer;
+ private IpAddressInfo _cachedIpAddress;
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger;
@@ -26,8 +28,9 @@ namespace Emby.Server.Implementations.Connect
private readonly IApplicationHost _appHost;
private readonly IFileSystem _fileSystem;
private readonly ITimerFactory _timerFactory;
+ private readonly IEncryptionManager _encryption;
- public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost, IFileSystem fileSystem, ITimerFactory timerFactory)
+ public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost, IFileSystem fileSystem, ITimerFactory timerFactory, IEncryptionManager encryption)
{
_httpClient = httpClient;
_appPaths = appPaths;
@@ -37,6 +40,7 @@ namespace Emby.Server.Implementations.Connect
_appHost = appHost;
_fileSystem = fileSystem;
_timerFactory = timerFactory;
+ _encryption = encryption;
}
public void Run()
@@ -143,17 +147,31 @@ namespace Emby.Server.Implementations.Connect
private string CacheFilePath
{
- get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
+ get { return Path.Combine(_appPaths.DataPath, "wan.dat"); }
}
private void CacheAddress(IpAddressInfo address)
{
+ if (_cachedIpAddress != null && _cachedIpAddress.Equals(address))
+ {
+ // no need to update the file if the address has not changed
+ return;
+ }
+
var path = CacheFilePath;
try
{
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
- _fileSystem.WriteAllText(path, address.ToString(), Encoding.UTF8);
+ }
+ catch (Exception ex)
+ {
+ }
+
+ try
+ {
+ _fileSystem.WriteAllText(path, _encryption.EncryptString(address.ToString()), Encoding.UTF8);
+ _cachedIpAddress = address;
}
catch (Exception ex)
{
@@ -169,11 +187,12 @@ namespace Emby.Server.Implementations.Connect
try
{
- var endpoint = _fileSystem.ReadAllText(path, Encoding.UTF8);
+ var endpoint = _encryption.DecryptString(_fileSystem.ReadAllText(path, Encoding.UTF8));
IpAddressInfo ipAddress;
if (_networkManager.TryParseIpAddress(endpoint, out ipAddress))
{
+ _cachedIpAddress = ipAddress;
((ConnectManager)_connectManager).OnWanAddressResolved(ipAddress);
}
}
diff --git a/Emby.Server.Implementations/Connect/ConnectManager.cs b/Emby.Server.Implementations/Connect/ConnectManager.cs
index 8c8b7b0268..7e6755f6aa 100644
--- a/Emby.Server.Implementations/Connect/ConnectManager.cs
+++ b/Emby.Server.Implementations/Connect/ConnectManager.cs
@@ -925,7 +925,11 @@ namespace Emby.Server.Implementations.Connect
}
_data.PendingAuthorizations = newPendingList;
- CacheData();
+
+ if (!newPendingList.Select(i => i.Id).SequenceEqual(currentPendingList.Select(i => i.Id), StringComparer.Ordinal))
+ {
+ CacheData();
+ }
await RefreshGuestNames(list, refreshImages).ConfigureAwait(false);
}
@@ -1118,7 +1122,7 @@ namespace Emby.Server.Implementations.Connect
}
}
- public async Task Authenticate(string username, string passwordMd5)
+ public async Task Authenticate(string username, string passwordMd5)
{
if (string.IsNullOrWhiteSpace(username))
{
@@ -1147,6 +1151,7 @@ namespace Emby.Server.Implementations.Connect
// No need to examine the response
using (var response = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content)
{
+ return _json.DeserializeFromStream(response);
}
}
diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
index 5bc3a625f1..2819a249fb 100644
--- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
+++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
@@ -137,6 +137,11 @@ namespace Emby.Server.Implementations.Data
var numComplete = 0;
var numItems = result.Count;
+ var allLibraryPaths = _libraryManager
+ .GetVirtualFolders()
+ .SelectMany(i => i.Locations)
+ .ToList();
+
foreach (var item in result)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -170,9 +175,8 @@ namespace Emby.Server.Implementations.Data
continue;
}
- if (Folder.IsPathOffline(path))
+ if (Folder.IsPathOffline(path, allLibraryPaths))
{
- await libraryItem.UpdateIsOffline(true).ConfigureAwait(false);
continue;
}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 8c16216b95..c158f2e513 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -372,7 +372,7 @@ namespace Emby.Server.Implementations.Data
userDataRepo.Initialize(WriteLock, _connection);
- _shrinkMemoryTimer = _timerFactory.Create(OnShrinkMemoryTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(15));
+ _shrinkMemoryTimer = _timerFactory.Create(OnShrinkMemoryTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(30));
}
private void OnShrinkMemoryTimerCallback(object state)
@@ -2384,8 +2384,17 @@ namespace Emby.Server.Implementations.Data
var excludeIds = query.ExcludeItemIds.ToList();
excludeIds.Add(item.Id.ToString("N"));
- query.ExcludeItemIds = excludeIds.ToArray();
+ if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains(typeof(Trailer).Name))
+ {
+ var hasTrailers = item as IHasTrailers;
+ if (hasTrailers != null)
+ {
+ excludeIds.AddRange(hasTrailers.GetTrailerIds().Select(i => i.ToString("N")));
+ }
+ }
+
+ query.ExcludeItemIds = excludeIds.ToArray();
query.ExcludeProviderIds = item.ProviderIds;
}
@@ -2548,57 +2557,53 @@ namespace Emby.Server.Implementations.Data
{
using (var connection = CreateConnection(true))
{
- return connection.RunInTransaction(db =>
- {
- var list = new List();
+ var list = new List();
- using (var statement = PrepareStatementSafe(db, commandText))
+ using (var statement = PrepareStatementSafe(connection, commandText))
+ {
+ if (EnableJoinUserData(query))
{
- if (EnableJoinUserData(query))
- {
- statement.TryBind("@UserId", query.User.Id);
- }
+ statement.TryBind("@UserId", query.User.Id);
+ }
- BindSimilarParams(query, statement);
+ BindSimilarParams(query, statement);
- // Running this again will bind the params
- GetWhereClauses(query, statement);
+ // Running this again will bind the params
+ GetWhereClauses(query, statement);
- foreach (var row in statement.ExecuteQuery())
+ foreach (var row in statement.ExecuteQuery())
+ {
+ var item = GetItem(row, query);
+ if (item != null)
{
- var item = GetItem(row, query);
- if (item != null)
- {
- list.Add(item);
- }
+ list.Add(item);
}
}
+ }
- // Hack for right now since we currently don't support filtering out these duplicates within a query
- if (query.EnableGroupByMetadataKey)
+ // Hack for right now since we currently don't support filtering out these duplicates within a query
+ if (query.EnableGroupByMetadataKey)
+ {
+ var limit = query.Limit ?? int.MaxValue;
+ limit -= 4;
+ var newList = new List();
+
+ foreach (var item in list)
{
- var limit = query.Limit ?? int.MaxValue;
- limit -= 4;
- var newList = new List();
+ AddItem(newList, item);
- foreach (var item in list)
+ if (newList.Count >= limit)
{
- AddItem(newList, item);
-
- if (newList.Count >= limit)
- {
- break;
- }
+ break;
}
-
- list = newList;
}
- LogQueryTime("GetItemList", commandText, now);
+ list = newList;
+ }
- return list;
+ LogQueryTime("GetItemList", commandText, now);
- }, ReadTransactionMode);
+ return list;
}
}
}
@@ -2652,7 +2657,7 @@ namespace Emby.Server.Implementations.Data
{
//Logger.Debug("{2} query time: {0}ms. Query: {1}",
// Convert.ToInt32(elapsed),
- // cmd.CommandText,
+ // commandText,
// methodName);
}
}
@@ -2825,8 +2830,9 @@ namespace Emby.Server.Implementations.Data
{
if (orderBy.Count == 0)
{
- orderBy.Add(new Tuple("SimilarityScore", SortOrder.Descending));
orderBy.Add(new Tuple(ItemSortBy.Random, SortOrder.Ascending));
+ orderBy.Add(new Tuple("SimilarityScore", SortOrder.Descending));
+ //orderBy.Add(new Tuple(ItemSortBy.Random, SortOrder.Ascending));
query.SortOrder = SortOrder.Descending;
enableOrderInversion = false;
}
@@ -3212,6 +3218,11 @@ namespace Emby.Server.Implementations.Data
private List GetWhereClauses(InternalItemsQuery query, IStatement statement, string paramSuffix = "")
{
+ if (query.IsResumable ?? false)
+ {
+ query.IsVirtualItem = false;
+ }
+
var whereClauses = new List();
if (EnableJoinUserData(query))
@@ -3372,9 +3383,9 @@ namespace Emby.Server.Implementations.Data
}
}
- if (query.SimilarTo != null)
+ if (query.SimilarTo != null && query.MinSimilarityScore > 0)
{
- whereClauses.Add("SimilarityScore > 0");
+ whereClauses.Add("SimilarityScore > " + (query.MinSimilarityScore - 1).ToString(CultureInfo.InvariantCulture));
}
if (query.IsFolder.HasValue)
@@ -3616,10 +3627,12 @@ namespace Emby.Server.Implementations.Data
var index = 0;
foreach (var type in query.TrailerTypes)
{
- clauses.Add("TrailerTypes like @TrailerTypes" + index);
+ var paramName = "@TrailerTypes" + index;
+
+ clauses.Add("TrailerTypes like " + paramName);
if (statement != null)
{
- statement.TryBind("@TrailerTypes" + index, "%" + type + "%");
+ statement.TryBind(paramName, "%" + type + "%");
}
index++;
}
@@ -4085,27 +4098,6 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("LocationType in (" + val + ")");
}
- if (query.ExcludeLocationTypes.Length == 1)
- {
- if (query.ExcludeLocationTypes[0] == LocationType.Virtual && _config.Configuration.SchemaVersion >= 90)
- {
- query.IsVirtualItem = false;
- }
- else
- {
- whereClauses.Add("LocationType<>@ExcludeLocationTypes");
- if (statement != null)
- {
- statement.TryBind("@ExcludeLocationTypes", query.ExcludeLocationTypes[0].ToString());
- }
- }
- }
- else if (query.ExcludeLocationTypes.Length > 1)
- {
- var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray());
-
- whereClauses.Add("LocationType not in (" + val + ")");
- }
if (query.IsVirtualItem.HasValue)
{
whereClauses.Add("IsVirtualItem=@IsVirtualItem");
@@ -4221,7 +4213,7 @@ namespace Emby.Server.Implementations.Data
var paramName = "@ExcludeProviderId" + index;
//excludeIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")");
- excludeIds.Add("ProviderIds not like " + paramName);
+ excludeIds.Add("(ProviderIds is null or ProviderIds not like " + paramName + ")");
if (statement != null)
{
statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%");
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 8e6c1263d6..f866c34dee 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -361,10 +361,7 @@ namespace Emby.Server.Implementations.Dto
if (collectionFolder != null)
{
dto.OriginalCollectionType = collectionFolder.CollectionType;
-
- dto.CollectionType = user == null ?
- collectionFolder.CollectionType :
- collectionFolder.GetViewType(user);
+ dto.CollectionType = collectionFolder.CollectionType;
}
if (fields.Contains(ItemFields.CanDelete))
@@ -1515,7 +1512,8 @@ namespace Emby.Server.Implementations.Dto
return artist;
}
}
- return item.GetParent();
+
+ return item.DisplayParent ?? item.GetParent();
}
private void AddInheritedImages(BaseItemDto dto, BaseItem item, DtoOptions options, BaseItem owner)
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 7ee0c566f7..e3cd968945 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -182,6 +182,7 @@
+
diff --git a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
index 021ae47ec3..4ab6d32f35 100644
--- a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
+++ b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
@@ -6,15 +6,16 @@ using System.Threading.Tasks;
using MediaBrowser.Model.System;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Common;
+using MediaBrowser.Controller;
namespace Emby.Server.Implementations.EntryPoints
{
public class SystemEvents : IServerEntryPoint
{
private readonly ISystemEvents _systemEvents;
- private readonly IApplicationHost _appHost;
+ private readonly IServerApplicationHost _appHost;
- public SystemEvents(ISystemEvents systemEvents, IApplicationHost appHost)
+ public SystemEvents(ISystemEvents systemEvents, IServerApplicationHost appHost)
{
_systemEvents = systemEvents;
_appHost = appHost;
diff --git a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
index 1b897ca299..9fbe06673f 100644
--- a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
@@ -10,6 +10,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
namespace Emby.Server.Implementations.EntryPoints
@@ -19,7 +20,7 @@ namespace Emby.Server.Implementations.EntryPoints
///
public class UsageEntryPoint : IServerEntryPoint
{
- private readonly IApplicationHost _applicationHost;
+ private readonly IServerApplicationHost _applicationHost;
private readonly IHttpClient _httpClient;
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
@@ -28,7 +29,7 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly ConcurrentDictionary _apps = new ConcurrentDictionary();
- public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config)
+ public UsageEntryPoint(ILogger logger, IServerApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config)
{
_logger = logger;
_applicationHost = applicationHost;
diff --git a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs
index be848acb77..31254c6c26 100644
--- a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs
+++ b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs
@@ -8,19 +8,20 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller;
using MediaBrowser.Model.Logging;
namespace Emby.Server.Implementations.EntryPoints
{
public class UsageReporter
{
- private readonly IApplicationHost _applicationHost;
+ private readonly IServerApplicationHost _applicationHost;
private readonly IHttpClient _httpClient;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
- public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger)
+ public UsageReporter(IServerApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger)
{
_applicationHost = applicationHost;
_httpClient = httpClient;
diff --git a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 5bb21d02ac..f841b8b6b2 100644
--- a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
@@ -61,92 +61,92 @@ namespace Emby.Server.Implementations.FileOrganization
};
try
- {
- if (_libraryMonitor.IsPathLocked(path))
{
- result.Status = FileSortingStatus.Failure;
- result.StatusMessage = "Path is locked by other processes. Please try again later.";
- return result;
- }
+ if (_libraryMonitor.IsPathLocked(path))
+ {
+ result.Status = FileSortingStatus.Failure;
+ result.StatusMessage = "Path is locked by other processes. Please try again later.";
+ return result;
+ }
- var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
- var resolver = new EpisodeResolver(namingOptions, new NullLogger());
+ var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
+ var resolver = new EpisodeResolver(namingOptions, new NullLogger());
- var episodeInfo = resolver.Resolve(path, false) ??
- new MediaBrowser.Naming.TV.EpisodeInfo();
+ var episodeInfo = resolver.Resolve(path, false) ??
+ new MediaBrowser.Naming.TV.EpisodeInfo();
- var seriesName = episodeInfo.SeriesName;
+ var seriesName = episodeInfo.SeriesName;
- if (!string.IsNullOrEmpty(seriesName))
- {
- var seasonNumber = episodeInfo.SeasonNumber;
+ if (!string.IsNullOrEmpty(seriesName))
+ {
+ var seasonNumber = episodeInfo.SeasonNumber;
- result.ExtractedSeasonNumber = seasonNumber;
+ result.ExtractedSeasonNumber = seasonNumber;
- // Passing in true will include a few extra regex's
- var episodeNumber = episodeInfo.EpisodeNumber;
+ // Passing in true will include a few extra regex's
+ var episodeNumber = episodeInfo.EpisodeNumber;
- result.ExtractedEpisodeNumber = episodeNumber;
+ result.ExtractedEpisodeNumber = episodeNumber;
- var premiereDate = episodeInfo.IsByDate ?
- new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
- (DateTime?)null;
+ var premiereDate = episodeInfo.IsByDate ?
+ new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
+ (DateTime?)null;
- if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
- {
- if (episodeInfo.IsByDate)
+ if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
{
- _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
+ if (episodeInfo.IsByDate)
+ {
+ _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
+ }
+ else
+ {
+ _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
+ }
+
+ var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;
+
+ result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;
+
+ await OrganizeEpisode(path,
+ seriesName,
+ seasonNumber,
+ episodeNumber,
+ endingEpisodeNumber,
+ premiereDate,
+ options,
+ overwriteExisting,
+ false,
+ result,
+ cancellationToken).ConfigureAwait(false);
}
else
{
- _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
+ var msg = string.Format("Unable to determine episode number from {0}", path);
+ result.Status = FileSortingStatus.Failure;
+ result.StatusMessage = msg;
+ _logger.Warn(msg);
}
-
- var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;
-
- result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;
-
- await OrganizeEpisode(path,
- seriesName,
- seasonNumber,
- episodeNumber,
- endingEpisodeNumber,
- premiereDate,
- options,
- overwriteExisting,
- false,
- result,
- cancellationToken).ConfigureAwait(false);
}
else
{
- var msg = string.Format("Unable to determine episode number from {0}", path);
+ var msg = string.Format("Unable to determine series name from {0}", path);
result.Status = FileSortingStatus.Failure;
result.StatusMessage = msg;
_logger.Warn(msg);
}
- }
- else
- {
- var msg = string.Format("Unable to determine series name from {0}", path);
- result.Status = FileSortingStatus.Failure;
- result.StatusMessage = msg;
- _logger.Warn(msg);
- }
- var previousResult = _organizationService.GetResultBySourcePath(path);
+ var previousResult = _organizationService.GetResultBySourcePath(path);
- if (previousResult != null)
- {
- // Don't keep saving the same result over and over if nothing has changed
- if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
+ if (previousResult != null)
{
- return previousResult;
+ // Don't keep saving the same result over and over if nothing has changed
+ if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
+ {
+ return previousResult;
+ }
}
- }
- await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
+ await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -162,58 +162,60 @@ namespace Emby.Server.Implementations.FileOrganization
var result = _organizationService.GetResult(request.ResultId);
try
- {
- Series series = null;
-
- if (request.NewSeriesProviderIds.Count > 0)
{
- // We're having a new series here
- SeriesInfo seriesRequest = new SeriesInfo();
- seriesRequest.ProviderIds = request.NewSeriesProviderIds;
-
- var refreshOptions = new MetadataRefreshOptions(_fileSystem);
- series = new Series();
- series.Id = Guid.NewGuid();
- series.Name = request.NewSeriesName;
+ Series series = null;
- int year;
- if (int.TryParse(request.NewSeriesYear, out year))
+ if (request.NewSeriesProviderIds.Count > 0)
{
- series.ProductionYear = year;
- }
+ // We're having a new series here
+ SeriesInfo seriesRequest = new SeriesInfo();
+ seriesRequest.ProviderIds = request.NewSeriesProviderIds;
- var seriesFolderName = series.Name;
- if (series.ProductionYear.HasValue)
- {
- seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
- }
+ var refreshOptions = new MetadataRefreshOptions(_fileSystem);
+ series = new Series();
+ series.Id = Guid.NewGuid();
+ series.Name = request.NewSeriesName;
+
+ int year;
+ if (int.TryParse(request.NewSeriesYear, out year))
+ {
+ series.ProductionYear = year;
+ }
- series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
+ var seriesFolderName = series.Name;
+ if (series.ProductionYear.HasValue)
+ {
+ seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
+ }
- series.ProviderIds = request.NewSeriesProviderIds;
+ seriesFolderName = _fileSystem.GetValidFilename(seriesFolderName);
- await series.RefreshMetadata(refreshOptions, cancellationToken);
- }
+ series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
- if (series == null)
- {
- // Existing Series
- series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
- }
+ series.ProviderIds = request.NewSeriesProviderIds;
- await OrganizeEpisode(result.OriginalPath,
- series,
- request.SeasonNumber,
- request.EpisodeNumber,
- request.EndingEpisodeNumber,
- null,
- options,
- true,
- request.RememberCorrection,
- result,
- cancellationToken).ConfigureAwait(false);
+ await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
+
+ if (series == null)
+ {
+ // Existing Series
+ series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
+ }
+
+ await OrganizeEpisode(result.OriginalPath,
+ series,
+ request.SeasonNumber,
+ request.EpisodeNumber,
+ request.EndingEpisodeNumber,
+ null,
+ options,
+ true,
+ request.RememberCorrection,
+ result,
+ cancellationToken).ConfigureAwait(false);
- await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
+ await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -287,91 +289,91 @@ namespace Emby.Server.Implementations.FileOrganization
{
throw new Exception("File is currently processed otherwise. Please try again later.");
}
-
- try
- {
- // Proceed to sort the file
- var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
-
- if (string.IsNullOrEmpty(newPath))
- {
- var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
- throw new Exception(msg);
- }
-
- _logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
- result.TargetPath = newPath;
-
- var fileExists = _fileSystem.FileExists(result.TargetPath);
- var otherDuplicatePaths = GetOtherDuplicatePaths(result.TargetPath, series, seasonNumber, episodeNumber, endingEpiosdeNumber);
- if (!overwriteExisting)
+ try
{
- if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
- {
- var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath);
- _logger.Info(msg);
- result.Status = FileSortingStatus.SkippedExisting;
- result.StatusMessage = msg;
- return;
- }
+ // Proceed to sort the file
+ var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
- if (fileExists)
+ if (string.IsNullOrEmpty(newPath))
{
- var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath);
- _logger.Info(msg);
- result.Status = FileSortingStatus.SkippedExisting;
- result.StatusMessage = msg;
- result.TargetPath = newPath;
- return;
+ var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
+ throw new Exception(msg);
}
- if (otherDuplicatePaths.Count > 0)
- {
- var msg = string.Format("File '{0}' already exists as these:'{1}'. Stopping organization", sourcePath, string.Join("', '", otherDuplicatePaths));
- _logger.Info(msg);
- result.Status = FileSortingStatus.SkippedExisting;
- result.StatusMessage = msg;
- result.DuplicatePaths = otherDuplicatePaths;
- return;
- }
- }
+ _logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
+ result.TargetPath = newPath;
- PerformFileSorting(options.TvOptions, result);
-
- if (overwriteExisting)
- {
- var hasRenamedFiles = false;
+ var fileExists = _fileSystem.FileExists(result.TargetPath);
+ var otherDuplicatePaths = GetOtherDuplicatePaths(result.TargetPath, series, seasonNumber, episodeNumber, endingEpiosdeNumber);
- foreach (var path in otherDuplicatePaths)
+ if (!overwriteExisting)
{
- _logger.Debug("Removing duplicate episode {0}", path);
-
- _libraryMonitor.ReportFileSystemChangeBeginning(path);
-
- var renameRelatedFiles = !hasRenamedFiles &&
- string.Equals(Path.GetDirectoryName(path), Path.GetDirectoryName(result.TargetPath), StringComparison.OrdinalIgnoreCase);
-
- if (renameRelatedFiles)
+ if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
{
- hasRenamedFiles = true;
+ var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath);
+ _logger.Info(msg);
+ result.Status = FileSortingStatus.SkippedExisting;
+ result.StatusMessage = msg;
+ return;
}
- try
+ if (fileExists)
{
- DeleteLibraryFile(path, renameRelatedFiles, result.TargetPath);
+ var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath);
+ _logger.Info(msg);
+ result.Status = FileSortingStatus.SkippedExisting;
+ result.StatusMessage = msg;
+ result.TargetPath = newPath;
+ return;
}
- catch (IOException ex)
+
+ if (otherDuplicatePaths.Count > 0)
{
- _logger.ErrorException("Error removing duplicate episode", ex, path);
+ var msg = string.Format("File '{0}' already exists as these:'{1}'. Stopping organization", sourcePath, string.Join("', '", otherDuplicatePaths));
+ _logger.Info(msg);
+ result.Status = FileSortingStatus.SkippedExisting;
+ result.StatusMessage = msg;
+ result.DuplicatePaths = otherDuplicatePaths;
+ return;
}
- finally
+ }
+
+ PerformFileSorting(options.TvOptions, result);
+
+ if (overwriteExisting)
+ {
+ var hasRenamedFiles = false;
+
+ foreach (var path in otherDuplicatePaths)
{
- _libraryMonitor.ReportFileSystemChangeComplete(path, true);
+ _logger.Debug("Removing duplicate episode {0}", path);
+
+ _libraryMonitor.ReportFileSystemChangeBeginning(path);
+
+ var renameRelatedFiles = !hasRenamedFiles &&
+ string.Equals(Path.GetDirectoryName(path), Path.GetDirectoryName(result.TargetPath), StringComparison.OrdinalIgnoreCase);
+
+ if (renameRelatedFiles)
+ {
+ hasRenamedFiles = true;
+ }
+
+ try
+ {
+ DeleteLibraryFile(path, renameRelatedFiles, result.TargetPath);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error removing duplicate episode", ex, path);
+ }
+ finally
+ {
+ _libraryMonitor.ReportFileSystemChangeComplete(path, true);
+ }
}
}
}
- }
catch (Exception ex)
{
result.Status = FileSortingStatus.Failure;
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index ec3dfeb609..ede85fb67d 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -49,6 +49,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
string device = null;
string client = null;
string version = null;
+ string token = null;
if (auth != null)
{
@@ -56,9 +57,13 @@ namespace Emby.Server.Implementations.HttpServer.Security
auth.TryGetValue("Device", out device);
auth.TryGetValue("Client", out client);
auth.TryGetValue("Version", out version);
+ auth.TryGetValue("Token", out token);
}
- var token = httpReq.Headers["X-Emby-Token"];
+ if (string.IsNullOrWhiteSpace(token))
+ {
+ token = httpReq.Headers["X-Emby-Token"];
+ }
if (string.IsNullOrWhiteSpace(token))
{
@@ -156,8 +161,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
// There should be at least to parts
if (parts.Length != 2) return null;
+ var acceptedNames = new[] { "MediaBrowser", "Emby"};
+
// It has to be a digest request
- if (!string.Equals(parts[0], "MediaBrowser", StringComparison.OrdinalIgnoreCase))
+ if (!acceptedNames.Contains(parts[0] ?? string.Empty, StringComparer.OrdinalIgnoreCase))
{
return null;
}
@@ -174,7 +181,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
if (param.Length == 2)
{
- var value = NormalizeValue (param[1].Trim(new[] { '"' }));
+ var value = NormalizeValue(param[1].Trim(new[] { '"' }));
result.Add(param[0], value);
}
}
@@ -182,14 +189,14 @@ namespace Emby.Server.Implementations.HttpServer.Security
return result;
}
- private string NormalizeValue(string value)
- {
- if (string.IsNullOrWhiteSpace (value))
- {
- return value;
- }
+ private string NormalizeValue(string value)
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ return value;
+ }
- return System.Net.WebUtility.HtmlEncode(value);
- }
+ return System.Net.WebUtility.HtmlEncode(value);
+ }
}
}
diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
index 39033249fd..d7f2ffa431 100644
--- a/Emby.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -261,10 +261,11 @@ namespace Emby.Server.Implementations.IO
// In order to determine if the file is being written to, we have to request write access
// But if the server only has readonly access, this is going to cause this entire algorithm to fail
// So we'll take a best guess about our access level
- var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta
- ? FileAccessMode.ReadWrite
- : FileAccessMode.Read;
+ //var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta
+ // ? FileAccessMode.ReadWrite
+ // : FileAccessMode.Read;
+ var requestedFileAccess = FileAccessMode.Read;
try
{
using (_fileSystem.GetFileStream(path, FileOpenMode.Open, requestedFileAccess, FileShareMode.ReadWrite))
diff --git a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
index 180f6aba7f..4d19a0e9b8 100644
--- a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
+++ b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
@@ -100,20 +100,30 @@ namespace Emby.Server.Implementations.Intros
if (trailerTypes.Count > 0)
{
+ if (trailerTypes.Count >= 5)
+ {
+ trailerTypes.Clear();
+ }
+
+ // hack - can't filter by user library because local trailers get TopParentId =null in the db.
+ // for now we have to use a post-query filter afterwards to solve that
var trailerResult = _libraryManager.GetItemList(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Trailer).Name },
TrailerTypes = trailerTypes.ToArray(),
SimilarTo = item,
- IsPlayed = config.EnableIntrosForWatchedContent ? (bool?)null : false,
+ //IsPlayed = config.EnableIntrosForWatchedContent ? (bool?)null : false,
MaxParentalRating = config.EnableIntrosParentalControl ? ratingLevel : null,
BlockUnratedItems = config.EnableIntrosParentalControl ? new[] { UnratedItem.Trailer } : new UnratedItem[] { },
// Account for duplicates by imdb id, since the database doesn't support this yet
- Limit = config.TrailerLimit * 2,
+ Limit = config.TrailerLimit * 4,
SourceTypes = sourceTypes.ToArray()
-
- }).Where(i => string.IsNullOrWhiteSpace(i.GetProviderId(MetadataProviders.Imdb)) || !string.Equals(i.GetProviderId(MetadataProviders.Imdb), item.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).Take(config.TrailerLimit);
+ })
+ .Where(i => string.IsNullOrWhiteSpace(i.GetProviderId(MetadataProviders.Imdb)) || !string.Equals(i.GetProviderId(MetadataProviders.Imdb), item.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
+ .Where(i => i.IsVisibleStandalone(user))
+ .Where(i => config.EnableIntrosForWatchedContent || !i.IsPlayed(user))
+ .Take(config.TrailerLimit);
candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer
{
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 4c788a2abe..c59a22884c 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1956,30 +1956,6 @@ namespace Emby.Server.Implementations.Library
var options = collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
- if (options.SchemaVersion < 3)
- {
- options.SaveLocalMetadata = ConfigurationManager.Configuration.SaveLocalMeta;
- options.EnableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders;
- }
-
- if (options.SchemaVersion < 2)
- {
- var chapterOptions = ConfigurationManager.GetConfiguration("chapters");
- options.ExtractChapterImagesDuringLibraryScan = chapterOptions.ExtractDuringLibraryScan;
-
- if (collectionFolder != null)
- {
- if (string.Equals(collectionFolder.CollectionType, "movies", StringComparison.OrdinalIgnoreCase))
- {
- options.EnableChapterImageExtraction = chapterOptions.EnableMovieChapterImageExtraction;
- }
- else if (string.Equals(collectionFolder.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
- {
- options.EnableChapterImageExtraction = chapterOptions.EnableEpisodeChapterImageExtraction;
- }
- }
- }
-
return options;
}
@@ -2034,7 +2010,7 @@ namespace Emby.Server.Implementations.Library
private string GetContentTypeOverride(string path, bool inherit)
{
- var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || (inherit && !string.IsNullOrWhiteSpace(i.Name) && _fileSystem.ContainsSubPath(i.Name, path)));
+ var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path) || (inherit && !string.IsNullOrWhiteSpace(i.Name) && _fileSystem.ContainsSubPath(i.Name, path)));
if (nameValuePair != null)
{
return nameValuePair.Value;
@@ -2505,6 +2481,8 @@ namespace Emby.Server.Implementations.Library
options.VideoFileExtensions.Remove(".zip");
}
+ options.VideoFileExtensions.Add(".tp");
+
return options;
}
@@ -2615,7 +2593,7 @@ namespace Emby.Server.Implementations.Library
{
foreach (var pathInfo in libraryOptions.PathInfos)
{
- if (string.IsNullOrWhiteSpace(pathInfo.NetworkPath))
+ if (string.IsNullOrWhiteSpace(pathInfo.Path) || string.IsNullOrWhiteSpace(pathInfo.NetworkPath))
{
continue;
}
@@ -2643,10 +2621,13 @@ namespace Emby.Server.Implementations.Library
foreach (var map in ConfigurationManager.Configuration.PathSubstitutions)
{
- var substitutionResult = SubstitutePathInternal(path, map.From, map.To);
- if (substitutionResult.Item2)
+ if (!string.IsNullOrWhiteSpace(map.From))
{
- return substitutionResult.Item1;
+ var substitutionResult = SubstitutePathInternal(path, map.From, map.To);
+ if (substitutionResult.Item2)
+ {
+ return substitutionResult.Item1;
+ }
}
}
@@ -3088,7 +3069,7 @@ namespace Emby.Server.Implementations.Library
{
removeList.Add(contentType);
}
- else if (string.Equals(path, contentType.Name, StringComparison.OrdinalIgnoreCase)
+ else if (_fileSystem.AreEqual(path, contentType.Name)
|| _fileSystem.ContainsSubPath(path, contentType.Name))
{
removeList.Add(contentType);
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 93c406ebca..c1bd8fe915 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -199,6 +199,8 @@ namespace Emby.Server.Implementations.Library
foreach (var mediaSource in list)
{
+ mediaSource.InferTotalBitrate();
+
SetKeyProperties(provider, mediaSource);
}
diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs
index 7669dd0bf1..9d07837c69 100644
--- a/Emby.Server.Implementations/Library/MusicManager.cs
+++ b/Emby.Server.Implementations/Library/MusicManager.cs
@@ -105,11 +105,10 @@ namespace Emby.Server.Implementations.Library
return inputItems
.Cast
\ No newline at end of file
diff --git a/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs
index 3d6a3e35dc..a5dc691a75 100644
--- a/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs
+++ b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs
@@ -6,8 +6,8 @@ namespace MediaBrowser.Server.Mono.Native
{
public class MonoFileSystem : ManagedFileSystem
{
- public MonoFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars)
- : base(logger, supportsAsyncFileStreams, enableManagedInvalidFileNameChars, true)
+ public MonoFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars, string tempPath)
+ : base(logger, supportsAsyncFileStreams, enableManagedInvalidFileNameChars, true, tempPath)
{
}
diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs
index b3aeb2027b..8100dec8d7 100644
--- a/MediaBrowser.Server.Mono/Program.cs
+++ b/MediaBrowser.Server.Mono/Program.cs
@@ -108,7 +108,7 @@ namespace MediaBrowser.Server.Mono
// Allow all https requests
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
- var fileSystem = new MonoFileSystem(logManager.GetLogger("FileSystem"), false, false);
+ var fileSystem = new MonoFileSystem(logManager.GetLogger("FileSystem"), false, false, appPaths.TempDirectory);
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
var environmentInfo = GetEnvironmentInfo();
diff --git a/MediaBrowser.Server.Mono/System.Data.SQLite.dll.config b/MediaBrowser.Server.Mono/System.Data.SQLite.dll.config
deleted file mode 100644
index 83a6cd9f38..0000000000
--- a/MediaBrowser.Server.Mono/System.Data.SQLite.dll.config
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
index 8ecdca46b3..fded988626 100644
--- a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
@@ -113,7 +113,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
Type = SatIpHost.DeviceType,
Url = deviceUrl,
InfoUrl = infoUrl,
- DataVersion = 1,
DeviceId = info.DeviceId,
FriendlyName = info.FriendlyName,
Tuners = info.Tuners,
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
index 55101ce10f..fffca4ca9f 100644
--- a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
@@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
if (!string.IsNullOrWhiteSpace(tuner.M3UUrl))
{
- return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
+ return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, false, cancellationToken).ConfigureAwait(false);
}
var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false);
@@ -115,6 +115,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
RequiresClosing = false
};
+ mediaSource.InferTotalBitrate(true);
+
return new List { mediaSource };
}
return new List();
@@ -179,4 +181,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
return streamPath;
}
}
-}
+}
\ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index c349401415..70b86c4a61 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -324,7 +324,7 @@ namespace MediaBrowser.ServerApplication
/// The options.
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
{
- var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
+ var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true, appPaths.TempDirectory);
fileSystem.AddShortcutHandler(new LnkShortcutHandler());
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
@@ -601,6 +601,12 @@ namespace MediaBrowser.ServerApplication
/// true if XXXX, false otherwise
private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
{
+ // Not supported
+ if (IsRunningAsService)
+ {
+ return false;
+ }
+
// Look for the existence of an update archive
var updateArchive = Path.Combine(appPaths.TempUpdatePath, "MBServer" + ".zip");
if (File.Exists(updateArchive))
diff --git a/MediaBrowser.Tests/M3uParserTest.cs b/MediaBrowser.Tests/M3uParserTest.cs
new file mode 100644
index 0000000000..3320d87947
--- /dev/null
+++ b/MediaBrowser.Tests/M3uParserTest.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Emby.Common.Implementations.Cryptography;
+using Emby.Server.Implementations.LiveTv.TunerHosts;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Model.Logging;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace MediaBrowser.Tests
+{
+ [TestClass]
+ public class M3uParserTest
+ {
+ [TestMethod]
+ public void TestFormat1()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString("#EXTINF:0,84. VOX Schweiz\nhttp://mystream", "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.AreEqual("VOX Schweiz", result[0].Name);
+ Assert.AreEqual("84", result[0].Number);
+ }
+ [TestMethod]
+ public void TestFormat2()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var input = "#EXTINF:-1 tvg-id=\"\" tvg-name=\"ABC News 04\" tvg-logo=\"\" group-title=\"ABC Group\",ABC News 04";
+ input += "\n";
+ input += "http://mystream";
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString(input, "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.AreEqual("ABC News 04", result[0].Name);
+ Assert.IsNull(result[0].Number);
+ }
+
+ [TestMethod]
+ public void TestFormat3()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString("#EXTINF:0, 3.2 - Movies!\nhttp://mystream", "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.AreEqual("Movies!", result[0].Name);
+ Assert.AreEqual("3.2", result[0].Number);
+ }
+
+ [TestMethod]
+ public void TestFormat4()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString("#EXTINF:0 tvg-id=\"abckabclosangeles.path.to\" tvg-logo=\"path.to / channel_logos / abckabclosangeles.png\", ABC KABC Los Angeles\nhttp://mystream", "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.IsNull(result[0].Number);
+ Assert.AreEqual("ABC KABC Los Angeles", result[0].Name);
+ }
+
+ [TestMethod]
+ public void TestFormat5()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString("#EXTINF:-1 channel-id=\"2101\" tvg-id=\"I69387.json.schedulesdirect.org\" group-title=\"Entertainment\",BBC 1 HD\nhttp://mystream", "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.AreEqual("BBC 1 HD", result[0].Name);
+ Assert.AreEqual("2101", result[0].Number);
+ }
+
+ [TestMethod]
+ public void TestFormat6()
+ {
+ BaseExtensions.CryptographyProvider = new CryptographyProvider();
+
+ var result = new M3uParser(new NullLogger(), null, null, null).ParseString("#EXTINF:-1 tvg-id=\"2101\" group-title=\"Entertainment\",BBC 1 HD\nhttp://mystream", "-", "-");
+ Assert.AreEqual(1, result.Count);
+
+ Assert.AreEqual("BBC 1 HD", result[0].Name);
+ Assert.AreEqual("2101", result[0].Number);
+ }
+ }
+}
diff --git a/MediaBrowser.Tests/MediaBrowser.Tests.csproj b/MediaBrowser.Tests/MediaBrowser.Tests.csproj
index 4ea2cb0c0e..8ba828d85f 100644
--- a/MediaBrowser.Tests/MediaBrowser.Tests.csproj
+++ b/MediaBrowser.Tests/MediaBrowser.Tests.csproj
@@ -37,6 +37,9 @@
4
+
+ ..\ThirdParty\emby\Emby.Common.Implementations.dll
+
@@ -58,12 +61,21 @@
+
+
+ {e383961b-9356-4d5d-8233-9a1079d03055}
+ Emby.Server.Implementations
+
+
+ {9142eefa-7570-41e1-bfcc-468bb571af2f}
+ MediaBrowser.Common
+
{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}
MediaBrowser.Controller
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 0a67cbdb06..5b0ef735ee 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -159,9 +159,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -255,6 +252,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -417,9 +417,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -645,9 +642,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -813,9 +807,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -855,9 +846,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -897,12 +885,6 @@
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
PreserveNewest
@@ -975,6 +957,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -987,9 +972,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -1024,9 +1006,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -1092,11 +1071,6 @@
PreserveNewest
-
-
- PreserveNewest
-
-
PreserveNewest
@@ -1193,11 +1167,6 @@
PreserveNewest
-
-
- PreserveNewest
-
-
PreserveNewest
@@ -1249,6 +1218,9 @@
+
+ PreserveNewest
+
PreserveNewest
@@ -1385,146 +1357,152 @@
PreserveNewest
-
- PreserveNewest
-
-
+
PreserveNewest
-
-
+
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
-
+
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
+
PreserveNewest
-
-
+
+
PreserveNewest
-
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index dba6d96ac4..e4037f2efc 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -964,7 +964,20 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
default:
- reader.Skip();
+ string readerName = reader.Name;
+ string providerIdValue;
+ if (_validProviderIds.TryGetValue(readerName, out providerIdValue))
+ {
+ var id = reader.ReadElementContentAsString();
+ if (!string.IsNullOrWhiteSpace(id))
+ {
+ item.SetProviderId(providerIdValue, id);
+ }
+ }
+ else
+ {
+ reader.Skip();
+ }
break;
}
}
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 18936df013..057522e9b1 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -316,11 +316,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
if ((stream.CodecTag ?? string.Empty).IndexOf("xvid", StringComparison.OrdinalIgnoreCase) != -1)
{
- codec = "xvid;";
+ codec = "xvid";
}
else if ((stream.CodecTag ?? string.Empty).IndexOf("divx", StringComparison.OrdinalIgnoreCase) != -1)
{
- codec = "divx;";
+ codec = "divx";
}
writer.WriteElementString("codec", codec);
@@ -846,7 +846,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
AddUserData(item, writer, userManager, userDataRepo, options);
- AddActors(people, writer, libraryManager, fileSystem, config);
+ AddActors(people, writer, libraryManager, fileSystem, config, options.SaveImagePathsInNfo);
var folder = item as BoxSet;
if (folder != null)
@@ -974,7 +974,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
writer.WriteEndElement();
}
- private static void AddActors(List people, XmlWriter writer, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config)
+ private static void AddActors(List people, XmlWriter writer, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config, bool saveImagePath)
{
var actors = people
.Where(i => !IsPersonType(i, PersonType.Director) && !IsPersonType(i, PersonType.Writer))
@@ -1004,20 +1004,23 @@ namespace MediaBrowser.XbmcMetadata.Savers
writer.WriteElementString("sortorder", person.SortOrder.Value.ToString(UsCulture));
}
- try
+ if (saveImagePath)
{
- var personEntity = libraryManager.GetPerson(person.Name);
- var image = personEntity.GetImageInfo(ImageType.Primary, 0);
+ try
+ {
+ var personEntity = libraryManager.GetPerson(person.Name);
+ var image = personEntity.GetImageInfo(ImageType.Primary, 0);
- if (image != null)
+ if (image != null)
+ {
+ writer.WriteElementString("thumb", GetImagePathToSave(image, libraryManager, config));
+ }
+ }
+ catch (Exception)
{
- writer.WriteElementString("thumb", GetImagePathToSave(image, libraryManager, config));
+ // Already logged in core
}
}
- catch (Exception)
- {
- // Already logged in core
- }
writer.WriteEndElement();
}
diff --git a/Mono.Nat/Pmp/PmpNatDevice.cs b/Mono.Nat/Pmp/PmpNatDevice.cs
index 93007cb8af..10ebbdc2cc 100644
--- a/Mono.Nat/Pmp/PmpNatDevice.cs
+++ b/Mono.Nat/Pmp/PmpNatDevice.cs
@@ -136,34 +136,36 @@ namespace Mono.Nat.Pmp
{
while (!cancellationToken.IsCancellationRequested)
{
- var result = await udpClient.ReceiveAsync().ConfigureAwait(false);
- var endPoint = result.RemoteEndPoint;
- byte[] data = data = result.Buffer;
+ try
+ {
+ var result = await udpClient.ReceiveAsync().ConfigureAwait(false);
+ var endPoint = result.RemoteEndPoint;
+ byte[] data = data = result.Buffer;
- if (data.Length < 16)
- continue;
+ if (data.Length < 16)
+ continue;
- if (data[0] != PmpConstants.Version)
- continue;
+ if (data[0] != PmpConstants.Version)
+ continue;
- var opCode = (byte)(data[1] & 127);
+ var opCode = (byte)(data[1] & 127);
- var protocol = Protocol.Tcp;
- if (opCode == PmpConstants.OperationCodeUdp)
- protocol = Protocol.Udp;
+ var protocol = Protocol.Tcp;
+ if (opCode == PmpConstants.OperationCodeUdp)
+ protocol = Protocol.Udp;
- short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
- int epoch = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
+ short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
+ int epoch = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
- short privatePort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 8));
- short publicPort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10));
+ short privatePort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 8));
+ short publicPort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10));
- var lifetime = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 12));
+ var lifetime = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 12));
- if (privatePort < 0 || publicPort < 0 || resultCode != PmpConstants.ResultCodeSuccess)
- {
- var errors = new[]
- {
+ if (privatePort < 0 || publicPort < 0 || resultCode != PmpConstants.ResultCodeSuccess)
+ {
+ var errors = new[]
+ {
"Success",
"Unsupported Version",
"Not Authorized/Refused (e.g. box supports mapping, but user has turned feature off)"
@@ -173,19 +175,25 @@ namespace Mono.Nat.Pmp
"Unsupported opcode"
};
- var errorMsg = errors[resultCode];
- NatUtility.Log("Error in CreatePortMapListen: " + errorMsg);
- return;
- }
+ var errorMsg = errors[resultCode];
+ NatUtility.Log("Error in CreatePortMapListen: " + errorMsg);
+ return;
+ }
- if (lifetime == 0) return; //mapping was deleted
+ if (lifetime == 0) return; //mapping was deleted
- //mapping was created
- //TODO: verify that the private port+protocol are a match
- mapping.PublicPort = publicPort;
- mapping.Protocol = protocol;
- mapping.Expiration = DateTime.Now.AddSeconds(lifetime);
- return;
+ //mapping was created
+ //TODO: verify that the private port+protocol are a match
+ mapping.PublicPort = publicPort;
+ mapping.Protocol = protocol;
+ mapping.Expiration = DateTime.Now.AddSeconds(lifetime);
+ return;
+ }
+ catch (Exception ex)
+ {
+ NatUtility.Logger.ErrorException("Error in CreatePortMapListen", ex);
+ return;
+ }
}
}
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 6b58957204..4bb58cd73f 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.692
+ 3.0.694
Emby.Common
Emby Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 36ff962261..c475a4c912 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.692
+ 3.0.694
Emby.Server.Core
Emby Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Emby Server.
Copyright © Emby 2013
-
+
diff --git a/OpenSubtitlesHandler/Utilities.cs b/OpenSubtitlesHandler/Utilities.cs
index c012da462d..f8cfa5c4fb 100644
--- a/OpenSubtitlesHandler/Utilities.cs
+++ b/OpenSubtitlesHandler/Utilities.cs
@@ -37,8 +37,8 @@ namespace OpenSubtitlesHandler
public static IHttpClient HttpClient { get; set; }
public static ITextEncoding EncodingHelper { get; set; }
- //private static string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc";
- private static string XML_RPC_SERVER = "https://92.240.234.122/xml-rpc";
+ private static string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc";
+ //private static string XML_RPC_SERVER = "https://92.240.234.122/xml-rpc";
private static string HostHeader = "api.opensubtitles.org:443";
///
diff --git a/RSSDP/DeviceAvailableEventArgs.cs b/RSSDP/DeviceAvailableEventArgs.cs
index 39f07e1d75..046c10524f 100644
--- a/RSSDP/DeviceAvailableEventArgs.cs
+++ b/RSSDP/DeviceAvailableEventArgs.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using MediaBrowser.Model.Net;
namespace Rssdp
{
@@ -11,10 +12,11 @@ namespace Rssdp
///
public sealed class DeviceAvailableEventArgs : EventArgs
{
+ public IpAddressInfo LocalIpAddress { get; set; }
- #region Fields
+ #region Fields
- private readonly DiscoveredSsdpDevice _DiscoveredDevice;
+ private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _IsNewlyDiscovered;
#endregion
diff --git a/RSSDP/ResponseReceivedEventArgs.cs b/RSSDP/ResponseReceivedEventArgs.cs
index f7dc5813d9..c983fa204a 100644
--- a/RSSDP/ResponseReceivedEventArgs.cs
+++ b/RSSDP/ResponseReceivedEventArgs.cs
@@ -15,9 +15,11 @@ namespace Rssdp.Infrastructure
public sealed class ResponseReceivedEventArgs : EventArgs
{
- #region Fields
+ public IpAddressInfo LocalIpAddress { get; set; }
- private readonly HttpResponseMessage _Message;
+ #region Fields
+
+ private readonly HttpResponseMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
#endregion
diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs
index 97f5ebbd06..c4959c1f2d 100644
--- a/RSSDP/SsdpCommunicationsServer.cs
+++ b/RSSDP/SsdpCommunicationsServer.cs
@@ -454,7 +454,7 @@ namespace Rssdp.Infrastructure
}
if (responseMessage != null)
- OnResponseReceived(responseMessage, endPoint);
+ OnResponseReceived(responseMessage, endPoint, receivedOnLocalIpAddress);
}
else
{
@@ -490,11 +490,14 @@ namespace Rssdp.Infrastructure
handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress));
}
- private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint)
+ private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint, IpAddressInfo localIpAddress)
{
var handlers = this.ResponseReceived;
if (handlers != null)
- handlers(this, new ResponseReceivedEventArgs(data, endPoint));
+ handlers(this, new ResponseReceivedEventArgs(data, endPoint)
+ {
+ LocalIpAddress = localIpAddress
+ });
}
#endregion
diff --git a/RSSDP/SsdpDeviceLocatorBase.cs b/RSSDP/SsdpDeviceLocatorBase.cs
index b6276e4997..60a792425d 100644
--- a/RSSDP/SsdpDeviceLocatorBase.cs
+++ b/RSSDP/SsdpDeviceLocatorBase.cs
@@ -7,6 +7,7 @@ using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
using RSSDP;
@@ -163,7 +164,7 @@ namespace Rssdp.Infrastructure
{
foreach (var device in GetUnexpiredDevices().Where(NotificationTypeMatchesFilter))
{
- DeviceFound(device, false);
+ DeviceFound(device, false, null);
}
}
@@ -237,16 +238,17 @@ namespace Rssdp.Infrastructure
///
/// Raises the event.
///
- /// A representing the device that is now available.
- /// True if the device was not currently in the cahce before this event was raised.
///
- protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice)
+ protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress)
{
if (this.IsDisposed) return;
var handlers = this.DeviceAvailable;
if (handlers != null)
- handlers(this, new DeviceAvailableEventArgs(device, isNewDevice));
+ handlers(this, new DeviceAvailableEventArgs(device, isNewDevice)
+ {
+ LocalIpAddress = localIpAddress
+ });
}
///
@@ -335,7 +337,7 @@ namespace Rssdp.Infrastructure
#region Discovery/Device Add
- private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device)
+ private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IpAddressInfo localIpAddress)
{
bool isNewDevice = false;
lock (_Devices)
@@ -353,10 +355,10 @@ namespace Rssdp.Infrastructure
}
}
- DeviceFound(device, isNewDevice);
+ DeviceFound(device, isNewDevice, localIpAddress);
}
- private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice)
+ private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress)
{
// Don't raise the event if we've already done it for a cached
// version of this device, and the cached version isn't
@@ -391,7 +393,7 @@ namespace Rssdp.Infrastructure
}
if (raiseEvent)
- OnDeviceAvailable(device, isNewDevice);
+ OnDeviceAvailable(device, isNewDevice, localIpAddress);
}
private bool NotificationTypeMatchesFilter(DiscoveredSsdpDevice device)
@@ -428,7 +430,7 @@ namespace Rssdp.Infrastructure
return _CommunicationsServer.SendMulticastMessage(message);
}
- private void ProcessSearchResponseMessage(HttpResponseMessage message)
+ private void ProcessSearchResponseMessage(HttpResponseMessage message, IpAddressInfo localIpAddress)
{
if (!message.IsSuccessStatusCode) return;
@@ -445,22 +447,22 @@ namespace Rssdp.Infrastructure
ResponseHeaders = message.Headers
};
- AddOrUpdateDiscoveredDevice(device);
+ AddOrUpdateDiscoveredDevice(device, localIpAddress);
}
}
- private void ProcessNotificationMessage(HttpRequestMessage message)
+ private void ProcessNotificationMessage(HttpRequestMessage message, IpAddressInfo localIpAddress)
{
if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) return;
var notificationType = GetFirstHeaderStringValue("NTS", message);
if (String.Compare(notificationType, SsdpConstants.SsdpKeepAliveNotification, StringComparison.OrdinalIgnoreCase) == 0)
- ProcessAliveNotification(message);
+ ProcessAliveNotification(message, localIpAddress);
else if (String.Compare(notificationType, SsdpConstants.SsdpByeByeNotification, StringComparison.OrdinalIgnoreCase) == 0)
ProcessByeByeNotification(message);
}
- private void ProcessAliveNotification(HttpRequestMessage message)
+ private void ProcessAliveNotification(HttpRequestMessage message, IpAddressInfo localIpAddress)
{
var location = GetFirstHeaderUriValue("Location", message);
if (location != null)
@@ -475,7 +477,7 @@ namespace Rssdp.Infrastructure
ResponseHeaders = message.Headers
};
- AddOrUpdateDiscoveredDevice(device);
+ AddOrUpdateDiscoveredDevice(device, localIpAddress);
ResetExpireCachedDevicesTimer();
}
@@ -702,12 +704,12 @@ namespace Rssdp.Infrastructure
private void CommsServer_ResponseReceived(object sender, ResponseReceivedEventArgs e)
{
- ProcessSearchResponseMessage(e.Message);
+ ProcessSearchResponseMessage(e.Message, e.LocalIpAddress);
}
private void CommsServer_RequestReceived(object sender, RequestReceivedEventArgs e)
{
- ProcessNotificationMessage(e.Message);
+ ProcessNotificationMessage(e.Message, e.LocalIpAddress);
}
#endregion
diff --git a/RSSDP/SsdpDevicePublisherBase.cs b/RSSDP/SsdpDevicePublisherBase.cs
index 2543632b6b..c0ae3955dc 100644
--- a/RSSDP/SsdpDevicePublisherBase.cs
+++ b/RSSDP/SsdpDevicePublisherBase.cs
@@ -245,7 +245,7 @@ namespace Rssdp.Infrastructure
return;
}
- WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget));
+ //WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget));
if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint))
{
diff --git a/src/Emby.Server/Program.cs b/src/Emby.Server/Program.cs
index 26141a0ce9..fde2ab7b2e 100644
--- a/src/Emby.Server/Program.cs
+++ b/src/Emby.Server/Program.cs
@@ -193,7 +193,7 @@ namespace Emby.Server
/// The options.
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options, EnvironmentInfo environmentInfo)
{
- var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
+ var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true, appPaths.TempDirectory);
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
diff --git a/src/Emby.Server/project.json b/src/Emby.Server/project.json
index e77506e927..83c9ce876e 100644
--- a/src/Emby.Server/project.json
+++ b/src/Emby.Server/project.json
@@ -1,5 +1,5 @@
{
- "version": "3.1.0-*",
+ "version": "3.1.0.1",
"buildOptions": {
"emitEntryPoint": true
},