dlna fixes

This commit is contained in:
Luke Pulverenti 2014-04-19 13:43:12 -04:00
parent 5170042eb5
commit 13509c1d8d
37 changed files with 271 additions and 57 deletions

View File

@ -196,19 +196,19 @@ namespace MediaBrowser.Controller.Entities.TV
public IEnumerable<Episode> GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
{
var episodes = GetRecursiveChildren(user)
.OfType<Episode>();
if (IndexNumber.HasValue)
{
var series = Series;
if (series != null)
{
return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes);
return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
}
}
var episodes = GetRecursiveChildren(user)
.OfType<Episode>();
if (!includeMissingEpisodes)
{
episodes = episodes.Where(i => !i.IsMissingEpisode);

View File

@ -167,12 +167,20 @@ namespace MediaBrowser.Controller.Entities.TV
}
public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
{
return GetEpisodes(user, seasonNumber, includeMissingEpisodes, includeVirtualUnairedEpisodes,
new List<Episode>());
}
internal IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> additionalEpisodes)
{
var episodes = GetRecursiveChildren(user)
.OfType<Episode>();
episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
episodes = episodes.Concat(additionalEpisodes).Distinct();
if (!includeMissingEpisodes)
{
episodes = episodes.Where(i => !i.IsMissingEpisode);

View File

@ -103,9 +103,10 @@ namespace MediaBrowser.Controller.Resolvers
".wav",
".ape",
".ogg",
".oga",
".asf",
".mp4"
".oga"
//".asf",
//".mp4"
};
private static readonly Dictionary<string, string> AudioFileExtensionsDictionary = AudioFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);

View File

@ -66,8 +66,8 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
private string _transportState = String.Empty;
public string TransportState
private TRANSPORTSTATE _transportState = TRANSPORTSTATE.STOPPED;
public TRANSPORTSTATE TransportState
{
get
{
@ -80,8 +80,7 @@ namespace MediaBrowser.Dlna.PlayTo
_transportState = value;
if (value == TRANSPORTSTATE.PLAYING || value == TRANSPORTSTATE.STOPPED)
NotifyPlaybackChanged(value == TRANSPORTSTATE.STOPPED);
NotifyPlaybackChanged(value);
}
}
@ -374,7 +373,7 @@ namespace MediaBrowser.Dlna.PlayTo
.ConfigureAwait(false);
await Task.Delay(50).ConfigureAwait(false);
TransportState = "PAUSED_PLAYBACK";
TransportState = TRANSPORTSTATE.PAUSED_PLAYBACK;
return true;
}
@ -492,7 +491,14 @@ namespace MediaBrowser.Dlna.PlayTo
var transportStateValue = transportState == null ? null : transportState.Value;
if (transportStateValue != null)
TransportState = transportStateValue;
{
TRANSPORTSTATE state;
if (Enum.TryParse(transportStateValue, true, out state))
{
TransportState = state;
}
}
UpdateTime = DateTime.UtcNow;
}
@ -857,13 +863,13 @@ namespace MediaBrowser.Dlna.PlayTo
public event EventHandler<TransportStateEventArgs> PlaybackChanged;
public event EventHandler<CurrentIdEventArgs> CurrentIdChanged;
private void NotifyPlaybackChanged(bool value)
private void NotifyPlaybackChanged(TRANSPORTSTATE state)
{
if (PlaybackChanged != null)
{
PlaybackChanged.Invoke(this, new TransportStateEventArgs
{
Stopped = IsStopped
State = state
});
}
}
@ -895,14 +901,14 @@ namespace MediaBrowser.Dlna.PlayTo
return String.Format("{0} - {1}", Properties.Name, Properties.BaseUrl);
}
private class TRANSPORTSTATE
{
public const string STOPPED = "STOPPED";
public const string PLAYING = "PLAYING";
public const string TRANSITIONING = "TRANSITIONING";
public const string PAUSED_PLAYBACK = "PAUSED_PLAYBACK";
public const string PAUSED = "PAUSED";
}
}
public enum TRANSPORTSTATE
{
STOPPED,
PLAYING,
TRANSITIONING,
PAUSED_PLAYBACK,
PAUSED
}
}

View File

