Merge pull request #3047 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-11-29 15:51:07 -05:00 committed by GitHub
commit 82254bd3c4
15 changed files with 328 additions and 92 deletions

View File

@ -393,6 +393,7 @@ namespace Emby.Server.Implementations
ISystemEvents systemEvents, ISystemEvents systemEvents,
INetworkManager networkManager) INetworkManager networkManager)
{ {
// hack alert, until common can target .net core // hack alert, until common can target .net core
BaseExtensions.CryptographyProvider = CryptographyProvider; BaseExtensions.CryptographyProvider = CryptographyProvider;
@ -423,6 +424,13 @@ namespace Emby.Server.Implementations
SetBaseExceptionMessage(); SetBaseExceptionMessage();
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
NetworkManager.NetworkChanged += NetworkManager_NetworkChanged;
}
private void NetworkManager_NetworkChanged(object sender, EventArgs e)
{
_validAddressResults.Clear();
} }
private Version _version; private Version _version;
@ -1960,9 +1968,9 @@ namespace Emby.Server.Implementations
try try
{ {
// Return the first matched address, if found, or the first known local address // Return the first matched address, if found, or the first known local address
var address = (await GetLocalIpAddresses(cancellationToken).ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false);
if (address != null) foreach (var address in addresses)
{ {
return GetLocalApiUrl(address); return GetLocalApiUrl(address);
} }
@ -1994,7 +2002,12 @@ namespace Emby.Server.Implementations
HttpPort.ToString(CultureInfo.InvariantCulture)); HttpPort.ToString(CultureInfo.InvariantCulture));
} }
public async Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken) public Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken)
{
return GetLocalIpAddressesInternal(true, 0, cancellationToken);
}
private async Task<List<IpAddressInfo>> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken)
{ {
var addresses = ServerConfigurationManager var addresses = ServerConfigurationManager
.Configuration .Configuration
@ -2006,22 +2019,33 @@ namespace Emby.Server.Implementations
if (addresses.Count == 0) if (addresses.Count == 0)
{ {
addresses.AddRange(NetworkManager.GetLocalIpAddresses()); addresses.AddRange(NetworkManager.GetLocalIpAddresses());
}
var list = new List<IpAddressInfo>(); var resultList = new List<IpAddressInfo>();
foreach (var address in addresses) foreach (var address in addresses)
{
if (!allowLoopback)
{ {
var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback))
if (valid)
{ {
list.Add(address); continue;
} }
} }
addresses = list; var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
if (valid)
{
resultList.Add(address);
if (limit > 0 && resultList.Count >= limit)
{
return resultList;
}
}
} }
return addresses; return resultList;
} }
private IpAddressInfo NormalizeConfiguredLocalAddress(string address) private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
@ -2042,7 +2066,6 @@ namespace Emby.Server.Implementations
} }
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private DateTime _lastAddressCacheClear;
private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken) private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken)
{ {
if (address.Equals(IpAddressInfo.Loopback) || if (address.Equals(IpAddressInfo.Loopback) ||
@ -2054,12 +2077,6 @@ namespace Emby.Server.Implementations
var apiUrl = GetLocalApiUrl(address); var apiUrl = GetLocalApiUrl(address);
apiUrl += "/system/ping"; apiUrl += "/system/ping";
if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15)
{
_lastAddressCacheClear = DateTime.UtcNow;
_validAddressResults.Clear();
}
bool cachedResult; bool cachedResult;
if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
{ {
@ -2087,18 +2104,19 @@ namespace Emby.Server.Implementations
var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase);
_validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid);
//Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
return valid; return valid;
} }
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, "Cancelled");
throw; throw;
} }
catch catch
{ {
//Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
_validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false); _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false);
return false; return false;

View File