@ -88,10 +88,10 @@ namespace MediaBrowser.Dlna.PlayTo
if (_currentItem == null)
return;
if (e.Stopped == false)
if (e.State == TRANSPORTSTATE.STOPPED)
await ReportProgress().ConfigureAwait(false);
else if (e.Stopped && _playbackStarted)
else if (e.State == TRANSPORTSTATE.STOPPED && _playbackStarted)
{
_playbackStarted = false;

View File

@ -4,6 +4,6 @@ namespace MediaBrowser.Dlna.PlayTo
{
public class TransportStateEventArgs : EventArgs
{
public bool Stopped { get; set; }
public TRANSPORTSTATE State { get; set; }
}
}

View File

@ -185,7 +185,7 @@ namespace MediaBrowser.Dlna.Server
{
var id = sparams["ObjectID"];
var item = _libraryManager.GetItemById(new Guid(id));
var item = GetItemFromObjectId(id, user);
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture);
@ -265,9 +265,7 @@ namespace MediaBrowser.Dlna.Server
didl.SetAttribute("xmlns:sec", NS_SEC);
result.AppendChild(didl);
var folder = string.IsNullOrWhiteSpace(id) || string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
? user.RootFolder
: (Folder)_libraryManager.GetItemById(new Guid(id));
var folder = (Folder)GetItemFromObjectId(id, user);
var children = GetChildrenSorted(folder, user).ToList();
@ -328,6 +326,17 @@ namespace MediaBrowser.Dlna.Server
return _libraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending);
}
private BaseItem GetItemFromObjectId(string id, User user)
{
return string.IsNullOrWhiteSpace(id) || string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
// Samsung sometimes uses 1 as root
|| string.Equals(id, "1", StringComparison.OrdinalIgnoreCase)
? user.RootFolder
: _libraryManager.GetItemById(new Guid(id));
}
private void Browse_AddFolder(XmlDocument result, Folder f, int childCount)
{
var container = result.CreateElement(string.Empty, "container", NS_DIDL);

View File

@ -12,9 +12,11 @@ namespace MediaBrowser.Dlna.Server
GetGetSystemUpdateIDAction(),
GetSearchCapabilitiesAction(),
GetSortCapabilitiesAction(),
GetSearchAction(),
GetBrowseAction(),
GetX_GetFeatureListAction(),
GetXSetBookmarkAction()
GetXSetBookmarkAction(),
GetBrowseByLetterAction()
};
return list;
@ -88,6 +90,86 @@ namespace MediaBrowser.Dlna.Server
return action;
}
private ServiceAction GetSearchAction()
{
var action = new ServiceAction
{
Name = "Search"
};
action.ArgumentList.Add(new Argument
{
Name = "ContainerID",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_ObjectID"
});
action.ArgumentList.Add(new Argument
{
Name = "SearchCriteria",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_SearchCriteria"
});
action.ArgumentList.Add(new Argument
{
Name = "Filter",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_Filter"
});
action.ArgumentList.Add(new Argument
{
Name = "StartingIndex",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_Index"
});
action.ArgumentList.Add(new Argument
{
Name = "RequestedCount",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "SortCriteria",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_SortCriteria"
});
action.ArgumentList.Add(new Argument
{
Name = "Result",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Result"
});
action.ArgumentList.Add(new Argument
{
Name = "NumberReturned",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "TotalMatches",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "UpdateID",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_UpdateID"
});
return action;
}
private ServiceAction GetBrowseAction()
{
var action = new ServiceAction
@ -168,6 +250,93 @@ namespace MediaBrowser.Dlna.Server
return action;
}
private ServiceAction GetBrowseByLetterAction()
{
var action = new ServiceAction
{
Name = "X_BrowseByLetter"
};
action.ArgumentList.Add(new Argument
{
Name = "ObjectID",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_ObjectID"
});
action.ArgumentList.Add(new Argument
{
Name = "BrowseFlag",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_BrowseFlag"
});
action.ArgumentList.Add(new Argument
{
Name = "Filter",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_Filter"
});
action.ArgumentList.Add(new Argument
{
Name = "StartingLetter",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_BrowseLetter"
});
action.ArgumentList.Add(new Argument
{
Name = "RequestedCount",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "SortCriteria",
Direction = "in",
RelatedStateVariable = "A_ARG_TYPE_SortCriteria"
});
action.ArgumentList.Add(new Argument
{
Name = "Result",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Result"
});
action.ArgumentList.Add(new Argument
{
Name = "NumberReturned",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "TotalMatches",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Count"
});
action.ArgumentList.Add(new Argument
{
Name = "UpdateID",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_UpdateID"
});
action.ArgumentList.Add(new Argument
{
Name = "StartingIndex",
Direction = "out",
RelatedStateVariable = "A_ARG_TYPE_Index"
});
return action;
}
private ServiceAction GetXSetBookmarkAction()
{
var action = new ServiceAction

View File

@ -135,7 +135,7 @@ namespace MediaBrowser.Dlna.Server
private void RespondToSearch(IPEndPoint endpoint, string req)
{
if (req == "ssdp:all")
if (string.Equals(req, "ssdp:all", StringComparison.OrdinalIgnoreCase))
{
req = null;
}
@ -171,7 +171,7 @@ namespace MediaBrowser.Dlna.Server
SendDatagram(endpoint, dev.Address, msg, false);
_logger.Info("{1} - Responded to a {0} request", dev.Type, endpoint);
_logger.Info("{1} - Responded to a {0} request to {2}", dev.Type, endpoint, dev.Address.ToString());
}
private void SendDatagram(IPEndPoint endpoint, IPAddress localAddress, string msg, bool sticky)

View File

@ -37,7 +37,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
var isStandalone = args.Parent == null;
if (isStandalone ||
string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) ||
string.IsNullOrEmpty(collectionType))
{
return new Controller.Entities.Audio.Audio();
}

View File

@ -0,0 +1 @@
{"SettingsSaved":"Settings saved.","AddUser":"Add User","Users":"Users","Delete":"Delete","Administrator":"Administrator","Password":"Password","DeleteImage":"Delete Image","DeleteImageConfirmation":"Are you sure you wish to delete this image?","FileReadCancelled":"The file read has been cancelled.","FileNotFound":"File not found.","FileReadError":"An error occurred while reading the file.","DeleteUser":"Delete User","DeleteUserConfirmation":"Are you sure you wish to delete {0}?","PasswordResetHeader":"Password Reset","PasswordResetComplete":"The password has been reset.","PasswordResetConfirmation":"Are you sure you wish to reset the password?","PasswordSaved":"Password saved.","PasswordMatchError":"Password and password confirmation must match.","OptionOff":"Off","OptionOn":"On","OptionRelease":"Official Release","OptionBeta":"Beta","OptionDev":"Dev (Unstable)","UninstallPluginHeader":"Uninstall Plugin","UninstallPluginConfirmation":"Are you sure you wish to uninstall {0}?","NoPluginConfigurationMessage":"This plugin has nothing to configure.","NoPluginsInstalledMessage":"You have no plugins installed.","BrowsePluginCatalogMessage":"Browse our plugin catalog to view available plugins."}

View File