@ -4286,7 +4286,7 @@ namespace Emby.Server.Implementations.Data
if (query.MinParentalRating.HasValue) if (query.MinParentalRating.HasValue)
{ {
whereClauses.Add("InheritedParentalRatingValue<=@MinParentalRating"); whereClauses.Add("InheritedParentalRatingValue>=@MinParentalRating");
if (statement != null) if (statement != null)
{ {
statement.TryBind("@MinParentalRating", query.MinParentalRating.Value); statement.TryBind("@MinParentalRating", query.MinParentalRating.Value);

View File

@ -708,6 +708,8 @@
<EmbeddedResource Include="Localization\Core\zh-CN.json" /> <EmbeddedResource Include="Localization\Core\zh-CN.json" />
<EmbeddedResource Include="Localization\Core\zh-HK.json" /> <EmbeddedResource Include="Localization\Core\zh-HK.json" />
<EmbeddedResource Include="Localization\Core\en-US.json" /> <EmbeddedResource Include="Localization\Core\en-US.json" />
<EmbeddedResource Include="Localization\Core\el.json" />
<EmbeddedResource Include="Localization\Core\gsw.json" />
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="TextEncoding\NLangDetect\Profiles\afr" /> <None Include="TextEncoding\NLangDetect\Profiles\afr" />
<None Include="TextEncoding\NLangDetect\Profiles\ara" /> <None Include="TextEncoding\NLangDetect\Profiles\ara" />

View File

@ -17,6 +17,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using System.IO;
namespace Emby.Server.Implementations.LiveTv.TunerHosts namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
@ -75,6 +76,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list); return Task.FromResult(list);
} }
private string[] _disallowedSharedStreamExtensions = new string[]
{
".mkv",
".mp4",
".m3u8",
".mpd"
};
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
{ {
var tunerCount = info.TunerCount; var tunerCount = info.TunerCount;
@ -95,7 +104,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping) if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
{ {
return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); var extension = Path.GetExtension(mediaSource.Path) ?? string.Empty;
if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
}
} }
return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths); return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths);

View File

@ -71,7 +71,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
} }
else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 || else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1) contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1)
{ {
requiresRemux = true; requiresRemux = true;
} }

View File