@ -1 +1 @@
{"SettingsSaved":"Configuraci\u00f3n guardada.","AddUser":"Agregar usuario","Users":"Usuarios","Delete":"Eliminar","Administrator":"Administrador","Password":"Contrase\u00f1a","DeleteImage":"Eliminar imagen","DeleteImageConfirmation":"\u00bfEst\u00e1 seguro que desea eliminar esta imagen?","FileReadCancelled":"La lectura del archivo ha sido cancelada.","FileNotFound":"Archivo no encontrado.","FileReadError":"Ha ocurrido un error al leer el archivo.","DeleteUser":"Eliminar Usuario","DeleteUserConfirmation":"\u00bfEsta seguro que desea eliminar a {0}?","PasswordResetHeader":"Restablecer Contrase\u00f1a","PasswordResetComplete":"La contrase\u00f1a ha sido restablecida.","PasswordResetConfirmation":"\u00bfEst\u00e1 seguro que desea restablecer la contrase\u00f1a?","PasswordSaved":"Contrase\u00f1a guardada.","PasswordMatchError":"La Contrase\u00f1a y la confirmaci\u00f3n de la contrase\u00f1a deben coincidir.","OptionOff":"Apagado","OptionOn":"Encendido","OptionRelease":"Versi\u00f3n Oficial","OptionBeta":"Beta","OptionDev":"Desarrollo (Inestable)","UninstallPluginHeader":"Desinstalar Complemento","UninstallPluginConfirmation":"\u00bfEst\u00e1 seguro que desea desinstalar {0}?","NoPluginConfigurationMessage":"El complemento no requiere configuraci\u00f3n","NoPluginsInstalledMessage":"No tiene complementos instalados.","BrowsePluginCatalogMessage":"Navege en el catalogo de complementos para ver los complementos disponibles."}
{"SettingsSaved":"Configuraci\u00f3n guardada.","AddUser":"Agregar usuario","Users":"Usuarios","Delete":"Eliminar","Administrator":"Administrador","Password":"Contrase\u00f1a","DeleteImage":"Eliminar imagen","DeleteImageConfirmation":"\u00bfEst\u00e1 seguro que desea eliminar esta imagen?","FileReadCancelled":"La lectura del archivo ha sido cancelada.","FileNotFound":"Archivo no encontrado.","FileReadError":"Ha ocurrido un error al leer el archivo.","DeleteUser":"Eliminar Usuario","DeleteUserConfirmation":"\u00bfEsta seguro que desea eliminar a {0}?","PasswordResetHeader":"Restablecer Contrase\u00f1a","PasswordResetComplete":"La contrase\u00f1a ha sido restablecida.","PasswordResetConfirmation":"\u00bfEst\u00e1 seguro que desea restablecer la contrase\u00f1a?","PasswordSaved":"Contrase\u00f1a guardada.","PasswordMatchError":"La Contrase\u00f1a y la confirmaci\u00f3n de la contrase\u00f1a deben coincidir.","OptionOff":"No","OptionOn":"Si","OptionRelease":"Versi\u00f3n Oficial","OptionBeta":"Beta","OptionDev":"Desarrollo (Inestable)","UninstallPluginHeader":"Desinstalar Complemento","UninstallPluginConfirmation":"\u00bfEst\u00e1 seguro que desea desinstalar {0}?","NoPluginConfigurationMessage":"El complemento no requiere configuraci\u00f3n","NoPluginsInstalledMessage":"No tiene complementos instalados.","BrowsePluginCatalogMessage":"Navege en el catalogo de complementos para ver los complementos disponibles."}

View File