@ -1,74 +1,74 @@
{ {
"Latest": "Darreres", "Latest": "Darreres",
"ValueSpecialEpisodeName": "Especial - {0}", "ValueSpecialEpisodeName": "Especial - {0}",
"Inherit": "Inherit", "Inherit": "Heretat",
"Books": "Books", "Books": "Llibres",
"Music": "Music", "Music": "M\u00fasica",
"Games": "Games", "Games": "Jocs",
"Photos": "Photos", "Photos": "Fotos",
"MixedContent": "Mixed content", "MixedContent": "Contingut mesclat",
"MusicVideos": "Music videos", "MusicVideos": "V\u00eddeos musicals",
"HomeVideos": "Home videos", "HomeVideos": "V\u00eddeos dom\u00e8stics",
"Playlists": "Playlists", "Playlists": "Llistes de reproducci\u00f3",
"HeaderRecordingGroups": "Recording Groups", "HeaderRecordingGroups": "Grups d'Enregistrament",
"HeaderContinueWatching": "Continua Veient", "HeaderContinueWatching": "Continua Veient",
"HeaderFavoriteArtists": "Favorite Artists", "HeaderFavoriteArtists": "Artistes Preferits",
"HeaderFavoriteSongs": "Favorite Songs", "HeaderFavoriteSongs": "Can\u00e7ons Preferides",
"HeaderAlbumArtists": "Album Artists", "HeaderAlbumArtists": "Album Artists",
"HeaderFavoriteAlbums": "Favorite Albums", "HeaderFavoriteAlbums": "\u00c0lbums Preferits",
"HeaderFavoriteEpisodes": "Favorite Episodes", "HeaderFavoriteEpisodes": "Episodis Preferits",
"HeaderFavoriteShows": "Programes Preferits", "HeaderFavoriteShows": "Programes Preferits",
"HeaderNextUp": "A continuaci\u00f3", "HeaderNextUp": "A continuaci\u00f3",
"Favorites": "Favorites", "Favorites": "Preferits",
"Collections": "Collections", "Collections": "Col\u00b7leccions",
"Channels": "Channels", "Channels": "Canals",
"Movies": "Movies", "Movies": "Pel\u00b7l\u00edcules",
"Albums": "Albums", "Albums": "\u00c0lbums",
"Artists": "Artists", "Artists": "Artistes",
"Folders": "Folders", "Folders": "Directoris",
"Songs": "Songs", "Songs": "Can\u00e7ons",
"TvShows": "TV Shows", "TvShows": "Espectacles de TV",
"Shows": "Shows", "Shows": "Espectacles",
"Genres": "G\u00e8neres", "Genres": "G\u00e8neres",
"NameSeasonNumber": "Season {0}", "NameSeasonNumber": "Temporada {0}",
"AppDeviceValues": "App: {0}, Device: {1}", "AppDeviceValues": "App: {0}, Dispositiu: {1}",
"UserDownloadingItemWithValues": "{0} is downloading {1}", "UserDownloadingItemWithValues": "{0} est\u00e0 descarregant {1}",
"HeaderLiveTV": "Live TV", "HeaderLiveTV": "TV en Directe",
"ChapterNameValue": "Chapter {0}", "ChapterNameValue": "Episodi {0}",
"ScheduledTaskFailedWithName": "{0} failed", "ScheduledTaskFailedWithName": "{0} ha fallat",
"LabelRunningTimeValue": "Running time: {0}", "LabelRunningTimeValue": "Temps en marxa: {0}",
"ScheduledTaskStartedWithName": "{0} started", "ScheduledTaskStartedWithName": "{0} iniciat",
"VersionNumber": "Version {0}", "VersionNumber": "Versi\u00f3 {0}",
"PluginInstalledWithName": "{0} was installed", "PluginInstalledWithName": "{0} ha estat instal\u00b7lat",
"StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.", "StartupEmbyServerIsLoading": "El Servidor d'Emby est&agrave; carregant. Si et plau, prova de nou en breus.",
"PluginUpdatedWithName": "{0} was updated", "PluginUpdatedWithName": "{0} ha estat actualitzat",
"PluginUninstalledWithName": "{0} was uninstalled", "PluginUninstalledWithName": "{0} ha estat desinstal\u00b7lat",
"ItemAddedWithName": "{0} was added to the library", "ItemAddedWithName": "{0} afegit a la biblioteca",
"ItemRemovedWithName": "{0} was removed from the library", "ItemRemovedWithName": "{0} eliminat de la biblioteca",
"LabelIpAddressValue": "Ip address: {0}", "LabelIpAddressValue": "Adre\u00e7a IP: {0}",
"DeviceOnlineWithName": "{0} is connected", "DeviceOnlineWithName": "{0} est\u00e0 connectat",
"UserOnlineFromDevice": "{0} is online from {1}", "UserOnlineFromDevice": "{0} est\u00e0 connectat des de {1}",
"ProviderValue": "Provider: {0}", "ProviderValue": "Prove\u00efdor: {0}",
"SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", "SubtitlesDownloadedForItem": "Subt\u00edtols descarregats per a {0}",
"UserCreatedWithName": "User {0} has been created", "UserCreatedWithName": "S'ha creat l'usuari {0}",
"UserPasswordChangedWithName": "Password has been changed for user {0}", "UserPasswordChangedWithName": "La contrasenya ha estat canviada per a l'usuari {0}",
"UserDeletedWithName": "User {0} has been deleted", "UserDeletedWithName": "L'usuari {0} ha estat eliminat",
"UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", "UserConfigurationUpdatedWithName": "La configuraci\u00f3 d'usuari ha estat actualitzada per a {0}",
"MessageServerConfigurationUpdated": "Server configuration has been updated", "MessageServerConfigurationUpdated": "S'ha actualitzat la configuraci\u00f3 del servidor",
"MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", "MessageNamedServerConfigurationUpdatedWithValue": "La secci\u00f3 de configuraci\u00f3 {0} ha estat actualitzada",
"MessageApplicationUpdated": "Emby Server has been updated", "MessageApplicationUpdated": "El Servidor d'Emby ha estat actualitzat",
"FailedLoginAttemptWithUserName": "Failed login attempt from {0}", "FailedLoginAttemptWithUserName": "Intent de connexi\u00f3 fallit des de {0}",
"AuthenticationSucceededWithUserName": "{0} successfully authenticated", "AuthenticationSucceededWithUserName": "{0} s'ha autenticat correctament",
"UserOfflineFromDevice": "{0} has disconnected from {1}", "UserOfflineFromDevice": "{0} s'ha desconnectat de {1}",
"DeviceOfflineWithName": "{0} has disconnected", "DeviceOfflineWithName": "{0} s'ha desconnectat",
"UserStartedPlayingItemWithValues": "{0} has started playing {1}", "UserStartedPlayingItemWithValues": "{0} ha comen\u00e7at a reproduir {1}",
"UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", "UserStoppedPlayingItemWithValues": "{0} ha parat de reproduir {1}",
"NotificationOptionPluginError": "Plugin failure", "NotificationOptionPluginError": "Un component ha fallat",
"NotificationOptionApplicationUpdateAvailable": "Application update available", "NotificationOptionApplicationUpdateAvailable": "Actualitzaci\u00f3 d'aplicaci\u00f3 disponible",
"NotificationOptionApplicationUpdateInstalled": "Application update installed", "NotificationOptionApplicationUpdateInstalled": "Actualitzaci\u00f3 d'aplicaci\u00f3 instal\u00b7lada",
"NotificationOptionPluginUpdateInstalled": "Plugin update installed", "NotificationOptionPluginUpdateInstalled": "Actualitzaci\u00f3 de complement instal\u00b7lada",
"NotificationOptionPluginInstalled": "Plugin installed", "NotificationOptionPluginInstalled": "Complement instal\u00b7lat",
"NotificationOptionPluginUninstalled": "Plugin uninstalled", "NotificationOptionPluginUninstalled": "Complement desinstal\u00b7lat",
"NotificationOptionVideoPlayback": "Video playback started", "NotificationOptionVideoPlayback": "Video playback started",
"NotificationOptionAudioPlayback": "Audio playback started", "NotificationOptionAudioPlayback": "Audio playback started",
"NotificationOptionGamePlayback": "Game playback started", "NotificationOptionGamePlayback": "Game playback started",

View File

@ -7,7 +7,7 @@
"Games": "Spiele", "Games": "Spiele",
"Photos": "Fotos", "Photos": "Fotos",
"MixedContent": "Gemischte Inhalte", "MixedContent": "Gemischte Inhalte",
"MusicVideos": "Musik-Videos", "MusicVideos": "Musikvideos",
"HomeVideos": "Heimvideos", "HomeVideos": "Heimvideos",
"Playlists": "Wiedergabelisten", "Playlists": "Wiedergabelisten",
"HeaderRecordingGroups": "Aufnahme-Gruppen", "HeaderRecordingGroups": "Aufnahme-Gruppen",
@ -27,7 +27,7 @@
"Artists": "Interpreten", "Artists": "Interpreten",
"Folders": "Verzeichnisse", "Folders": "Verzeichnisse",
"Songs": "Songs", "Songs": "Songs",
"TvShows": "TV Shows", "TvShows": "TV Sendungen",
"Shows": "Serien", "Shows": "Serien",
"Genres": "Genres", "Genres": "Genres",
"NameSeasonNumber": "Staffel {0}", "NameSeasonNumber": "Staffel {0}",

View File

@ -0,0 +1,91 @@
{
"Latest": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1",
"ValueSpecialEpisodeName": "\u0395\u03b9\u03b4\u03b9\u03ba\u03ac - {0} ",
"Inherit": "Inherit",
"Books": "\u0392\u03b9\u03b2\u03bb\u03af\u03b1",
"Music": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae",
"Games": "\u03a0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9\u03b1",
"Photos": "\u03a6\u03c9\u03c4\u03bf\u03b3\u03c1\u03b1\u03c6\u03af\u03b5\u03c2",
"MixedContent": "\u0391\u03bd\u03ac\u03bc\u03b5\u03b9\u03ba\u03c4\u03bf \u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf",
"MusicVideos": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ac \u03b2\u03af\u03bd\u03c4\u03b5\u03bf",
"HomeVideos": "\u03a0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03ac \u0392\u03af\u03bd\u03c4\u03b5\u03bf",
"Playlists": "\u039b\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2",
"HeaderRecordingGroups": "\u0393\u03ba\u03c1\u03bf\u03c5\u03c0 \u0395\u03b3\u03b3\u03c1\u03b1\u03c6\u03ce\u03bd",
"HeaderContinueWatching": "\u03a3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b7",
"HeaderFavoriteArtists": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03bf\u03b9 \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2",
"HeaderFavoriteSongs": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1",
"HeaderAlbumArtists": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03b5\u03c7\u03bd\u03ce\u03bd",
"HeaderFavoriteAlbums": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc",
"HeaderFavoriteEpisodes": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03b5\u03c0\u03b5\u03b9\u03c3\u03cc\u03b4\u03b9\u03b1",
"HeaderFavoriteShows": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a3\u03b5\u03b9\u03c1\u03ad\u03c2",
"HeaderNextUp": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf",
"Favorites": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1",
"Collections": "\u03a3\u03c5\u03bb\u03bb\u03bf\u03b3\u03ad\u03c2",
"Channels": "\u039a\u03b1\u03bd\u03ac\u03bb\u03b9\u03b1",
"Movies": "\u03a4\u03b1\u03b9\u03bd\u03af\u03b5\u03c2",
"Albums": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc",
"Artists": "\u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2",
"Folders": "\u03a6\u03ac\u03ba\u03b5\u03bb\u03bf\u03b9",
"Songs": "\u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1",
"TvShows": "\u03a4\u03b7\u03bb\u03b5\u03bf\u03c0\u03c4\u03b9\u03ba\u03ac \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03b1",
"Shows": "\u03a3\u03b5\u03b9\u03c1\u03ad\u03c2",
"Genres": "\u0395\u03af\u03b4\u03b7",
"NameSeasonNumber": "\u039a\u03cd\u03ba\u03bb\u03bf\u03c2 {0}",
"AppDeviceValues": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae: {0}, \u03a3\u03c5\u03c3\u03ba\u03b5\u03c5\u03ae: {1}",
"UserDownloadingItemWithValues": "{0} \u03ba\u03b1\u03c4\u03b5\u03b2\u03ac\u03b6\u03b5\u03b9 {1}",
"HeaderLiveTV": "\u0396\u03c9\u03bd\u03c4\u03b1\u03bd\u03ae \u03a4\u03b7\u03bb\u03b5\u03cc\u03c1\u03b1\u03c3\u03b7",
"ChapterNameValue": "\u039a\u03b5\u03c6\u03ac\u03bb\u03b1\u03b9\u03bf {0}",
"ScheduledTaskFailedWithName": "{0} \u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1",
"LabelRunningTimeValue": "\u0394\u03b9\u03ac\u03c1\u03ba\u03b5\u03b9\u03b1: {0}",
"ScheduledTaskStartedWithName": "{0} \u03ad\u03bd\u03b1\u03c1\u03be\u03b7",
"VersionNumber": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 {0}",
"PluginInstalledWithName": "{0} \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03b8\u03b7\u03ba\u03b5",
"StartupEmbyServerIsLoading": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03c6\u03bf\u03c1\u03c4\u03ce\u03bd\u03b5\u03b9. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03c3\u03b5 \u03bb\u03af\u03b3\u03bf",
"PluginUpdatedWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af",
"PluginUninstalledWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03b1\u03b8\u03b5\u03af",
"ItemAddedWithName": "{0} \u03c0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03c3\u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7",
"ItemRemovedWithName": "{0} \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c6\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc \u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7",
"LabelIpAddressValue": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 IP: {0}",
"DeviceOnlineWithName": "{0} \u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5",
"UserOnlineFromDevice": "{0} \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2 \u03b1\u03c0\u03bf {1}",
"ProviderValue": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2: {0}",
"SubtitlesDownloadedForItem": "\u03a5\u03c0\u03cc\u03c4\u03b9\u03c4\u03bb\u03bf\u03b9 \u03bb\u03ae\u03c6\u03b8\u03b7\u03ba\u03b1\u03bd \u03b1\u03c0\u03cc {0}",
"UserCreatedWithName": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03bf \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0}",
"UserPasswordChangedWithName": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03b1\u03bb\u03bb\u03ac\u03c7\u03b8\u03b7\u03ba\u03b5",
"UserDeletedWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b4\u03b9\u03b5\u03b3\u03c1\u03ac\u03c6\u03b5\u03b9",
"UserConfigurationUpdatedWithName": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9",
"MessageServerConfigurationUpdated": "Server configuration has been updated",
"MessageNamedServerConfigurationUpdatedWithValue": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03bc\u03ad\u03b1 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9",
"MessageApplicationUpdated": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af",
"FailedLoginAttemptWithUserName": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b5\u03b9\u03b1 \u03b5\u03b9\u03c3\u03cc\u03b4\u03bf\u03c5 \u03b1\u03c0\u03cc {0}",
"AuthenticationSucceededWithUserName": "{0} \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03b5\u03af\u03c2 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7",
"UserOfflineFromDevice": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc {1}",
"DeviceOfflineWithName": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5",
"UserStartedPlayingItemWithValues": "{0} \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}",
"UserStoppedPlayingItemWithValues": "{0} \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}",
"NotificationOptionPluginError": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c4\u03bf\u03c5",
"NotificationOptionApplicationUpdateAvailable": "\u03a5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7",
"NotificationOptionApplicationUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5",
"NotificationOptionPluginUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03bf\u03c5 plugin \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5",
"NotificationOptionPluginInstalled": "\u03a4\u03bf plugin \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5",
"NotificationOptionPluginUninstalled": "\u03a4\u03bf plugin \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5",
"NotificationOptionVideoPlayback": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c0\u03c1\u03bf\u03b2\u03ac\u03bb\u03bb\u03b5\u03c4\u03b1\u03b9",
"NotificationOptionAudioPlayback": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c0\u03b1\u03af\u03b6\u03b5\u03b9",
"NotificationOptionGamePlayback": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5",
"NotificationOptionVideoPlaybackStopped": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
"NotificationOptionAudioPlaybackStopped": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
"NotificationOptionGamePlaybackStopped": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5",
"NotificationOptionTaskFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7\u03c2 \u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2",
"NotificationOptionInstallationFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03b5\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2",
"NotificationOptionNewLibraryContent": "\u03a0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03bd\u03ad\u03bf \u03c0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf",
"NotificationOptionCameraImageUploaded": "Camera image uploaded",
"NotificationOptionUserLockedOut": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5",
"NotificationOptionServerRestartRequired": "\u0391\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b5\u03c0\u03b1\u03bd\u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae",
"UserLockedOutWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5",
"SubtitleDownloadFailureForItem": "\u0391\u03b4\u03c5\u03bd\u03b1\u03bc\u03af\u03b1 \u03bb\u03ae\u03c8\u03b7\u03c2 \u03c5\u03c0\u03bf\u03c4\u03af\u03c4\u03bb\u03c9\u03bd \u03b1\u03c0\u03cc {0}",
"Sync": "\u03a3\u03c5\u03b3\u03c7\u03c1\u03bf\u03bd\u03b9\u03c3\u03bc\u03cc\u03c2",
"User": "\u03a7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2",
"System": "\u03a3\u03cd\u03c3\u03c4\u03b7\u03bc\u03b1",
"Application": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae",
"Plugin": "\u03a0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c4\u03bf"
}

View File

@ -83,7 +83,7 @@
"NotificationOptionServerRestartRequired": "Se necesita reiniciar el Servidor", "NotificationOptionServerRestartRequired": "Se necesita reiniciar el Servidor",
"UserLockedOutWithName": "El usuario {0} ha sido bloqueado", "UserLockedOutWithName": "El usuario {0} ha sido bloqueado",
"SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}", "SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}",
"Sync": "Sinc.", "Sync": "Sincronizar",
"User": "Usuario", "User": "Usuario",
"System": "Sistema", "System": "Sistema",
"Application": "Aplicaci\u00f3n", "Application": "Aplicaci\u00f3n",

View File

@ -0,0 +1,91 @@
{
"Latest": "Letschte",
"ValueSpecialEpisodeName": "Spezial - {0}",
"Inherit": "Hinzuef\u00fcege",
"Books": "B\u00fcecher",
"Music": "Musig",
"Games": "Spiel",
"Photos": "Fotis",
"MixedContent": "Gmischte Inhalt",
"MusicVideos": "Musigfilm",
"HomeVideos": "Heimfilmli",
"Playlists": "Abspielliste",
"HeaderRecordingGroups": "Ufnahmegruppe",
"HeaderContinueWatching": "Wiiterluege",
"HeaderFavoriteArtists": "Besti Interpret",
"HeaderFavoriteSongs": "Besti Lieder",
"HeaderAlbumArtists": "Albuminterprete",
"HeaderFavoriteAlbums": "Favorite Albums",
"HeaderFavoriteEpisodes": "Favorite Episodes",
"HeaderFavoriteShows": "Favorite Shows",
"HeaderNextUp": "Next Up",
"Favorites": "Favorites",
"Collections": "Collections",
"Channels": "Channels",
"Movies": "Movies",
"Albums": "Albums",
"Artists": "Artists",
"Folders": "Folders",
"Songs": "Songs",
"TvShows": "TV Shows",
"Shows": "Shows",
"Genres": "Genres",
"NameSeasonNumber": "Season {0}",
"AppDeviceValues": "App: {0}, Device: {1}",
"UserDownloadingItemWithValues": "{0} is downloading {1}",
"HeaderLiveTV": "Live TV",
"ChapterNameValue": "Chapter {0}",
"ScheduledTaskFailedWithName": "{0} failed",
"LabelRunningTimeValue": "Running time: {0}",
"ScheduledTaskStartedWithName": "{0} started",
"VersionNumber": "Version {0}",
"PluginInstalledWithName": "{0} was installed",
"StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.",
"PluginUpdatedWithName": "{0} was updated",
"PluginUninstalledWithName": "{0} was uninstalled",
"ItemAddedWithName": "{0} was added to the library",
"ItemRemovedWithName": "{0} was removed from the library",
"LabelIpAddressValue": "Ip address: {0}",
"DeviceOnlineWithName": "{0} is connected",
"UserOnlineFromDevice": "{0} is online from {1}",
"ProviderValue": "Provider: {0}",
"SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
"UserCreatedWithName": "User {0} has been created",
"UserPasswordChangedWithName": "Password has been changed for user {0}",
"UserDeletedWithName": "User {0} has been deleted",
"UserConfigurationUpdatedWithName": "User configuration has been updated for {0}",
"MessageServerConfigurationUpdated": "Server configuration has been updated",
"MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
"MessageApplicationUpdated": "Emby Server has been updated",
"FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
"AuthenticationSucceededWithUserName": "{0} successfully authenticated",
"UserOfflineFromDevice": "{0} has disconnected from {1}",
"DeviceOfflineWithName": "{0} has disconnected",
"UserStartedPlayingItemWithValues": "{0} has started playing {1}",
"UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
"NotificationOptionPluginError": "Plugin failure",
"NotificationOptionApplicationUpdateAvailable": "Application update available",
"NotificationOptionApplicationUpdateInstalled": "Application update installed",
"NotificationOptionPluginUpdateInstalled": "Plugin update installed",
"NotificationOptionPluginInstalled": "Plugin installed",
"NotificationOptionPluginUninstalled": "Plugin uninstalled",
"NotificationOptionVideoPlayback": "Video playback started",
"NotificationOptionAudioPlayback": "Audio playback started",
"NotificationOptionGamePlayback": "Game playback started",
"NotificationOptionVideoPlaybackStopped": "Video playback stopped",
"NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
"NotificationOptionGamePlaybackStopped": "Game playback stopped",
"NotificationOptionTaskFailed": "Scheduled task failure",
"NotificationOptionInstallationFailed": "Installation failure",
"NotificationOptionNewLibraryContent": "New content added",
"NotificationOptionCameraImageUploaded": "Camera image uploaded",
"NotificationOptionUserLockedOut": "User locked out",
"NotificationOptionServerRestartRequired": "Server restart required",
"UserLockedOutWithName": "User {0} has been locked out",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
"Sync": "Sync",
"User": "User",
"System": "System",
"Application": "Application",
"Plugin": "Plugin"
}

View File

@ -27,7 +27,7 @@
"Artists": "Artistas", "Artists": "Artistas",
"Folders": "Pastas", "Folders": "Pastas",
"Songs": "M\u00fasicas", "Songs": "M\u00fasicas",
"TvShows": "TV Shows", "TvShows": "S\u00e9ries de TV",
"Shows": "S\u00e9ries", "Shows": "S\u00e9ries",
"Genres": "G\u00eaneros", "Genres": "G\u00eaneros",
"NameSeasonNumber": "Temporada {0}", "NameSeasonNumber": "Temporada {0}",

View File

@ -19,7 +19,9 @@ namespace Emby.Server.Implementations.Networking
{ {
protected ILogger Logger { get; private set; } protected ILogger Logger { get; private set; }
private DateTime _lastRefresh; private DateTime _lastRefresh;
private int NetworkCacheMinutes = 360; private int NetworkCacheMinutes = 720;
public event EventHandler NetworkChanged;
public NetworkManager(ILogger logger) public NetworkManager(ILogger logger)
{ {
@ -50,12 +52,22 @@ namespace Emby.Server.Implementations.Networking
{ {
Logger.Debug("NetworkAvailabilityChanged"); Logger.Debug("NetworkAvailabilityChanged");
_lastRefresh = DateTime.MinValue; _lastRefresh = DateTime.MinValue;
OnNetworkChanged();
} }
private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{ {
Logger.Debug("NetworkAddressChanged"); Logger.Debug("NetworkAddressChanged");
_lastRefresh = DateTime.MinValue; _lastRefresh = DateTime.MinValue;
OnNetworkChanged();
}
private void OnNetworkChanged()
{
if (NetworkChanged != null)
{
NetworkChanged(this, EventArgs.Empty);
}
} }
private List<IpAddressInfo> _localIpAddresses; private List<IpAddressInfo> _localIpAddresses;

View File

@ -1,13 +1,15 @@
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MediaBrowser.Common.Net namespace MediaBrowser.Common.Net
{ {
public interface INetworkManager public interface INetworkManager
{ {
event EventHandler NetworkChanged;
/// <summary> /// <summary>
/// Gets a random port number that is currently available /// Gets a random port number that is currently available
/// </summary> /// </summary>

View File

@ -186,6 +186,11 @@ namespace MediaBrowser.Model.Dlna
return MediaSource.Path; return MediaSource.Path;
} }
if (string.IsNullOrWhiteSpace(PlaySessionId))
{
PlaySessionId = Guid.NewGuid().ToString("N");
}
string dlnaCommand = BuildDlnaParam(this, accessToken); string dlnaCommand = BuildDlnaParam(this, accessToken);
return GetUrl(baseUrl, dlnaCommand); return GetUrl(baseUrl, dlnaCommand);
} }

View File

@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.2.40.4")] [assembly: AssemblyVersion("3.2.40.5")]