@ -0,0 +1 @@
{"SettingsSaved":"\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u0430\u049b\u0442\u0430\u043b\u0434\u044b.","AddUser":"\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b \u04af\u0441\u0442\u0435\u0443","Users":"\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u0430\u0440","Delete":"\u0416\u043e\u044e","Administrator":"\u04d8\u043a\u0456\u043c\u0448\u0456","Password":"\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437","DeleteImage":"\u0421\u0443\u0440\u0435\u0442\u0442\u0456 \u0436\u043e\u044e","DeleteImageConfirmation":"\u0421\u0456\u0437 \u0448\u044b\u043d\u044b\u043c\u0435\u043d \u0431\u04b1\u043b \u0441\u0443\u0440\u0435\u0442\u0442\u0456 \u0436\u043e\u0439\u0493\u044b\u04a3\u044b\u0437 \u043a\u0435\u043b\u0435 \u043c\u0435?","FileReadCancelled":"\u0424\u0430\u0439\u043b \u043e\u049b\u0443\u044b \u0442\u043e\u049b\u0442\u0430\u0442\u044b\u043b\u0434\u044b.","FileNotFound":"\u0424\u0430\u0439\u043b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0434\u044b.","FileReadError":"\u0424\u0430\u0439\u043b\u0434\u044b \u043e\u049b\u044b\u043f \u0436\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u049b\u0430\u0442\u0435 \u043f\u0430\u0439\u0434\u0430 \u0431\u043e\u043b\u0434\u044b.","DeleteUser":"\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b \u0430\u043b\u0430\u0441\u0442\u0430\u0443","DeleteUserConfirmation":"\u0421\u0456\u0437 \u0448\u044b\u043d\u044b\u043c\u0435\u043d {0} \u0436\u043e\u0439\u0493\u044b\u04a3\u044b\u0437 \u043a\u0435\u043b\u0435 \u043c\u0435?","PasswordResetHeader":"\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0456 \u044b\u0441\u044b\u0440\u0443","PasswordResetComplete":"\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437 \u044b\u0441\u044b\u0440\u044b\u043b\u0434\u044b.","PasswordResetConfirmation":"\u0421\u0456\u0437 \u0448\u044b\u043d\u044b\u043c\u0435\u043d \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0456 \u044b\u0441\u044b\u0440\u0493\u044b\u04a3\u044b\u0437 \u043a\u0435\u043b\u0435 \u043c\u0435?","PasswordSaved":"\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437 \u0441\u0430\u049b\u0442\u0430\u043b\u0434\u044b.","PasswordMatchError":"\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0456 \u043c\u0435\u043d \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0456 \u0440\u0430\u0441\u0442\u0430\u0443 \u04e9\u0440\u0456\u0441\u0442\u0435\u0440\u0456 \u0441\u04d9\u0439\u043a\u0435\u0441 \u0431\u043e\u043b\u0443 \u043a\u0435\u0440\u0435\u043a.","OptionOff":"\u04e8\u0448\u0456\u0440","OptionOn":"\u049a\u043e\u0441","OptionRelease":"\u0420\u0435\u0441\u043c\u0438 \u0448\u044b\u0493\u0430\u0440\u044b\u043b\u044b\u043c","OptionBeta":"\u0411\u0435\u0442\u0430 \u043d\u04b1\u0441\u049b\u0430","OptionDev":"\u0416\u0430\u0441\u0430\u049b\u0442\u0430\u0443 (\u0422\u04b1\u0440\u0430\u049b\u0441\u044b\u0437)","UninstallPluginHeader":"\u041f\u043b\u0430\u0433\u0438\u043d \u043e\u0440\u043d\u0430\u0442\u0443\u044b\u043d \u0431\u043e\u043b\u0434\u044b\u0440\u043c\u0430\u0443","UninstallPluginConfirmation":"\u0421\u0456\u0437 \u0448\u044b\u043d\u044b\u043c\u0435\u043d {0} \u043e\u0440\u043d\u0430\u0442\u0443\u044b\u043d \u0431\u043e\u043b\u0434\u044b\u0440\u043c\u0430\u0443\u044b\u04a3\u044b\u0437 \u043a\u0435\u043b\u0435 \u043c\u0435?","NoPluginConfigurationMessage":"\u0411\u04b1\u043b \u043f\u043b\u0430\u0433\u0438\u043d \u04af\u0448\u0456\u043d \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u043b\u0430\u0443 \u0436\u043e\u049b.","NoPluginsInstalledMessage":"\u0421\u0456\u0437\u0434\u0435 \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u043f\u043b\u0430\u0433\u0438\u043d\u0434\u0435\u0440 \u043e\u0440\u043d\u0430\u0442\u044b\u043b\u043c\u0430\u0493\u0430\u043d.","BrowsePluginCatalogMessage":"\u049a\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456 \u043f\u043b\u0430\u0433\u0438\u043d\u0434\u0435\u0440\u043c\u0435\u043d \u0442\u0430\u043d\u044b\u0441\u0443 \u04af\u0448\u0456\u043d \u0431\u0456\u0437\u0434\u0456\u04a3 \u043f\u043b\u0430\u0433\u0438\u043d \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0456\u043d \u0448\u043e\u043b\u044b\u04a3\u044b\u0437."}

View File

@ -1 +1 @@
{"SettingsSaved":"Configura\u00e7\u00f5es guardadas.","AddUser":"Adicionar Utilizador","Users":"Utilizadores","Delete":"Apagar","Administrator":"Administrador","Password":"Senha","DeleteImage":"Apagar Imagem","DeleteImageConfirmation":"Tem a certeza que deseja apagar a imagem?","FileReadCancelled":"A leitura do ficheiro foi cancelada.","FileNotFound":"Ficheiro n\u00e3o encontrado.","FileReadError":"Ocorreu um erro ao ler o ficheiro.","DeleteUser":"Apagar Utilizador","DeleteUserConfirmation":"Tem a certeza que deseja apagar {0}?","PasswordResetHeader":"Redefinir Senha","PasswordResetComplete":"A senha foi redefinida.","PasswordResetConfirmation":"Tem a certeza que deseja redefinir a senha?","PasswordSaved":"Senha guardada.","PasswordMatchError":"A senha e a confirma\u00e7\u00e3o da senha devem coincidir.","OptionOff":"Desligar","OptionOn":"Ligar","OptionRelease":"Lan\u00e7amento Oficial","OptionBeta":"Beta","OptionDev":"Dev (Inst\u00e1vel)","UninstallPluginHeader":"Desinstalar extens\u00e3o","UninstallPluginConfirmation":"Tem a certeza que deseja desinstalar {0}?","NoPluginConfigurationMessage":"Esta extens\u00e3o n\u00e3o \u00e9 configur\u00e1vel.","NoPluginsInstalledMessage":"N\u00e3o tem extens\u00f5es instaladas.","BrowsePluginCatalogMessage":"Navegue o nosso cat\u00e1logo de extens\u00f5es, para ver as extens\u00f5es dispon\u00edveis."}
{"SettingsSaved":"Configura\u00e7\u00f5es guardadas.","AddUser":"Adicionar Utilizador","Users":"Utilizadores","Delete":"Apagar","Administrator":"Administrador","Password":"Senha","DeleteImage":"Apagar Imagem","DeleteImageConfirmation":"Tem a certeza que deseja apagar a imagem?","FileReadCancelled":"A leitura do ficheiro foi cancelada.","FileNotFound":"Ficheiro n\u00e3o encontrado.","FileReadError":"Ocorreu um erro ao ler o ficheiro.","DeleteUser":"Apagar Utilizador","DeleteUserConfirmation":"Tem a certeza que deseja apagar {0}?","PasswordResetHeader":"Redefinir Senha","PasswordResetComplete":"A senha foi redefinida.","PasswordResetConfirmation":"Tem a certeza que deseja redefinir a senha?","PasswordSaved":"Senha guardada.","PasswordMatchError":"A senha e a confirma\u00e7\u00e3o da senha devem coincidir.","OptionOff":"Desligado","OptionOn":"Ligado","OptionRelease":"Lan\u00e7amento Oficial","OptionBeta":"Beta","OptionDev":"Dev (Inst\u00e1vel)","UninstallPluginHeader":"Desinstalar extens\u00e3o","UninstallPluginConfirmation":"Tem a certeza que deseja desinstalar {0}?","NoPluginConfigurationMessage":"Esta extens\u00e3o n\u00e3o \u00e9 configur\u00e1vel.","NoPluginsInstalledMessage":"N\u00e3o tem extens\u00f5es instaladas.","BrowsePluginCatalogMessage":"Navegue o nosso cat\u00e1logo de extens\u00f5es, para ver as extens\u00f5es dispon\u00edveis."}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -517,5 +517,20 @@
"LabelComponentsUpdated": "The following components have been installed or updated:",
"MessagePleaseRestartServerToFinishUpdating": "Please restart the server to finish applying updates.",
"LabelDownMixAudioScale": "Down mix audio boost scale:",
"LabelDownMixAudioScaleHelp": "Boost audio when downmixing. Set to 1 to preserve original volume value."
"LabelDownMixAudioScaleHelp": "Boost audio when downmixing. Set to 1 to preserve original volume value.",
"ButtonLinkKeys": "Link Keys",
"LabelOldSupporterKey": "Old supporter key",
"LabelNewSupporterKey": "New supporter key",
"HeaderMultipleKeyLinking": "Multiple Key Linking",
"MultipleKeyLinkingHelp": "If you have more than one supporter key, use this form to link the old key's registrations with your new one.",
"LabelCurrentEmailAddress": "Current email address",
"LabelCurrentEmailAddressHelp": "The current email address to which your new key was sent.",
"HeaderForgotKey": "Forgot Key",
"LabelEmailAddress": "Email address",
"LabelSupporterEmailAddress": "The email address that was used to purchase the key.",
"ButtonRetrieveKey": "Retrieve Key",
"LabelSupporterKey": "Supporter Key (paste from email)",
"LabelSupporterKeyHelp": "Enter your supporter key to start enjoying additional benefits the community has developed for Media Browser.",
"MessageInvalidKey": "MB3 Key Missing or Invalid",
"ErrorMessageInvalidKey": "In order for any premium content to be registered, you must also be an MB3 Supporter. Please donate and support the continued development of the core product. Thank you."
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -323,6 +323,8 @@
<EmbeddedResource Include="Localization\JavaScript\ms.json" />
<EmbeddedResource Include="Localization\Server\ca.json" />
<EmbeddedResource Include="Localization\Server\ms.json" />
<EmbeddedResource Include="Localization\JavaScript\kk.json" />
<EmbeddedResource Include="Localization\Server\kk.json" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>