From a55d156fd65e297b044d8ad898b1e04f659e4e60 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 Jun 2014 17:45:21 -0400 Subject: [PATCH 001/131] update translations --- .../Playback/BaseStreamingService.cs | 3 +- .../Playback/Progressive/VideoService.cs | 2 +- .../Entities/Movies/Movie.cs | 3 +- MediaBrowser.Controller/Entities/Video.cs | 4 +- .../MediaEncoding/InternalMediaInfoResult.cs | 6 + .../Localization/JavaScript/ar.json | 19 +-- .../Localization/JavaScript/ca.json | 19 +-- .../Localization/JavaScript/cs.json | 19 +-- .../Localization/JavaScript/da.json | 19 +-- .../Localization/JavaScript/de.json | 19 +-- .../Localization/JavaScript/el.json | 19 +-- .../Localization/JavaScript/en_GB.json | 19 +-- .../Localization/JavaScript/en_US.json | 19 +-- .../Localization/JavaScript/es.json | 19 +-- .../Localization/JavaScript/es_MX.json | 19 +-- .../Localization/JavaScript/fr.json | 121 +++++++++--------- .../Localization/JavaScript/he.json | 19 +-- .../Localization/JavaScript/it.json | 19 +-- .../Localization/JavaScript/javascript.json | 9 +- .../Localization/JavaScript/kk.json | 19 +-- .../Localization/JavaScript/ms.json | 19 +-- .../Localization/JavaScript/nb.json | 19 +-- .../Localization/JavaScript/nl.json | 21 +-- .../Localization/JavaScript/pt_BR.json | 25 ++-- .../Localization/JavaScript/pt_PT.json | 19 +-- .../Localization/JavaScript/ru.json | 23 ++-- .../Localization/JavaScript/sv.json | 19 +-- .../Localization/JavaScript/vi.json | 19 +-- .../Localization/JavaScript/zh_TW.json | 19 +-- .../Localization/Server/ar.json | 49 ++----- .../Localization/Server/ca.json | 49 ++----- .../Localization/Server/cs.json | 49 ++----- .../Localization/Server/da.json | 49 ++----- .../Localization/Server/de.json | 49 ++----- .../Localization/Server/el.json | 49 ++----- .../Localization/Server/en_GB.json | 49 ++----- .../Localization/Server/en_US.json | 49 ++----- .../Localization/Server/es.json | 49 ++----- .../Localization/Server/es_MX.json | 49 ++----- .../Localization/Server/fr.json | 109 ++++++---------- .../Localization/Server/he.json | 49 ++----- .../Localization/Server/it.json | 49 ++----- .../Localization/Server/kk.json | 49 ++----- .../Localization/Server/ms.json | 49 ++----- .../Localization/Server/nb.json | 49 ++----- .../Localization/Server/nl.json | 51 ++------ .../Localization/Server/pt_BR.json | 63 +++------ .../Localization/Server/pt_PT.json | 49 ++----- .../Localization/Server/ru.json | 51 ++------ .../Localization/Server/server.json | 10 +- .../Localization/Server/sv.json | 49 ++----- .../Localization/Server/vi.json | 49 ++----- .../Localization/Server/zh_TW.json | 49 ++----- .../Session/SessionManager.cs | 2 +- MediaBrowser.ServerApplication/MainStartup.cs | 1 - Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 58 files changed, 612 insertions(+), 1194 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index c016f67ab2..1b3ff8d689 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1061,7 +1061,8 @@ namespace MediaBrowser.Api.Playback // Make sure we don't request a bitrate higher than the source var currentBitrate = audioStream == null ? request.AudioBitRate.Value : audioStream.BitRate ?? request.AudioBitRate.Value; - return Math.Min(currentBitrate, request.AudioBitRate.Value); + return request.AudioBitRate.Value; + //return Math.Min(currentBitrate, request.AudioBitRate.Value); } return null; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 063b056b09..937df513e6 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -210,7 +210,7 @@ namespace MediaBrowser.Api.Playback.Progressive args += " -ab " + bitrate.Value.ToString(UsCulture); } - args += " " + GetAudioFilterParam(state, true); + args += " " + GetAudioFilterParam(state, false); return args; } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 54cb3fcc94..5510c795a0 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasPreferredMetadataLanguage, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasShortOverview + public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasPreferredMetadataLanguage, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping { public List SpecialFeatureIds { get; set; } @@ -52,7 +52,6 @@ namespace MediaBrowser.Controller.Entities.Movies ProductionLocations = new List(); } - public string ShortOverview { get; set; } public string AwardSummary { get; set; } public float? Metascore { get; set; } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 61404949e4..4d50e61aeb 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -23,7 +23,8 @@ namespace MediaBrowser.Controller.Entities IHasAspectRatio, IHasTags, ISupportsPlaceHolders, - IHasMediaSources + IHasMediaSources, + IHasShortOverview { public bool IsMultiPart { get; set; } public bool HasLocalAlternateVersions { get; set; } @@ -36,6 +37,7 @@ namespace MediaBrowser.Controller.Entities public long? Size { get; set; } public string Container { get; set; } public int? TotalBitrate { get; set; } + public string ShortOverview { get; set; } /// /// Gets or sets the timestamp. diff --git a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs index 39d1c32202..796fdb723a 100644 --- a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs +++ b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs @@ -312,6 +312,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The bit_rate. public string bit_rate { get; set; } + /// + /// Gets or sets the probe_score. + /// + /// The probe_score. + public int probe_score { get; set; } + /// /// Gets or sets the tags. /// diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json index d9bde20901..9d900131fb 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "\u0627\u064a\u0642\u0627\u0641", - "OptionOn": "\u062a\u0634\u063a\u064a\u0644", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "\u062a\u0645 \u062d\u0641\u0638 \u0627\u0644\u0627\u0639\u062f\u0627\u062f\u0627\u062a.", "AddUser": "\u0627\u0636\u0627\u0641\u0629 \u0645\u0633\u062a\u062e\u062f\u0645", "Users": "\u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "\u0645\u0648\u0627\u0641\u0642", + "ButtonCancel": "\u0627\u0644\u063a\u0627\u0621", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json index b6c67083ef..b3480f4a28 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Apagat", - "OptionOn": "Enc\u00e8s", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Configuraci\u00f3 guardada.", "AddUser": "Afegir Usuari", "Users": "Usuaris", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json index 6998eacccd..9d0c2d6fba 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Vypnout", - "OptionOn": "Zapnout", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Nastaven\u00ed ulo\u017eeno.", "AddUser": "P\u0159idat u\u017eivatele", "Users": "U\u017eivatel\u00e9", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "P\u0159ehr\u00e1t", "ButtonEdit": "Upravit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Zru\u0161it", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json index 0e6fe6a335..a545648641 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mit bibliotek", "SettingsSaved": "Indstillinger er gemt", "AddUser": "Tilf\u00f8j bruger", "Users": "Brugere", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Afspil", "ButtonEdit": "Rediger", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Annuller", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json index b2987fa9cb..e48b788b07 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Passwort erstellen", - "OptionOff": "Aus", - "OptionOn": "Ein", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Meine Bibliothek", "SettingsSaved": "Einstellungen gespeichert", "AddUser": "Benutzer hinzuf\u00fcgen", "Users": "Benutzer", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Stumm", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "N\u00e4chster Track", "ButtonPause": "Pause", "ButtonPlay": "Abspielen", "ButtonEdit": "Bearbeiten", "ButtonQueue": "Queue", "ButtonPlayTrailer": "Spiele Trailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Vorheriger Track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Abbrechen", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json index c28e6870df..719f63e086 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "\u03c3\u03b2\u03b7\u03c3\u03c4\u03cc\u03c2", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b1\u03bd", "AddUser": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7", "Users": "\u039f\u03b9 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "\u03b5\u03bd\u03c4\u03ac\u03be\u03b5\u03b9", + "ButtonCancel": "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7 ", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json index 5e8ffeb028..246d872751 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Settings saved.", "AddUser": "Add User", "Users": "Users", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json index 5fafacc780..6c5cf65dff 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Settings saved.", "AddUser": "Add User", "Users": "Users", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json index 0d72753546..f4f1264224 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Crear Contrase\u00f1a", - "OptionOff": "Apagado", - "OptionOn": "Encendido", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Por favor, seleccione dos o m\u00e1s elementos para unir al grupo.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mi librer\u00eda", "SettingsSaved": "Configuraci\u00f3n guardada", "AddUser": "Agregar usuario", "Users": "Usuarios", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Idioma desconocido", "ButtonMute": "Silencio", "ButtonUnmute": "Activar audio", + "ButtonNextTrack": "Pista siguiente", "ButtonPause": "Pausa", "ButtonPlay": "Reproducir", "ButtonEdit": "Editar", "ButtonQueue": "En cola", "ButtonPlayTrailer": "Reproducir trailer", "ButtonPlaylist": "Lista de reproducci\u00f3n", + "ButtonPreviousTrack": "Pista anterior", "LabelEnabled": "Activado", "LabelDisabled": "Desactivado", "ButtonMoreInformation": "M\u00e1s informaci\u00f3n", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "OK", + "ButtonCancel": "Cancelar", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json index d5c854c1ab..6b609dde17 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "No", - "OptionOn": "Si", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Por favor selecciona dos o mas elementos para agruparlos", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mi Biblioteca", "SettingsSaved": "Configuraci\u00f3n guardada.", "AddUser": "Agregar usuario", "Users": "Usuarios", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Idioma Desconocido", "ButtonMute": "Mudo", "ButtonUnmute": "Quitar mudo", + "ButtonNextTrack": "Pista Siguiente", "ButtonPause": "Pausar", "ButtonPlay": "Reproducir", "ButtonEdit": "Editar", "ButtonQueue": "A cola", "ButtonPlayTrailer": "Reproducir Trailer", "ButtonPlaylist": "Lista de Reprod.", + "ButtonPreviousTrack": "Pista Anterior", "LabelEnabled": "Habilitado", "LabelDisabled": "Deshabilitado", "ButtonMoreInformation": "Mas Informaci\u00f3n", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "La descarga se ha agregado a la cola.", "MessageAreYouSureDeleteSubtitles": "\u00bfEstas seguro de que deseas eliminar este archivo de subtitulos?", "ButtonRemoteControl": "Control Remoto", - "HeaderLatestTvRecordings": "\u00daltimas Grabaciones" + "HeaderLatestTvRecordings": "\u00daltimas Grabaciones", + "ButtonOk": "Ok", + "ButtonCancel": "Cancelar", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json index 6e7f3246a6..4ba25ce7ab 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Cr\u00e9er mot de passe", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Ma biblioth\u00e8que", "SettingsSaved": "Param\u00e8tres sauvegard\u00e9s.", "AddUser": "Ajouter utilisateur", "Users": "Utilisateurs", @@ -51,9 +43,9 @@ "LabelFailed": "(\u00e9chou\u00e9)", "LabelAbortedByServerShutdown": "(Annul\u00e9 par fermeture du serveur)", "LabelScheduledTaskLastRan": "Derni\u00e8re ex\u00e9cution {0}, dur\u00e9e {1}.", - "HeaderDeleteTaskTrigger": "Delete Task Trigger", - "HeaderTaskTriggers": "Task Triggers", - "MessageDeleteTaskTrigger": "Are you sure you wish to delete this task trigger?", + "HeaderDeleteTaskTrigger": "Supprimer le d\u00e9clencheur de t\u00e2che", + "HeaderTaskTriggers": "D\u00e9clencheurs de t\u00e2ches", + "MessageDeleteTaskTrigger": "\u00cates-vous s\u00fbr de vouloir supprimer ce d\u00e9clencheur de t\u00e2che?", "MessageNoPluginsInstalled": "Vous n'avez aucun plugin install\u00e9.", "LabelVersionInstalled": "{0} install\u00e9(s)", "LabelNumberReviews": "{0} Critique(s)", @@ -65,13 +57,15 @@ "LabelDefaultForcedStream": "(Par d\u00e9faut\/Forc\u00e9)", "LabelUnknownLanguage": "Langue inconnue", "ButtonMute": "Sourdine", - "ButtonUnmute": "Unmute", + "ButtonUnmute": "D\u00e9sactiver sourdine", + "ButtonNextTrack": "Piste suivante", "ButtonPause": "Pause", "ButtonPlay": "Lire", "ButtonEdit": "Modifier", "ButtonQueue": "En file d'attente", "ButtonPlayTrailer": "Lire bande-annonce", "ButtonPlaylist": "Liste de lecture", + "ButtonPreviousTrack": "Piste pr\u00e9c\u00e9dante", "LabelEnabled": "Activ\u00e9", "LabelDisabled": "D\u00e9sactiv\u00e9", "ButtonMoreInformation": "Plus d'information", @@ -85,7 +79,7 @@ "RecommendationBecauseYouLike": "Parce-que vous aimez {0}", "RecommendationBecauseYouWatched": "Parece-que vous avez regard\u00e9 {0}", "RecommendationDirectedBy": "R\u00e9alis\u00e9 par {0}", - "RecommendationStarring": "Starring {0}", + "RecommendationStarring": "Mettant en vedette {0}", "HeaderConfirmRecordingCancellation": "Confirmer l'annulation de l'enregistrement.", "MessageConfirmRecordingCancellation": "\u00cates-vous s\u00fbr de vouloir annuler cet enregistrement?", "MessageRecordingCancelled": "Enregistrement annul\u00e9.", @@ -114,21 +108,21 @@ "ButtonCancelSeries": "Annuler s\u00e9ries", "LabelAllChannels": "Toutes les cha\u00eenes", "HeaderSeriesRecordings": "Enregistrements de s\u00e9ries", - "LabelAnytime": "Any time", + "LabelAnytime": "N'importe quelle heure", "StatusRecording": "En cours d'enregistrement", - "StatusWatching": "Watching", + "StatusWatching": "En lecture", "StatusRecordingProgram": "Enregistre {0}", - "StatusWatchingProgram": "Watching {0}", + "StatusWatchingProgram": "En lecture de {0}", "HeaderSplitMedia": "Split Media Apart", "MessageConfirmSplitMedia": "Are you sure you wish to split the media sources into separate items?", "HeaderError": "Erreur", - "MessagePleaseSelectOneItem": "Please select at least one item.", - "MessagePleaseSelectTwoItems": "Please select at least two items.", - "MessageTheFollowingItemsWillBeGrouped": "The following titles will be grouped into one item:", - "MessageConfirmItemGrouping": "Media Browser clients will automatically choose the optimal version to play based on device and network performance. Are you sure you wish to continue?", + "MessagePleaseSelectOneItem": "Veuillez s\u00e9lectionner au moins un item.", + "MessagePleaseSelectTwoItems": "Veuillez s\u00e9lectionner au moins deux items.", + "MessageTheFollowingItemsWillBeGrouped": "Les titres suivants seront group\u00e9s en un seul item:", + "MessageConfirmItemGrouping": "Les clients Media Browser s\u00e9lectionneront automatiquement la version optimale \u00e0 lire bas\u00e9 sur l'appareil et la performance du r\u00e9seau. \u00cates-vous s\u00fbr de vouloir continuer?", "HeaderResume": "Reprendre", - "HeaderMyViews": "My Views", - "HeaderLibraryFolders": "Media Folders", + "HeaderMyViews": "Mes affichages", + "HeaderLibraryFolders": "R\u00e9pertoires de m\u00e9dias", "HeaderLatestMedia": "Derniers m\u00e9dias", "ButtonMore": "Plus...", "HeaderFavoriteMovies": "Films favoris", @@ -148,50 +142,57 @@ "HeaderSelectMetadataPathHelp": "Browse or enter the path you'd like to store metadata within. The folder must be writeable.", "HeaderSelectChannelDownloadPath": "Select Channel Download Path", "HeaderSelectChannelDownloadPathHelp": "Browse or enter the path to use for storing channel cache files. The folder must be writeable.", - "OptionNewCollection": "New...", + "OptionNewCollection": "Nouveau...", "ButtonAdd": "Ajouter", "ButtonRemove": "Supprimer", - "LabelChapterDownloaders": "Chapter downloaders:", + "LabelChapterDownloaders": "Agents de t\u00e9l\u00e9chargement de chapitres:", "LabelChapterDownloadersHelp": "Enable and rank your preferred chapter downloaders in order of priority. Lower priority downloaders will only be used to fill in missing information.", - "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderLatestChannelMedia": "Latest Channel Items", - "ButtonOrganizeFile": "Organize File", - "ButtonDeleteFile": "Delete File", - "HeaderOrganizeFile": "Organize File", - "HeaderDeleteFile": "Delete File", - "StatusSkipped": "Skipped", - "StatusFailed": "Failed", - "StatusSuccess": "Success", - "MessageFileWillBeDeleted": "The following file will be deleted:", - "MessageSureYouWishToProceed": "Are you sure you wish to proceed?", + "HeaderFavoriteAlbums": "Albums favoris", + "HeaderLatestChannelMedia": "Derniers items de cha\u00eenes", + "ButtonOrganizeFile": "Organiser fichier", + "ButtonDeleteFile": "Supprimer fichier", + "HeaderOrganizeFile": "Organiser fichier", + "HeaderDeleteFile": "Supprimer fichier", + "StatusSkipped": "Saut\u00e9s", + "StatusFailed": "\u00c9chou\u00e9", + "StatusSuccess": "Succ\u00e8s", + "MessageFileWillBeDeleted": "Le fichier suivant sera supprim\u00e9:", + "MessageSureYouWishToProceed": "\u00cates-vous s\u00fbr de vouloir continuer?", "MessageDuplicatesWillBeDeleted": "In addition the following dupliates will be deleted:", - "MessageFollowingFileWillBeMovedFrom": "The following file will be moved from:", - "MessageDestinationTo": "to:", - "HeaderSelectWatchFolder": "Select Watch Folder", + "MessageFollowingFileWillBeMovedFrom": "Le fichier suivant sera d\u00e9plac\u00e9 de:", + "MessageDestinationTo": "Vers:", + "HeaderSelectWatchFolder": "S\u00e9lectionner le r\u00e9pertoire surveill\u00e9", "HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.", - "OrganizePatternResult": "Result: {0}", - "HeaderRestart": "Restart", - "HeaderShutdown": "Shutdown", - "MessageConfirmRestart": "Are you sure you wish to restart Media Browser Server?", - "MessageConfirmShutdown": "Are you sure you wish to shutdown Media Browser Server?", + "OrganizePatternResult": "R\u00e9sultats: {0}", + "HeaderRestart": "Red\u00e9marrer", + "HeaderShutdown": "\u00c9teindre", + "MessageConfirmRestart": "\u00cates-vous s\u00fbr de vouloir red\u00e9marrer le serveur Media Browser?", + "MessageConfirmShutdown": "\u00cates-vous s\u00fbr de vouloir \u00e9teindre le serveur Media Browser?", "ButtonUpdateNow": "Mettre \u00e0 jour maintenant", - "NewVersionOfSomethingAvailable": "A new version of {0} is available!", - "VersionXIsAvailableForDownload": "Version {0} is now available for download.", + "NewVersionOfSomethingAvailable": "Une nouvelle version de {0} est disponible!", + "VersionXIsAvailableForDownload": "La version {0} est maintenant disponible \u00e0 \u00eatre t\u00e9l\u00e9charg\u00e9e.", "LabelVersionNumber": "Version {0}", - "LabelPlayMethodTranscoding": "Transcoding", - "LabelPlayMethodDirectStream": "Direct Streaming", - "LabelPlayMethodDirectPlay": "Direct Playing", + "LabelPlayMethodTranscoding": "Transcodage", + "LabelPlayMethodDirectStream": "Direct Stream", + "LabelPlayMethodDirectPlay": "Direct Play", "LabelAudioCodec": "Audio: {0}", - "LabelVideoCodec": "Video: {0}", - "LabelRemoteAccessUrl": "Remote access: {0}", - "LabelRunningOnPort": "Running on port {0}.", - "LabelRunningOnPorts": "Running on ports {0} and {1}.", - "HeaderLatestFromChannel": "Latest from {0}", - "ButtonDownload": "Download", - "LabelUnknownLanaguage": "Unknown language", - "HeaderCurrentSubtitles": "Current Subtitles", - "MessageDownloadQueued": "The download has been queued.", - "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", - "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "LabelVideoCodec": "Vid\u00e9o: {0}", + "LabelRemoteAccessUrl": "Acc\u00e8s distant: {0}", + "LabelRunningOnPort": "En ex\u00e9cution sur le port: {0}.", + "LabelRunningOnPorts": "En ex\u00e9cution sur le port: {0} et {1}.", + "HeaderLatestFromChannel": "Les plus r\u00e9cents de {0}", + "ButtonDownload": "T\u00e9l\u00e9chargement", + "LabelUnknownLanaguage": "Langue inconnue", + "HeaderCurrentSubtitles": "Sous-titres actuels", + "MessageDownloadQueued": "Le t\u00e9l\u00e9chargement a \u00e9t\u00e9 mis en file.", + "MessageAreYouSureDeleteSubtitles": "\u00cates-vous s\u00fbr de vouloir supprimer ce fichier de sous-titre?", + "ButtonRemoteControl": "Acc\u00e8s distant", + "HeaderLatestTvRecordings": "Les plus r\u00e9cents enregistrements", + "ButtonOk": "Ok", + "ButtonCancel": "Annuler", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json index c22783249b..c3f5fecc17 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "\u05db\u05d1\u05d5\u05d9", - "OptionOn": "\u05e4\u05d5\u05e2\u05dc", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "\u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e0\u05e9\u05de\u05e8\u05d5.", "AddUser": "\u05d4\u05d5\u05e1\u05e3 \u05de\u05e9\u05ea\u05de\u05e9", "Users": "\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "\u05e0\u05d2\u05df", "ButtonEdit": "\u05e2\u05e8\u05d5\u05da", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "\u05d0\u05e9\u05e8", + "ButtonCancel": "\u05d1\u05d8\u05dc", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json index dcd0f73e8d..4c5bfe46ee 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Crea Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Si prega di selezionare due o pi\u00f9 elementi al gruppo insieme.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mia Libreria", "SettingsSaved": "Settaggi salvati.", "AddUser": "Aggiungi utente", "Users": "Utenti", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "(linguaggio sconosciuto)", "ButtonMute": "Muto", "ButtonUnmute": "Togli muto", + "ButtonNextTrack": "Prossimo", "ButtonPause": "Pausa", "ButtonPlay": "Riproduci", "ButtonEdit": "Modifica", "ButtonQueue": "In coda", "ButtonPlayTrailer": "Visualizza trailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Precedente", "LabelEnabled": "Abilitato", "LabelDisabled": "Disabilitato", "ButtonMoreInformation": "Maggiori informazioni", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "Il download \u00e8 stato accodato.", "MessageAreYouSureDeleteSubtitles": "Sei sicuro di voler cancellare questo file dei sottotitoli?", "ButtonRemoteControl": "telecomando", - "HeaderLatestTvRecordings": "Ultime registrazioni" + "HeaderLatestTvRecordings": "Ultime registrazioni", + "ButtonOk": "OK", + "ButtonCancel": "Annulla", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 6851e03875..7aad8e381d 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -188,5 +188,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json index 99a9ff6c18..5191e82e96 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "\u04e8\u0448\u0456\u0440", - "OptionOn": "\u049a\u043e\u0441", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "\u0411\u0456\u0440\u0435\u0443 \u043d\u0435 \u043a\u04e9\u0431\u0456\u0440\u0435\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0456 \u0431\u0456\u0440\u0433\u0435 \u0442\u043e\u043f\u0442\u0430\u04a3\u044b\u0437.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "\u041c\u0435\u043d\u0456\u04a3 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043c", "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", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "\u0411\u0435\u043b\u0433\u0456\u0441\u0456\u0437 \u0442\u0456\u043b", "ButtonMute": "\u0414\u044b\u0431\u044b\u0441\u0442\u044b \u04e9\u0448\u0456\u0440\u0443", "ButtonUnmute": "\u0414\u044b\u0431\u044b\u0441\u0442\u044b \u049b\u043e\u0441\u0443", + "ButtonNextTrack": "\u041a\u0435\u043b\u0435\u0441\u0456 \u0436\u043e\u043b\u0448\u044b\u049b", "ButtonPause": "\u04ae\u0437\u0456\u043b\u0456\u0441", "ButtonPlay": "\u041e\u0439\u043d\u0430\u0442\u0443", "ButtonEdit": "\u04e8\u04a3\u0434\u0435\u0443", "ButtonQueue": "\u041a\u0435\u0437\u0435\u043a", "ButtonPlayTrailer": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u0434\u0456 \u043e\u0439\u043d\u0430\u0442\u0443", "ButtonPlaylist": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456", + "ButtonPreviousTrack": "\u0410\u043b\u0434\u044b\u04a3\u0493\u044b \u0436\u043e\u043b\u0448\u044b\u049b", "LabelEnabled": "\u049a\u043e\u0441\u044b\u043b\u0493\u0430\u043d", "LabelDisabled": "\u0410\u0436\u044b\u0440\u0430\u0442\u044b\u043b\u0493\u0430\u043d", "ButtonMoreInformation": "\u041a\u04e9\u0431\u0456\u0440\u0435\u043a \u0430\u049b\u043f\u0430\u0440\u0430\u0442", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "\u0416\u04af\u043a\u0442\u0435\u0443 \u043a\u0435\u0437\u0435\u043a\u043a\u0435 \u043a\u0456\u0440\u0433\u0456\u0437\u0456\u043b\u0434\u0456.", "MessageAreYouSureDeleteSubtitles": "\u0428\u044b\u043d\u044b\u043c\u0435\u043d \u043e\u0441\u044b \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u0444\u0430\u0439\u043b\u044b\u043d \u0436\u043e\u044e \u049b\u0430\u0436\u0435\u0442 \u043f\u0435?", "ButtonRemoteControl": "\u049a\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443", - "HeaderLatestTvRecordings": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u0436\u0430\u0437\u0431\u0430\u043b\u0430\u0440" + "HeaderLatestTvRecordings": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u0436\u0430\u0437\u0431\u0430\u043b\u0430\u0440", + "ButtonOk": "\u0416\u0430\u0440\u0430\u0439\u0434\u044b", + "ButtonCancel": "\u0411\u043e\u043b\u0434\u044b\u0440\u043c\u0430\u0443", + "ButtonRefresh": "\u0416\u0430\u04a3\u0430\u0440\u0442\u0443", + "LabelCurrentPath": "\u0410\u0493\u044b\u043c\u0434\u044b\u049b \u0436\u043e\u043b:", + "HeaderSelectMediaPath": "\u0422\u0430\u0441\u0443\u0448\u044b \u0436\u043e\u043b\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0443", + "ButtonNetwork": "\u0416\u0435\u043b\u0456", + "MessageDirectoryPickerInstruction": "\u0416\u0435\u043b\u0456 \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456 \u0431\u0430\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u043e\u0440\u043d\u044b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0441\u0430, \u0436\u0435\u043b\u0456\u043b\u0456\u043a \u0436\u043e\u043b\u0434\u0430\u0440 \u049b\u043e\u043b\u043c\u0435\u043d \u0435\u043d\u0433\u0456\u0437\u0456\u043b\u0443\u0456 \u043c\u04af\u043c\u043a\u0456\u043d. \u041c\u044b\u0441\u0430\u043b\u044b, {0} \u043d\u0435\u043c\u0435\u0441\u0435 {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json index 51055f880c..57cb41fe94 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Seting Disimpan", "AddUser": "Tambah Pengguna", "Users": "Para Pengguna", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancel", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json index 351ab9520d..52e3f2b4ae 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Av", - "OptionOn": "P\u00e5", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mitt bibliotek", "SettingsSaved": "Innstillinger lagret", "AddUser": "Legg til bruker", "Users": "Brukere", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "avbryt", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json index 4e045acf34..9f54ce9b62 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Maak wachtwoord", - "OptionOff": "Uit", - "OptionOn": "Aan", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Selecteer twee of meer items om te groeperen.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mijn Bibliotheek", "SettingsSaved": "Instellingen opgeslagen.", "AddUser": "Gebruiker toevoegen", "Users": "Gebruikers", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Onbekende taal", "ButtonMute": "Dempen", "ButtonUnmute": "Dempen opheffen", + "ButtonNextTrack": "Volgend nummer", "ButtonPause": "Pauze", "ButtonPlay": "Afspelen", "ButtonEdit": "Bewerken", "ButtonQueue": "Wachtrij", "ButtonPlayTrailer": "Trailer Afspelen", "ButtonPlaylist": "Afspeellijst", + "ButtonPreviousTrack": "Vorig nummer", "LabelEnabled": "Ingeschakeld", "LabelDisabled": "Uitgeschakeld", "ButtonMoreInformation": "Meer informatie", @@ -128,7 +122,7 @@ "MessageConfirmItemGrouping": "Media Browser clients zullen automatisch de optimale versie afspelen op basis van het apparaat en de prestaties van het netwerk. Weet u zeker dat u wilt doorgaan?", "HeaderResume": "Hervatbaar", "HeaderMyViews": "Mijn weergaves", - "HeaderLibraryFolders": "Mapweergave", + "HeaderLibraryFolders": "Media Mappen", "HeaderLatestMedia": "Nieuw in bibliotheek", "ButtonMore": "Meer ...", "HeaderFavoriteMovies": "Favoriete Films", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "De download is in de wachtrij geplaatst.", "MessageAreYouSureDeleteSubtitles": "Weet u zeker dat u dit ondertitelbestand wilt verwijderen?", "ButtonRemoteControl": "Beheer op afstand", - "HeaderLatestTvRecordings": "Nieuwste opnames" + "HeaderLatestTvRecordings": "Nieuwste opnames", + "ButtonOk": "Ok", + "ButtonCancel": "Annuleren", + "ButtonRefresh": "Vernieuwen", + "LabelCurrentPath": "Huidige pad:", + "HeaderSelectMediaPath": "Selecteer Media Pad", + "ButtonNetwork": "Netwerk", + "MessageDirectoryPickerInstruction": "Netwerk paden kunnen handmatig worden ingevoerd in het geval de Netwerk knop faalt om uw apparatuur te lokaliseren . Bijvoorbeeld: {0} of {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json index 609c8e477c..5b1667db68 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Criar Senha", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Por favor, selecione dois ou mais itens para agrupar.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Minha Biblioteca", "SettingsSaved": "Ajustes salvos.", "AddUser": "Adicionar Usu\u00e1rio", "Users": "Usu\u00e1rios", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Idioma desconhecido", "ButtonMute": "Mudo", "ButtonUnmute": "Remover Mudo", + "ButtonNextTrack": "Pr\u00f3xima faixa", "ButtonPause": "Pausar", "ButtonPlay": "Reproduzir", "ButtonEdit": "Editar", "ButtonQueue": "Fila", "ButtonPlayTrailer": "Reproduzir Trailer", "ButtonPlaylist": "Lista reprodu\u00e7\u00e3o", + "ButtonPreviousTrack": "Faixa anterior", "LabelEnabled": "Ativada", "LabelDisabled": "Desativada", "ButtonMoreInformation": "Mais informa\u00e7\u00f5es", @@ -127,8 +121,8 @@ "MessageTheFollowingItemsWillBeGrouped": "Os seguintes t\u00edtulos ser\u00e3o agrupados em um \u00fanico item:", "MessageConfirmItemGrouping": "Os clientes do Media Browser escolher\u00e3o automaticamente a vers\u00e3o ideal para reproduzir com base no performance do dispositivo e da rede. Tem certeza que deseja continuar?", "HeaderResume": "Retomar", - "HeaderMyViews": "My Views", - "HeaderLibraryFolders": "Visualiza\u00e7\u00e3o da Pasta", + "HeaderMyViews": "Minhas Visualiza\u00e7\u00f5es", + "HeaderLibraryFolders": "Pastas de M\u00eddias", "HeaderLatestMedia": "M\u00eddias Recentes", "ButtonMore": "Mais...", "HeaderFavoriteMovies": "Filmes Favoritos", @@ -192,6 +186,13 @@ "HeaderCurrentSubtitles": "Legendas Atuais", "MessageDownloadQueued": "O download foi enfileirado.", "MessageAreYouSureDeleteSubtitles": "Tem certeza que deseja excluir este arquivo de legendas?", - "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "ButtonRemoteControl": "Controle Remoto", + "HeaderLatestTvRecordings": "\u00daltimas Grava\u00e7\u00f5es", + "ButtonOk": "Ok", + "ButtonCancel": "Cancelar", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json index 89d5c217be..b996b70753 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Criar Senha", - "OptionOff": "Desligado", - "OptionOn": "Ligado", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "Configura\u00e7\u00f5es guardadas.", "AddUser": "Adicionar Utilizador", "Users": "Utilizadores", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Pr\u00f3xima Faixa", "ButtonPause": "Pausar", "ButtonPlay": "Reproduzir", "ButtonEdit": "Editar", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Faixa Anterior", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Cancelar", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json index e64ac36065..3661e5f601 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json @@ -1,12 +1,4 @@ { - "CreatePassword": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c", - "OptionOff": "\u0412\u044b\u043a\u043b", - "OptionOn": "\u0412\u043a\u043b", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0432\u0430 \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430", "SettingsSaved": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0431\u044b\u043b\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b.", "AddUser": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "Users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438", @@ -66,15 +58,17 @@ "LabelUnknownLanguage": "\u041d\u0435\u043e\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a", "ButtonMute": "\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0437\u0432\u0443\u043a", "ButtonUnmute": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0437\u0432\u0443\u043a", + "ButtonNextTrack": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", "ButtonPause": "\u041f\u0430\u0443\u0437\u0430", "ButtonPlay": "\u0412\u043e\u0441\u043f\u0440", "ButtonEdit": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c", "ButtonQueue": "\u041e\u0447\u0435\u0440\u0435\u0434\u044c", "ButtonPlayTrailer": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u0440\u0435\u0439\u043b\u0435\u0440", "ButtonPlaylist": "\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f", + "ButtonPreviousTrack": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", "LabelEnabled": "\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e", "LabelDisabled": "\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e", - "ButtonMoreInformation": "\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f", + "ButtonMoreInformation": "\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f", "LabelNoUnreadNotifications": "\u041d\u0435\u0442 \u043d\u0435\u043f\u0440\u043e\u0447\u0442\u0451\u043d\u043d\u044b\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439.", "ButtonViewNotifications": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f", "ButtonMarkTheseRead": "\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u043e\u0447\u0442\u0451\u043d\u043d\u044b\u0435", @@ -130,7 +124,7 @@ "HeaderMyViews": "\u041c\u043e\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f", "HeaderLibraryFolders": "\u041c\u0435\u0434\u0438\u0430\u043f\u0430\u043f\u043a\u0438", "HeaderLatestMedia": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u043e\u0432", - "ButtonMore": "\u0411\u043e\u043b\u0435\u0435...", + "ButtonMore": "\u0415\u0449\u0451...", "HeaderFavoriteMovies": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u043c\u044b", "HeaderFavoriteShows": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u044b", "HeaderFavoriteEpisodes": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u044d\u043f\u0438\u0437\u043e\u0434\u044b", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c.", "MessageAreYouSureDeleteSubtitles": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441\u0443\u0431\u0438\u0442\u0440\u043e\u0432?", "ButtonRemoteControl": "\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e", - "HeaderLatestTvRecordings": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439" + "HeaderLatestTvRecordings": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439", + "ButtonOk": "\u041e\u041a", + "ButtonCancel": "\u041e\u0442\u043c\u0435\u043d\u0430", + "ButtonRefresh": "\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c", + "LabelCurrentPath": "\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0443\u0442\u044c:", + "HeaderSelectMediaPath": "\u0412\u044b\u0431\u043e\u0440 \u043f\u0443\u0442\u0438 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044f", + "ButtonNetwork": "\u0421\u0435\u0442\u044c", + "MessageDirectoryPickerInstruction": "\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u043f\u0443\u0442\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0421\u0435\u0442\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u0431\u043e\u0439 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, {0} \u0438\u043b\u0438 {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json index 47f2b8fdb2..7bb4f54092 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Av", - "OptionOn": "P\u00e5", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "V\u00e4lj tv\u00e5 eller flera objekt att gruppera.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "Mitt bibliotek", "SettingsSaved": "Inst\u00e4llningarna sparade.", "AddUser": "Skapa anv\u00e4ndare", "Users": "Anv\u00e4ndare", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Ok\u00e4nt spr\u00e5k", "ButtonMute": "Tyst", "ButtonUnmute": "Muting av", + "ButtonNextTrack": "N\u00e4sta sp\u00e5r", "ButtonPause": "Paus", "ButtonPlay": "Spela upp", "ButtonEdit": "\u00c4ndra", "ButtonQueue": "K\u00f6", "ButtonPlayTrailer": "Spela upp trailer", "ButtonPlaylist": "Spellista", + "ButtonPreviousTrack": "F\u00f6reg\u00e5ende sp\u00e5r", "LabelEnabled": "Aktiverad", "LabelDisabled": "Avaktiverad", "ButtonMoreInformation": "Mer information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "Nedladdningen har lagts i k\u00f6n.", "MessageAreYouSureDeleteSubtitles": "\u00c4r du s\u00e4ker p\u00e5 att du vill radera den h\u00e4r undertextfilen?", "ButtonRemoteControl": "Fj\u00e4rrkontroll", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Senaste inspelningar", + "ButtonOk": "OK", + "ButtonCancel": "Avbryt", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json index 8963853af1..9feeb51832 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json @@ -1,12 +1,4 @@ { - "CreatePassword": "Create Password", - "OptionOff": "Off", - "OptionOn": "On", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "L\u01b0u c\u00e1c c\u00e0i \u0111\u1eb7t.", "AddUser": "Th\u00eam ng\u01b0\u1eddi d\u00f9ng", "Users": "Ng\u01b0\u1eddi d\u00f9ng", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "Play", "ButtonEdit": "Edit", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "Ok", + "ButtonCancel": "Tho\u00e1t", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json index 85ccd54eb3..7bd50e2ca9 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json @@ -1,12 +1,4 @@ { - "CreatePassword": "\u5275\u5efa\u5bc6\u78bc", - "OptionOff": "\u95dc\u9589", - "OptionOn": "\u958b\u555f", - "LabelAborted": "(Aborted by server shutdown)", - "MessagePleaseSelectItemsToGroup": "Please select two or more items to group together.", - "ButtonNextTrack": "Next Track", - "ButtonPreviousTrack": "Previous Track", - "HeaderMyLibrary": "My Library", "SettingsSaved": "\u8a2d\u7f6e\u5df2\u4fdd\u5b58\u3002", "AddUser": "\u6dfb\u52a0\u7528\u6236", "Users": "\u7528\u6236", @@ -66,12 +58,14 @@ "LabelUnknownLanguage": "Unknown language", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", + "ButtonNextTrack": "Next track", "ButtonPause": "Pause", "ButtonPlay": "\u64ad\u653e", "ButtonEdit": "\u7de8\u8f2f", "ButtonQueue": "Queue", "ButtonPlayTrailer": "PlayTrailer", "ButtonPlaylist": "Playlist", + "ButtonPreviousTrack": "Previous track", "LabelEnabled": "Enabled", "LabelDisabled": "Disabled", "ButtonMoreInformation": "More Information", @@ -193,5 +187,12 @@ "MessageDownloadQueued": "The download has been queued.", "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", "ButtonRemoteControl": "Remote Control", - "HeaderLatestTvRecordings": "Latest Recordings" + "HeaderLatestTvRecordings": "Latest Recordings", + "ButtonOk": "OK", + "ButtonCancel": "\u53d6\u6d88", + "ButtonRefresh": "Refresh", + "LabelCurrentPath": "Current path:", + "HeaderSelectMediaPath": "Select Media Path", + "ButtonNetwork": "Network", + "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ar.json b/MediaBrowser.Server.Implementations/Localization/Server/ar.json index ef58f37f9c..82a5cb4228 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ar.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ar.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "\u0639\u0631\u0636 \u0641\u0642\u0637 \u0627\u0644\u062a\u0631\u062c\u0645\u0627\u062a \u0627\u0644\u0642\u0633\u0631\u064a\u0629", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "\u062e\u0631\u0648\u062c", "LabelVisitCommunity": "\u0632\u064a\u0627\u0631\u0629 \u0627\u0644\u0645\u062c\u062a\u0645\u0639", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ca.json b/MediaBrowser.Server.Implementations/Localization/Server/ca.json index 05f5190566..13e14f7b44 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ca.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Sortir", "LabelVisitCommunity": "Visitar la comunitat", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/cs.json b/MediaBrowser.Server.Implementations/Localization/Server/cs.json index 167e21db82..b9f7fba6fe 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/cs.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/cs.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Aktualizace", - "HeaderUpdateLevel": "Level aktualizace", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Zobrazit pouze vynucen\u00e9 titulky", - "HeaderCustomizeOptionsPerMediaType": "Upravit nastaven\u00ed podle typu m\u00e9dia", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Chyba", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Zav\u0159\u00edt", "LabelVisitCommunity": "Nav\u0161t\u00edvit komunitu", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Herci a obsazen\u00ed", "HeaderAdditionalParts": "Dal\u0161\u00ed sou\u010d\u00e1sti", "ButtonSplitVersionsApart": "Rozd\u011blit verze od sebe", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Chyb\u00ed", "LabelOffline": "Offline", "PathSubstitutionHelp": "Nahrazen\u00ed cest se pou\u017e\u00edv\u00e1 pro namapov\u00e1n\u00ed cest k serveru, kter\u00e9 je p\u0159\u00edstupn\u00e9 u\u017eivateli. Povolen\u00edm p\u0159\u00edm\u00e9ho p\u0159\u00edstupu m\u016f\u017ee umo\u017enit u\u017eivateli jeho p\u0159ehr\u00e1n\u00ed bez u\u017eit\u00ed streamov\u00e1n\u00ed a p\u0159ek\u00f3dov\u00e1n\u00ed servru.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Klienti", "LabelCompleted": "Hotovo", + "LabelFailed": "Chyba", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/da.json b/MediaBrowser.Server.Implementations/Localization/Server/da.json index e6ea74d50d..ac070a3520 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/da.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/da.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "Mit bibliotek", - "HeaderLibraryViews": "Library Views", "LabelExit": "Afslut", "LabelVisitCommunity": "Bes\u00f8g F\u00e6lleskab", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scener", "ButtonSubtitles": "Undertekster", "ButtonAudioTracks": "Lyd filer", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/de.json b/MediaBrowser.Server.Implementations/Localization/Server/de.json index c0e2415c2b..c5fc62bed3 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/de.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Zeige nur erzwungene Untertitel", - "HeaderCustomizeOptionsPerMediaType": "Passe die Optionen per Medientyp an", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Gescheitert", - "LabelSeries": "Serien:", - "ButtonPreviousTrack": "Vorheriger Track", - "ButtonNextTrack": "N\u00e4chster Track", - "HeaderMyLibrary": "Meine Bibliothek", - "HeaderLibraryViews": "Library Views", "LabelExit": "Ende", "LabelVisitCommunity": "Besuche die Community", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Besetzung & Crew", "HeaderAdditionalParts": "Zus\u00e4tzliche Teile", "ButtonSplitVersionsApart": "Spalte Versionen ab", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Fehlend", "LabelOffline": "Offline", "PathSubstitutionHelp": "Pfad Substitutionen werden zum Abbilden eines Pfad auf dem Server zu einem Pfad der Clients direkt zugreifen k\u00f6nnen, verwendet. Weil Clients direkten Zugang zu den Medien auf dem Server haben, sind sie in der Lage die Medien direkt \u00fcber das Netzwerk zu spielen und dabei vermeiden sie die nutzung von Server-Ressourcen f\u00fcr streaming transkodieren.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programm", "HeaderClients": "Clients", "LabelCompleted": "Fertiggestellt", + "LabelFailed": "Gescheitert", "LabelSkipped": "\u00dcbersprungen", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Serien:", "LabelSeasonNumber": "Staffelnummer", "LabelEpisodeNumber": "Episodennummer", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Szenen", "ButtonSubtitles": "Untertitel", "ButtonAudioTracks": "Audiospuren", + "ButtonPreviousTrack": "Vorheriger Track", + "ButtonNextTrack": "N\u00e4chster Track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Gruppiere Filme in Collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/el.json b/MediaBrowser.Server.Implementations/Localization/Server/el.json index 1caf760b13..fd439fdc4e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/el.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/el.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "\u03ad\u03be\u03bf\u03b4\u03bf\u03c2", "LabelVisitCommunity": "\u0395\u03c0\u03af\u03c3\u03ba\u03b5\u03c8\u03b7 \u039a\u03bf\u03b9\u03bd\u03cc\u03c4\u03b7\u03c4\u03b1", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json index 751d1e4682..4d4a24ce1b 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customise options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Exit", "LabelVisitCommunity": "Visit Community", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json index 503e8e8d67..91588bdaab 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Exit", "LabelVisitCommunity": "Visit Community", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es.json b/MediaBrowser.Server.Implementations/Localization/Server/es.json index 5819ab3397..9811cb9511 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/es.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/es.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Actualizaciones", - "HeaderUpdateLevel": "Nivel de actualizaci\u00f3n", - "LabelRequireTextSubtitles": "Descarga incluso si el v\u00eddeo ya contiene subt\u00edtulos gr\u00e1ficos", - "LabelRequireTextSubtitlesHelp": "Mantener versiones de texto de los subt\u00edtulos se traducir\u00e1 en una prestaci\u00f3n m\u00e1s eficiente para los clientes m\u00f3viles.", - "HeaderSubtitleDownloadingMoreHelp": "Los subt\u00edtulos se consideran faltantes cuando la pista de audio est\u00e1 en un idioma extranjero, y no hay subt\u00edtulos disponibles en el idioma preferido.", - "LabelDisplayForcedSubtitlesOnly": "Mostrar \u00fanicamente subtitulos forzados", - "HeaderCustomizeOptionsPerMediaType": "Personalizar las opciones por tipo de medio", - "LabelAudioLanguagePreferenceHelp": "Si est\u00e1 vac\u00edo, se seleccionar\u00e1 la pista de audio por defecto, sin importar el idioma.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "Todos los dispositivos", - "HeaderThisDevice": "Este dispositivo", - "OptionLibraryButtons": "Botones de biblioteca", - "OptionLibraryTiles": "T\u00edtulos de biblioteca", - "OptionSmallLibraryTiles": "T\u00edtulos de librer\u00eda (peque\u00f1o)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Err\u00f3neo", - "LabelSeries": "Serie:", - "ButtonPreviousTrack": "Pista anterior", - "ButtonNextTrack": "Pista siguiente", - "HeaderMyLibrary": "Mi librer\u00eda", - "HeaderLibraryViews": "Vistas de librer\u00eda", "LabelExit": "Salir", "LabelVisitCommunity": "Visitar la comunidad", "LabelGithubWiki": "Wiki de Github", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Reparto y equipo t\u00e9cnico", "HeaderAdditionalParts": "Partes adicionales", "ButtonSplitVersionsApart": "Dividir versiones aparte", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Falta", "LabelOffline": "Apagado", "PathSubstitutionHelp": "Las rutas alternativas se utilizan para mapear una ruta en el servidor a la que los clientes puedan acceder. El permitir que los clientes se conecten directamente a trav\u00e9s de la red y puedan reproducir los medios directamente, evita utilizar recursos del servidor para la transcodificaci\u00f3n y el stream,", @@ -512,8 +479,10 @@ "HeaderProgram": "Programa", "HeaderClients": "Clientes", "LabelCompleted": "Completado", + "LabelFailed": "Err\u00f3neo", "LabelSkipped": "Omitido", "HeaderEpisodeOrganization": "Organizaci\u00f3n de episodios", + "LabelSeries": "Serie:", "LabelSeasonNumber": "Temporada n\u00famero:", "LabelEpisodeNumber": "Episodio n\u00famero:", "LabelEndingEpisodeNumber": "N\u00famero episodio final:", @@ -661,6 +630,8 @@ "ButtonScenes": "Escenas", "ButtonSubtitles": "Subt\u00edtulos", "ButtonAudioTracks": "Pistas de audio", + "ButtonPreviousTrack": "Pista anterior", + "ButtonNextTrack": "Pista siguiente", "ButtonStop": "Detener", "ButtonPause": "Pausa", "LabelGroupMoviesIntoCollections": "Agrupar pel\u00edculas en colecciones", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Secci\u00f3n dos de la p\u00e1gina de inicio:", "LabelHomePageSection3": "Secci\u00f3n tres de la p\u00e1gina de inicio:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "Mi librer\u00eda (botones)", - "OptionMyLibrary": "Mi librer\u00eda", - "OptionMyLibrarySmall": "Mi librer\u00eda (peque\u00f1o)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Continuar", "OptionLatestMedia": "\u00daltimos medios", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Mostrar contenido para adultos", "OptionLibraryFolders": "Vista de carpeta", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json index 741646596f..407cd6ace7 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "Cuando los usuarios reproduzcan contenidos", - "HeaderEnableNotificationForEvents": "Enviar notificaciones para los siguientes eventos:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Cuando se encuentren disponibles actualizaciones", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Cuando las tareas programadas fallen", - "OptionNotifyOnNewLibraryContent": "Cuando se a\u00f1adan nuevos contenidos a la biblioteca", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Actualizaciones", - "HeaderUpdateLevel": "Nivel de Actualizaci\u00f3n", - "LabelRequireTextSubtitles": "Descargar a\u00fan cuando el video ya contiene subt\u00edtulos gr\u00e1ficos", - "LabelRequireTextSubtitlesHelp": "Mantener versiones de texto de los subt\u00edtulos resultar\u00e1 en una entrega m\u00e1s eficiente para clientes m\u00f3viles.", - "HeaderSubtitleDownloadingMoreHelp": "Los subt\u00edtulos se consideran como faltantes cuando la pista de audio se encuentra en un lenguaje extranjero y no se cuenta con subt\u00edtulos disponibles en el lenguaje preferido.", - "LabelDisplayForcedSubtitlesOnly": "Mostrar \u00fanicamente subtitulos forzados", - "HeaderCustomizeOptionsPerMediaType": "Personalice opciones por tipo de medio", - "LabelAudioLanguagePreferenceHelp": "Si se deja vac\u00edo, la pista de audio por defecto ser\u00e1 seleccionada, independientemente del lenguaje.", - "TabCustomizations": "Personalizaciones", - "HeaderAllDevices": "Todos los Dispositivos", - "HeaderThisDevice": "Este Dispositivo", - "OptionLibraryButtons": "Botones de la biblioteca", - "OptionLibraryTiles": "Mosaicos de biblioteca (largo)", - "OptionSmallLibraryTiles": "Mosaicos de biblioteca (peque\u00f1o)", - "ButtonPlayTrailer": "Avance", - "LabelFailed": "Fallido", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Pista Anterior", - "ButtonNextTrack": "Pista Siguiente", - "HeaderMyLibrary": "Mi Biblioteca", - "HeaderLibraryViews": "Vistas de Biblioteca", "LabelExit": "Salir", "LabelVisitCommunity": "Visitar la Comunidad", "LabelGithubWiki": "Wiki de Github", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Reparto y Personal", "HeaderAdditionalParts": "Partes Adicionales", "ButtonSplitVersionsApart": "Separar Versiones", + "ButtonPlayTrailer": "Avance", "LabelMissing": "Falta", "LabelOffline": "Desconectado", "PathSubstitutionHelp": "Las rutas alternativas se utilizan para mapear una ruta en el servidor a la que los clientes puedan acceder. Al permitir a los clientes acceder directamente a los medios en el servidor podr\u00e1n reproducirlos directamente a trav\u00e9s de la red evitando el uso de recursos del servidor para transmitirlos y transcodificarlos.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programa", "HeaderClients": "Clientes", "LabelCompleted": "Completado", + "LabelFailed": "Fallido", "LabelSkipped": "Omitido", "HeaderEpisodeOrganization": "Organizaci\u00f3n de Episodios", + "LabelSeries": "Series:", "LabelSeasonNumber": "N\u00famero de temporada", "LabelEpisodeNumber": "N\u00famero de episodio", "LabelEndingEpisodeNumber": "N\u00famero episodio final", @@ -661,6 +630,8 @@ "ButtonScenes": "Escenas", "ButtonSubtitles": "Subt\u00edtulos", "ButtonAudioTracks": "Pistas de audio", + "ButtonPreviousTrack": "Pista Anterior", + "ButtonNextTrack": "Pista Siguiente", "ButtonStop": "Detener", "ButtonPause": "Pausar", "LabelGroupMoviesIntoCollections": "Agrupar pel\u00edculas en colecciones", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Pagina principal secci\u00f3n dos:", "LabelHomePageSection3": "Pagina principal secci\u00f3n tres:", "LabelHomePageSection4": "Pagina principal secci\u00f3n cuatro:", - "OptionMyLibraryButtons": "Mi Biblioteca (botones)", - "OptionMyLibrary": "Mi Biblioteca", - "OptionMyLibrarySmall": "Mi Biblioteca (peque\u00f1o)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Reanudar", "OptionLatestMedia": "Agregados recientemente", "OptionLatestChannelMedia": "Elementos recientes de canales", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Desplegar contenido para Adultos", "OptionLibraryFolders": "Carpetas de medios", "TitleRemoteControl": "Control Remoto", - "OptionLatestTvRecordings": "\u00daltimas grabaciones" + "OptionLatestTvRecordings": "\u00daltimas grabaciones", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fr.json b/MediaBrowser.Server.Implementations/Localization/Server/fr.json index 3975d5b43d..299868a541 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/fr.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Mises \u00e0 jour", - "HeaderUpdateLevel": "Niveau de mise \u00e0 jour", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Les sous-titres son consid\u00e9r\u00e9s manquants lorsque la piste audio est dans une langue \u00e9trang\u00e8re, et qu'aucun sous-titre n'est disponible dans la langue pr\u00e9f\u00e9r\u00e9e.", - "LabelDisplayForcedSubtitlesOnly": "Afficher seulement les sous-titres forc\u00e9s", - "HeaderCustomizeOptionsPerMediaType": "Personnaliser les param\u00e8tres par type de m\u00e9dias", - "LabelAudioLanguagePreferenceHelp": "Si laiss\u00e9 vide, la piste audio par d\u00e9faut sera s\u00e9lectionn\u00e9e, peu importe la langue.", - "TabCustomizations": "Personnalisations", - "HeaderAllDevices": "Tous les appareils", - "HeaderThisDevice": "Cet appareil", - "OptionLibraryButtons": "Boutons de r\u00e9pertoires de m\u00e9dias", - "OptionLibraryTiles": "Tuiles de r\u00e9pertoires de m\u00e9dias", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Bande-annonce", - "LabelFailed": "\u00c9chec", - "LabelSeries": "S\u00e9ries:", - "ButtonPreviousTrack": "Piste pr\u00e9c\u00e9dante", - "ButtonNextTrack": "Piste suivante", - "HeaderMyLibrary": "Ma biblioth\u00e8que", - "HeaderLibraryViews": "Library Views", "LabelExit": "Quitter", "LabelVisitCommunity": "Visiter la Communaut\u00e9", "LabelGithubWiki": "GitHub Wiki", @@ -268,7 +234,7 @@ "ButtonSelect": "S\u00e9lectionner", "ButtonSearch": "Recherche", "ButtonGroupVersions": "Versions des groupes", - "ButtonAddToCollection": "Add to Collection", + "ButtonAddToCollection": "Ajouter \u00e0 la Collection", "PismoMessage": "En utilisation de \"Pismo File Mount\" par une license fournie.", "TangibleSoftwareMessage": "Utilisation de convertisseurs Tangible Solutions Java\/C# par licence fournie.", "HeaderCredits": "Cr\u00e9dits", @@ -430,6 +396,7 @@ "HeaderCastCrew": "\u00c9quipe de tournage", "HeaderAdditionalParts": "Parties Additionelles", "ButtonSplitVersionsApart": "S\u00e9parer les versions", + "ButtonPlayTrailer": "Bande-annonce", "LabelMissing": "Manquant(s)", "LabelOffline": "Hors ligne", "PathSubstitutionHelp": "Les substitutions de chemins d'acc\u00e8s sont utilis\u00e9es pour faire correspondre un chemin d'acc\u00e8s du serveur \u00e0 un chemin d'acc\u00e8s accessible par les clients. En autorisant un acc\u00e8s direct aux m\u00e9dias du serveur, les clients pourront les lire directement du r\u00e9seau et \u00e9viter l'utilisation inutiles des ressources du serveur en demandant du transcodage.", @@ -484,8 +451,8 @@ "LabelPreferredDisplayLanguageHelp": "La traduction de Media Browser est un projet en cours et n'est pas compl\u00e9t\u00e9e encore.", "LabelReadHowYouCanContribute": "Lire comment vous pouvez contribuer.", "HeaderNewCollection": "Nouvelle collection", - "HeaderAddToCollection": "Add to Collection", - "ButtonSubmit": "Submit", + "HeaderAddToCollection": "Ajouter \u00e0 la Collection", + "ButtonSubmit": "Soumettre", "NewCollectionNameExample": "Exemple: Collection Star Wars", "OptionSearchForInternetMetadata": "Rechercher sur Internet les images et m\u00e9tadonn\u00e9es", "ButtonCreate": "Cr\u00e9er", @@ -512,8 +479,10 @@ "HeaderProgram": "Programme", "HeaderClients": "Clients", "LabelCompleted": "Compl\u00e9t\u00e9", + "LabelFailed": "\u00c9chec", "LabelSkipped": "Saut\u00e9", "HeaderEpisodeOrganization": "Organisation d'\u00e9pisodes", + "LabelSeries": "S\u00e9ries:", "LabelSeasonNumber": "Num\u00e9ro de saison", "LabelEpisodeNumber": "Num\u00e9ro d'\u00e9pisode", "LabelEndingEpisodeNumber": "Num\u00e9ro d'\u00e9pisode se terminant", @@ -593,7 +562,7 @@ "LabelDefaultUser": "Utilisateur par d\u00e9faut:", "LabelDefaultUserHelp": "D\u00e9termine quelle biblioth\u00e8que d'utilisateur doit \u00eatre afficher sur les appareils connect\u00e9s. Ces param\u00e8tres peuvent \u00eatre remplac\u00e9s pour chaque appareil par les configurations de profils.", "TitleDlna": "DLNA", - "TitleChannels": "Channels", + "TitleChannels": "Cha\u00eenes", "HeaderServerSettings": "Param\u00e8tres du serveur", "LabelWeatherDisplayLocation": "Emplacement de l'affichage de la m\u00e9t\u00e9o:", "LabelWeatherDisplayLocationHelp": "Code ZIP US \/ Ville, \u00c9tat, Pays \/ Ville, Pays", @@ -661,6 +630,8 @@ "ButtonScenes": "Sc\u00e8nes", "ButtonSubtitles": "Sous-titres", "ButtonAudioTracks": "Piste audio", + "ButtonPreviousTrack": "Piste pr\u00e9c\u00e9dante", + "ButtonNextTrack": "Piste suivante", "ButtonStop": "Arr\u00eat", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Grouper les films en collections", @@ -755,8 +726,8 @@ "LabelSkipIfGraphicalSubsPresent": "Sauter la vid\u00e9o si elle contient d\u00e9j\u00e0 des sous-titres graphiques", "LabelSkipIfGraphicalSubsPresentHelp": "Garder des versions textes des sous-titres va \u00eatre plus efficace avec les appareils mobiles.", "TabSubtitles": "Sous-titres", - "TabChapters": "Chapters", - "HeaderDownloadChaptersFor": "Download chapter names for:", + "TabChapters": "Chapitres:", + "HeaderDownloadChaptersFor": "T\u00e9l\u00e9charger les noms de chapitre pour:", "LabelOpenSubtitlesUsername": "Nom d'utilisateur de Open Subtitles:", "LabelOpenSubtitlesPassword": "Mot de passe de Open Subtitles:", "HeaderChapterDownloadingHelp": "When Media Browser scans your video files it can download friendly chapter names from the internet using chapter plugins such as ChapterDb.", @@ -799,14 +770,14 @@ "LabelHomePageSection1": "Section 1 de la page de d\u00e9marrage:", "LabelHomePageSection2": "Section 2 de la page de d\u00e9marrage:", "LabelHomePageSection3": "Section 3 de la page de d\u00e9marrage:", - "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "LabelHomePageSection4": "Section 4 de la page de d\u00e9marrage:", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Reprendre", "OptionLatestMedia": "Les plus r\u00e9cents", - "OptionLatestChannelMedia": "Latest channel items", - "HeaderLatestChannelItems": "Latest Channel Items", + "OptionLatestChannelMedia": "Items de cha\u00eene les plus r\u00e9cents", + "HeaderLatestChannelItems": "Items de cha\u00eene les plus r\u00e9cents", "OptionNone": "Aucun", "HeaderLiveTv": "TV en directe", "HeaderReports": "Rapports", @@ -818,35 +789,37 @@ "OptionCommunityMostWatchedSort": "Les plus \u00e9cout\u00e9s", "TabNextUp": "Prochains \u00e0 voir", "MessageNoMovieSuggestionsAvailable": "Aucune suggestion de film n'est actuellement disponible. Commencez \u00e0 regarder et noter vos films pour avoir des suggestions.", - "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the New button to start creating Collections.", + "MessageNoCollectionsAvailable": "Les Collections permettent le groupement de films, S\u00e9ries, Albums, Livres et Jeux. Cliquer sur \"Nouveau\" pour commencer la cr\u00e9ation des Collections.", "HeaderWelcomeToMediaBrowserWebClient": "Bienvenue au client Web Media Browser", - "ButtonDismiss": "Dismiss", - "MessageLearnHowToCustomize": "Learn how to customize this page to your own personal tastes. Click your user icon in the top right corner of the screen to view and update your preferences.", - "ButtonEditOtherUserPreferences": "Edit this user's personal preferences.", + "ButtonDismiss": "Annuler", + "MessageLearnHowToCustomize": "Apprenez comment personnaliser cette page selon vos propres go\u00fbts. S\u00e9lectionnez votre ic\u00f4ne d'utilisateur dans le coin en haut, \u00e0 droite de l'\u00e9cran pour visionner et mettre \u00e0 jour vos pr\u00e9f\u00e9rences. ", + "ButtonEditOtherUserPreferences": "Modifier les pr\u00e9f\u00e9rences personnelles de cet utilisateur.", "LabelChannelStreamQuality": "Preferred internet stream quality:", "LabelChannelStreamQualityHelp": "In a low bandwidth environment, limiting quality can help ensure a smooth streaming experience.", - "OptionBestAvailableStreamQuality": "Best available", - "LabelEnableChannelContentDownloadingFor": "Enable channel content downloading for:", + "OptionBestAvailableStreamQuality": "Meilleur disponible", + "LabelEnableChannelContentDownloadingFor": "Activer le t\u00e9l\u00e9chargement de contenu de cha\u00eene pour:", "LabelEnableChannelContentDownloadingForHelp": "Some channels support downloading content prior to viewing. Enable this in low bandwidth enviornments to download channel content during off hours. Content is downloaded as part of the channel download scheduled task.", - "LabelChannelDownloadPath": "Channel content download path:", + "LabelChannelDownloadPath": "Chemin d'acc\u00e8s de t\u00e9l\u00e9chargement de contenu de cha\u00eene:", "LabelChannelDownloadPathHelp": "Specify a custom download path if desired. Leave empty to download to an internal program data folder.", - "LabelChannelDownloadAge": "Delete content after: (days)", - "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", - "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", - "ViewTypeMovies": "Movies", + "LabelChannelDownloadAge": "Supprimer le contenu apr\u00e8s: (jours)", + "LabelChannelDownloadAgeHelp": "Le contenu t\u00e9l\u00e9charg\u00e9 plus vieux sera supprim\u00e9. Par contre, il sera toujours disponible par flux Internet (en ligne).", + "ChannelSettingsFormHelp": "Installer des cha\u00eenes comme \"Trailers\" and \"Vimeo\" par le catalogue de Plugins.", + "LabelSelectCollection": "S\u00e9lectionner collection:", + "ViewTypeMovies": "Films", "ViewTypeTvShows": "TV", - "ViewTypeGames": "Games", - "ViewTypeMusic": "Music", + "ViewTypeGames": "Jeux", + "ViewTypeMusic": "Musique", "ViewTypeBoxSets": "Collections", - "ViewTypeChannels": "Channels", - "ViewTypeLiveTV": "Live TV", - "HeaderOtherDisplaySettings": "Display Settings", - "HeaderMyViews": "My Views", + "ViewTypeChannels": "Cha\u00eenes", + "ViewTypeLiveTV": "TV en directe", + "HeaderOtherDisplaySettings": "Param\u00e8tres d'affichage", + "HeaderMyViews": "Mes affichages", "LabelSelectFolderGroups": "Automatically group content from the following folders into views such as Movies, Music and TV:", "LabelSelectFolderGroupsHelp": "Folders that are unchecked will be displayed by themselves in their own view.", - "OptionDisplayAdultContent": "Display adult content", - "OptionLibraryFolders": "Media folders", - "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionDisplayAdultContent": "Afficher le contenu adulte", + "OptionLibraryFolders": "R\u00e9pertoires de m\u00e9dias", + "TitleRemoteControl": "Acc\u00e8s \u00e0 distance", + "OptionLatestTvRecordings": "Les plus r\u00e9cents enregistrements", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/he.json b/MediaBrowser.Server.Implementations/Localization/Server/he.json index 66c33c3d9e..28bb4a4bfc 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/he.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/he.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "\u05e2\u05d9\u05d3\u05db\u05d5\u05e0\u05d9\u05dd", - "HeaderUpdateLevel": "\u05e8\u05de\u05ea \u05d4\u05e2\u05d9\u05d3\u05db\u05d5\u05df", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "\u05d4\u05e6\u05d2 \u05e8\u05e7 \u05db\u05ea\u05d5\u05d1\u05d9\u05d5\u05ea \u05de\u05d0\u05d5\u05dc\u05e6\u05d5\u05ea", - "HeaderCustomizeOptionsPerMediaType": "\u05d0\u05e4\u05e9\u05e8\u05d5\u05d9\u05d5\u05ea \u05d4\u05ea\u05d0\u05de\u05d4 \u05dc\u05e4\u05d9 \u05e1\u05d5\u05d2 \u05de\u05d3\u05d9\u05d4", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "\u05d8\u05e8\u05d9\u05d9\u05dc\u05e8\u05d9\u05dd", - "LabelFailed": "\u05e0\u05db\u05e9\u05dc", - "LabelSeries": "\u05e1\u05d3\u05e8\u05d4:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "\u05d9\u05e6\u05d9\u05d0\u05d4", "LabelVisitCommunity": "\u05d1\u05e7\u05e8 \u05d1\u05e7\u05d4\u05d9\u05dc\u05d4", "LabelGithubWiki": "\u05e1\u05e4\u05e8\u05d9\u05d9\u05ea \u05d4\u05e7\u05d5\u05d3", @@ -430,6 +396,7 @@ "HeaderCastCrew": "\u05e9\u05d7\u05e7\u05e0\u05d9\u05dd \u05d5\u05e6\u05d5\u05d5\u05ea", "HeaderAdditionalParts": "\u05d7\u05dc\u05e7\u05d9\u05dd \u05e0\u05d5\u05e1\u05e4\u05d9\u05dd", "ButtonSplitVersionsApart": "\u05e4\u05e6\u05dc \u05d2\u05e8\u05e1\u05d0\u05d5\u05ea \u05d1\u05e0\u05e4\u05e8\u05d3", + "ButtonPlayTrailer": "\u05d8\u05e8\u05d9\u05d9\u05dc\u05e8\u05d9\u05dd", "LabelMissing": "\u05d7\u05e1\u05e8", "LabelOffline": "\u05dc\u05d0 \u05de\u05e7\u05d5\u05d5\u05df", "PathSubstitutionHelp": "\u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05d7\u05dc\u05d5\u05e4\u05d9\u05d9\u05dd \u05d4\u05dd \u05dc\u05e6\u05d5\u05e8\u05da \u05de\u05d9\u05e4\u05d5\u05d9 \u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05d1\u05e9\u05e8\u05ea \u05dc\u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05e9\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05d9\u05db\u05d5\u05dc\u05d9\u05dd \u05dc\u05d2\u05e9\u05ea \u05d0\u05dc\u05d9\u05d4\u05dd. \u05e2\u05dc \u05d9\u05d3\u05d9 \u05d4\u05e8\u05e9\u05d0\u05d4 \u05dc\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05d2\u05d9\u05e9\u05d4 \u05d9\u05e9\u05d9\u05e8\u05d4 \u05dc\u05de\u05d3\u05d9\u05d4 \u05d1\u05e9\u05e8\u05ea \u05d0\u05dd \u05d9\u05db\u05d5\u05dc\u05d9\u05dd \u05dc\u05e0\u05d2\u05df \u05d0\u05ea \u05d4\u05e7\u05d1\u05e6\u05d9\u05dd \u05d9\u05e9\u05d9\u05e8\u05d5\u05ea \u05e2\u05dc \u05d2\u05d1\u05d9 \u05d4\u05e8\u05e9\u05ea \u05d5\u05dc\u05d4\u05d9\u05de\u05e0\u05e2 \u05de\u05e9\u05d9\u05de\u05d5\u05e9 \u05d1\u05de\u05e9\u05d0\u05d1\u05d9 \u05d4\u05e9\u05e8\u05ea \u05dc\u05e6\u05d5\u05e8\u05da \u05e7\u05d9\u05d3\u05d5\u05d3 \u05d5\u05e9\u05d9\u05d3\u05d5\u05e8.", @@ -512,8 +479,10 @@ "HeaderProgram": "\u05ea\u05d5\u05db\u05e0\u05d4", "HeaderClients": "\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd", "LabelCompleted": "\u05d4\u05d5\u05e9\u05dc\u05dd", + "LabelFailed": "\u05e0\u05db\u05e9\u05dc", "LabelSkipped": "\u05d3\u05d5\u05dc\u05d2", "HeaderEpisodeOrganization": "\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05e4\u05e8\u05e7\u05d9\u05dd", + "LabelSeries": "\u05e1\u05d3\u05e8\u05d4:", "LabelSeasonNumber": "\u05de\u05e1\u05e4\u05e8 \u05e2\u05d5\u05e0\u05d4:", "LabelEpisodeNumber": "\u05de\u05e1\u05e4\u05e8 \u05e4\u05e8\u05e7:", "LabelEndingEpisodeNumber": "\u05de\u05e1\u05e4\u05e8 \u05e1\u05d9\u05d5\u05dd \u05e4\u05e8\u05e7:", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/it.json b/MediaBrowser.Server.Implementations/Localization/Server/it.json index 53e13727b2..1ef8205ad0 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/it.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/it.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Aggiornamenti", - "HeaderUpdateLevel": "Livello", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Visualizzare solo i sottotitoli forzati", - "HeaderCustomizeOptionsPerMediaType": "Personalizza le opzioni per i media.", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Personalizzazioni", - "HeaderAllDevices": "Tutti i dispositivi", - "HeaderThisDevice": "Questo dispositivo", - "OptionLibraryButtons": "Bottoni libreria", - "OptionLibraryTiles": "Files Libreria", - "OptionSmallLibraryTiles": "Titles Biblioteca (piccolo)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Fallito", - "LabelSeries": "Serie:", - "ButtonPreviousTrack": "Precedente", - "ButtonNextTrack": "Prossimo", - "HeaderMyLibrary": "Mia Libreria", - "HeaderLibraryViews": "Biblioteca Visualizzazioni", "LabelExit": "Esci", "LabelVisitCommunity": "Visita Comunit\u00e0", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Parti addizionali", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "mancante", "LabelOffline": "Spento", "PathSubstitutionHelp": "il percorso 'sostituzioni' vengono utilizzati per mappare un percorso sul server per un percorso che i client sono in grado di accedere. Consentendo ai clienti l'accesso diretto ai media sul server possono essere in grado di giocare direttamente attraverso la rete ed evitare di utilizzare le risorse del server per lo streaming e transcodificare tra di loro.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programma", "HeaderClients": "Dispositivi", "LabelCompleted": "Completato", + "LabelFailed": "Fallito", "LabelSkipped": "Saltato", "HeaderEpisodeOrganization": "Organizzazione Episodi", + "LabelSeries": "Serie:", "LabelSeasonNumber": "Numero Stagione:", "LabelEpisodeNumber": "Numero Episodio:", "LabelEndingEpisodeNumber": "Ultimo Episodio Numero:", @@ -661,6 +630,8 @@ "ButtonScenes": "Scene", "ButtonSubtitles": "Sottotitoli", "ButtonAudioTracks": "Traccia Audio", + "ButtonPreviousTrack": "Precedente", + "ButtonNextTrack": "Prossimo", "ButtonStop": "Stop", "ButtonPause": "Pausa", "LabelGroupMoviesIntoCollections": "Raggruppa i film nelle collection", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Sezione 2 pagina iniziale", "LabelHomePageSection3": "Sezione 3 pagina iniziale", "LabelHomePageSection4": "Sezione Home page sezione quattro:", - "OptionMyLibraryButtons": "Mia libreria", - "OptionMyLibrary": "Mia libreria", - "OptionMyLibrarySmall": "Mia libreria", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Riprendi", "OptionLatestMedia": "Ultimo media", "OptionLatestChannelMedia": "Ultime voci del canale", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Visualizzazioni contenuti per adulti", "OptionLibraryFolders": "Vista", "TitleRemoteControl": "Telecomando", - "OptionLatestTvRecordings": "Ultime registrazioni" + "OptionLatestTvRecordings": "Ultime registrazioni", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/kk.json b/MediaBrowser.Server.Implementations/Localization/Server/kk.json index 8122c030c6..6e8abc47da 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/kk.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "\u041f\u0430\u0439\u0434\u0430\u043b\u0443\u043d\u044b\u0448\u044b\u043b\u0430\u0440 \u043c\u0430\u0437\u043c\u04b1\u043d\u0434\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u0434\u0430", - "HeaderEnableNotificationForEvents": "\u041d\u0435 \u0431\u043e\u043b\u0493\u0430\u043d\u0434\u0430 \u04d9\u043a\u0456\u043c\u0448\u0456\u043b\u0435\u0440\u0434\u0456 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u043d\u0434\u044b\u0440\u0443:", - "HeaderEnableNotificationForPlayback": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u0430\u0440 \u043e\u0439\u043d\u0430\u0493\u0430\u043d\u0434\u0430 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u043d\u0434\u044b\u0440\u0443:", - "OptionNotifyOnUpdates": "\u0416\u0430\u04a3\u0430\u0440\u0442\u0443\u043b\u0430\u0440 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456", - "OptionNotifyOnVideoPlayback": "\u0411\u0435\u0439\u043d\u0435 \u043e\u0439\u043d\u0430\u0442\u0443", - "OptionNotifyOnAudioPlayback": "\u0414\u044b\u0431\u044b\u0441 \u043e\u0439\u043d\u0430\u0442\u0443", - "OptionNotifyOnGamePlayback": "\u041e\u0439\u044b\u043d\u0434\u0430\u0440 \u043e\u0439\u043d\u0430\u0442\u0443", - "OptionNotifyOnFailedTasks": "\u0416\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430 \u0441\u04d9\u0442\u0441\u0456\u0437\u0434\u0456\u0433\u0456", - "OptionNotifyOnNewLibraryContent": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u0493\u0430 \u0436\u0430\u04a3\u0430 \u043c\u0430\u0437\u043c\u04b1\u043d \u04af\u0441\u0442\u0435\u043b\u0433\u0435\u043d", - "OptionNotifyOnServerRestartRequired": "\u0421\u0435\u0440\u0432\u0435\u0440\u0434\u0456 \u049b\u0430\u0439\u0442\u0430 \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u0443 \u049b\u0430\u0436\u0435\u0442", - "NotificationOptionUpdatesAvailable": "\u0416\u0430\u04a3\u0430\u0440\u0442\u0443\u043b\u0430\u0440 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456", - "NotificationOptionFailedTasks": "\u0416\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430 \u0441\u04d9\u0442\u0441\u0456\u0437\u0434\u0456\u0433\u0456", - "TabUpdates": "\u0416\u0430\u04a3\u0430\u0440\u0442\u0443\u043b\u0430\u0440", - "HeaderUpdateLevel": "\u0416\u0430\u04a3\u0430\u0440\u0442\u0443 \u0434\u0435\u04a3\u0433\u0435\u0439\u0456", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "\u0422\u0435\u043a \u049b\u0430\u043d\u0430 \u043c\u04d9\u0436\u0431\u04af\u0440\u043b\u0456 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443", - "HeaderCustomizeOptionsPerMediaType": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u0442\u0430\u0441\u0443\u0448\u044b \u0442\u04af\u0440\u0456 \u0431\u043e\u0439\u044b\u043d\u0448\u0430 \u0442\u0435\u04a3\u0448\u0435\u0443", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "\u0411\u0430\u0440\u043b\u044b\u049b \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440", - "HeaderThisDevice": "\u041e\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b", - "OptionLibraryButtons": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u043a\u0442\u0435\u0440\u0456", - "OptionLibraryTiles": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u049b\u0430\u0442\u0430\u0440\u043b\u0430\u0440\u044b (\u04af\u043b\u043a\u0435\u043d)", - "OptionSmallLibraryTiles": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u049b\u0430\u0442\u0430\u0440\u043b\u0430\u0440\u044b (\u043a\u0456\u0448\u0456)", - "ButtonPlayTrailer": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440", - "LabelFailed": "\u0421\u04d9\u0442\u0441\u0456\u0437", - "LabelSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", - "ButtonPreviousTrack": "\u0410\u043b\u0434\u044b\u04a3\u0493\u044b \u0436\u043e\u043b\u0448\u044b\u049b", - "ButtonNextTrack": "\u041a\u0435\u043b\u0435\u0441\u0456 \u0436\u043e\u043b\u0448\u044b\u049b", - "HeaderMyLibrary": "\u041c\u0435\u043d\u0456\u04a3 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043c", - "HeaderLibraryViews": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u043a\u04e9\u0440\u0456\u043d\u0456\u0441\u0442\u0435\u0440\u0456", "LabelExit": "\u0428\u044b\u0493\u0443", "LabelVisitCommunity": "\u049a\u0430\u0443\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u049b\u049b\u0430 \u0431\u0430\u0440\u0443", "LabelGithubWiki": "Github \u0443\u0438\u043a\u0438\u0456", @@ -430,6 +396,7 @@ "HeaderCastCrew": "\u0422\u04af\u0441\u0456\u0440\u0443\u0433\u0435 \u049b\u0430\u0442\u044b\u0441\u049b\u0430\u043d\u0434\u0430\u0440", "HeaderAdditionalParts": "\u0416\u0430\u043b\u0493\u0430\u0441\u0430\u0442\u044b\u043d \u0431\u04e9\u043b\u0456\u043c\u0434\u0435\u0440", "ButtonSplitVersionsApart": "\u041d\u04af\u0441\u049b\u0430\u043b\u0430\u0440\u0434\u044b \u049b\u0430\u0439\u0442\u0430 \u0431\u04e9\u043b\u0443", + "ButtonPlayTrailer": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440", "LabelMissing": "\u0416\u043e\u049b", "LabelOffline": "\u049a\u043e\u0441\u044b\u043b\u043c\u0430\u0493\u0430\u043d", "PathSubstitutionHelp": "\u0416\u043e\u043b \u0430\u043b\u043c\u0430\u0441\u0442\u044b\u0440\u0443\u043b\u0430\u0440\u044b\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0434\u0435\u0433\u0456 \u0436\u043e\u043b\u0434\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0430 \u0430\u043b\u0430\u0442\u044b\u043d \u0436\u043e\u043b\u043c\u0435\u043d \u0441\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443 \u04af\u0448\u0456\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b. \u0421\u0435\u0440\u0432\u0435\u0440\u0434\u0435\u0433\u0456 \u0442\u0430\u0441\u0443\u0448\u044b\u043b\u0430\u0440\u0493\u0430 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443 \u04af\u0448\u0456\u043d \u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440\u0433\u0435 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0456\u043b\u0433\u0435\u043d\u0434\u0435, \u0431\u04b1\u043b\u0430\u0440 \u0442\u0430\u0441\u0443\u0448\u044b\u043d\u044b \u0436\u0435\u043b\u0456 \u0430\u0440\u049b\u044b\u043b\u044b \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d \u0436\u04d9\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0435\u0441\u0443\u0440\u0441\u0442\u0430\u0440\u044b\u043d \u0430\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u04af\u0448\u0456\u043d \u0436\u04d9\u043d\u0435 \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u0443 \u04af\u0448\u0456\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0434\u0430\u043d \u0436\u0430\u043b\u0442\u0430\u0440\u0430\u0434\u044b.", @@ -512,8 +479,10 @@ "HeaderProgram": "\u0411\u0435\u0440\u0456\u043b\u0456\u043c", "HeaderClients": "\u041a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440", "LabelCompleted": "\u0410\u044f\u049b\u0442\u0430\u043b\u0493\u0430\u043d", + "LabelFailed": "\u0421\u04d9\u0442\u0441\u0456\u0437", "LabelSkipped": "\u04e8\u0442\u043a\u0456\u0437\u0456\u043b\u0433\u0435\u043d", "HeaderEpisodeOrganization": "\u042d\u043f\u0438\u0437\u043e\u0434\u0442\u044b \u04b1\u0439\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u0440\u0443", + "LabelSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", "LabelSeasonNumber": "\u041c\u0430\u0443\u0441\u044b\u043c \u043d\u04e9\u043c\u0456\u0440\u0456", "LabelEpisodeNumber": "\u042d\u043f\u0438\u0437\u043e\u0434 \u043d\u04e9\u043c\u0456\u0440\u0456", "LabelEndingEpisodeNumber": "\u0410\u044f\u049b\u0442\u0430\u0443\u0448\u044b \u044d\u043f\u0438\u0437\u043e\u0434\u0442\u044b\u04a3 \u043d\u04e9\u043c\u0456\u0440\u0456", @@ -661,6 +630,8 @@ "ButtonScenes": "\u0421\u0430\u0445\u043d\u0430\u043b\u0430\u0440", "ButtonSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440", "ButtonAudioTracks": "\u0414\u044b\u0431\u044b\u0441 \u0436\u043e\u043b\u0448\u044b\u049b\u0442\u0430\u0440\u044b", + "ButtonPreviousTrack": "\u0410\u043b\u0434\u044b\u04a3\u0493\u044b \u0436\u043e\u043b\u0448\u044b\u049b", + "ButtonNextTrack": "\u041a\u0435\u043b\u0435\u0441\u0456 \u0436\u043e\u043b\u0448\u044b\u049b", "ButtonStop": "\u0422\u043e\u049b\u0442\u0430\u0442\u0443", "ButtonPause": "\u04ae\u0437\u0456\u043b\u0456\u0441", "LabelGroupMoviesIntoCollections": "\u0422\u043e\u043f\u0442\u0430\u043c\u0430\u043b\u0430\u0440 \u0456\u0448\u0456\u043d\u0434\u0435\u0433\u0456 \u0444\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456 \u0442\u043e\u043f\u0442\u0430\u0441\u0442\u044b\u0440\u0443", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "\u0411\u0430\u0441\u0442\u044b \u0431\u0435\u0442 2-\u0431\u04e9\u043b\u0456\u043c:", "LabelHomePageSection3": "\u0411\u0430\u0441\u0442\u044b \u0431\u0435\u0442 3-\u0431\u04e9\u043b\u0456\u043c:", "LabelHomePageSection4": "\u0411\u0430\u0441\u0442\u044b \u0431\u0435\u0442 4-\u0431\u04e9\u043b\u0456\u043c:", - "OptionMyLibraryButtons": "\u041c\u0435\u043d\u0456\u04a3 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043c (\u0442\u04af\u0439\u043c\u0435\u0448\u0456\u043a\u0442\u0435\u0440)", - "OptionMyLibrary": "\u041c\u0435\u043d\u0456\u04a3 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043c", - "OptionMyLibrarySmall": "\u041c\u0435\u043d\u0456\u04a3 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043c (\u043a\u0456\u0448\u0456)", + "OptionMyViewsButtons": "\u041c\u0435\u043d\u0456\u04a3 \u043a\u04e9\u0440\u0456\u043d\u0456\u0441\u0442\u0435\u0440\u0456\u043c (\u0442\u04af\u0439\u043c\u0435\u0448\u0456\u043a\u0442\u0435\u0440)", + "OptionMyViews": "\u041c\u0435\u043d\u0456\u04a3 \u043a\u04e9\u0440\u0456\u043d\u0456\u0441\u0442\u0435\u0440\u0456\u043c", + "OptionMyViewsSmall": "\u041c\u0435\u043d\u0456\u04a3 \u043a\u04e9\u0440\u0456\u043d\u0456\u0441\u0442\u0435\u0440\u0456\u043c (\u043a\u0456\u0448\u0456)", "OptionResumablemedia": "\u0416\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443", "OptionLatestMedia": "\u0415\u04a3 \u0441\u043e\u04a3\u0493\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u043b\u0430\u0440", "OptionLatestChannelMedia": "\u0410\u0440\u043d\u0430\u043b\u0430\u0440\u0434\u044b\u04a3 \u0435\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440\u0456", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "\u0415\u0440\u0435\u0441\u0435\u043a\u0442\u0435\u0440\u0433\u0435 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u043c\u0430\u0437\u043c\u04b1\u043d\u0434\u044b \u043a\u04e9\u0440\u0441\u0435\u0442\u0443", "OptionLibraryFolders": "\u0422\u0430\u0441\u0443\u0448\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u044b", "TitleRemoteControl": "\u049a\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443", - "OptionLatestTvRecordings": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u0436\u0430\u0437\u0431\u0430\u043b\u0430\u0440" + "OptionLatestTvRecordings": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u0436\u0430\u0437\u0431\u0430\u043b\u0430\u0440", + "LabelProtocolInfo": "\u041f\u0440\u043e\u0442\u043e\u049b\u043e\u043b \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u044b:", + "LabelProtocolInfoHelp": "\u0411\u04b1\u043b \u043c\u04d9\u043d \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u044b\u04a3 GetProtocolInfo \u0441\u04b1\u0440\u0430\u043d\u044b\u0441\u0442\u0430\u0440\u044b\u043d\u0430 \u0436\u0430\u0443\u0430\u043f \u0431\u0435\u0440\u0433\u0435\u043d\u0434\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ms.json b/MediaBrowser.Server.Implementations/Localization/Server/ms.json index ff3ea24f11..2e32a8aaf1 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ms.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ms.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Tutup", "LabelVisitCommunity": "Melawat Masyarakat", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nb.json b/MediaBrowser.Server.Implementations/Localization/Server/nb.json index 0f97aa95e3..2eb1f0c189 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/nb.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/nb.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Oppdateringer", - "HeaderUpdateLevel": "Oppdaterings-niv\u00e5", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "Mitt bibliotek", - "HeaderLibraryViews": "Library Views", "LabelExit": "Exit", "LabelVisitCommunity": "Bes\u00f8k oss", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nl.json b/MediaBrowser.Server.Implementations/Localization/Server/nl.json index 31f4a38fe8..1e92d46d68 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/nl.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Meld administratieve gebruikers wanneer:", - "HeaderEnableNotificationForPlayback": "Meld wanneer gebruikers spelen:", - "OptionNotifyOnUpdates": "Updates zijn beschikbaar zijn", - "OptionNotifyOnVideoPlayback": "Video afspelen", - "OptionNotifyOnAudioPlayback": "Audio afspelen", - "OptionNotifyOnGamePlayback": "Games afspelen", - "OptionNotifyOnFailedTasks": "Geplande taken mislukt zijn", - "OptionNotifyOnNewLibraryContent": "Nieuwe bibliotheek inhoud wordt toegevoegd", - "OptionNotifyOnServerRestartRequired": "De server moet opnieuw worden gestart", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Niveau", - "LabelRequireTextSubtitles": "Ook downloaden als de film al ondertitels bevat", - "LabelRequireTextSubtitlesHelp": "Als de tekst versies van ondertiteling bewaard wordt zal er effici\u00ebnter naar mobiele apparaten gespeeld worden.", - "HeaderSubtitleDownloadingMoreHelp": "Ondertiteling wordt als missend gezien als het audio spoor in een buitenlandse taal is en er geen ondertiteling in de voorkeurstaal aanwezig is.", - "LabelDisplayForcedSubtitlesOnly": "laat alleen geforceerde ondertiteling zien", - "HeaderCustomizeOptionsPerMediaType": "Pas opties aan per mediatype", - "LabelAudioLanguagePreferenceHelp": "Indien niet ingevuld zal het standaard audio spoor geselecteerd worden, ongeacht de taal.", - "TabCustomizations": "Aanpassingen", - "HeaderAllDevices": "Alle apparaten", - "HeaderThisDevice": "Dit apparaat", - "OptionLibraryButtons": "Bibliotheek knoppen", - "OptionLibraryTiles": "Bibliotheek tegels (groot)", - "OptionSmallLibraryTiles": "Bibliotheek tegels (klein)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Mislukt", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Vorig nummer", - "ButtonNextTrack": "Volgend nummer", - "HeaderMyLibrary": "Mijn Bibliotheek", - "HeaderLibraryViews": "Bibliotheken overzicht", "LabelExit": "Afsluiten", "LabelVisitCommunity": "Bezoek Gemeenschap", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Extra onderdelen", "ButtonSplitVersionsApart": "Splits Versies Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Ontbreekt", "LabelOffline": "Offline", "PathSubstitutionHelp": "Pad vervangen worden gebruikt voor het in kaart brengen van een pad op de server naar een pad dat de Cli\u00ebnt in staat stelt om toegang te krijgen. Doordat de Cli\u00ebnt directe toegang tot de media op de server heeft is deze in staat om ze direct af te spelen via het netwerk. Daardoor wordt het gebruik van server resources om te streamen en te transcoderen vermeden.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programma", "HeaderClients": "Clients", "LabelCompleted": "Compleet", + "LabelFailed": "Mislukt", "LabelSkipped": "Overgeslagen", "HeaderEpisodeOrganization": "Afleveringen Organisatie", + "LabelSeries": "Series:", "LabelSeasonNumber": "Seizoen:", "LabelEpisodeNumber": "Aflevering:", "LabelEndingEpisodeNumber": "Laatste aflevering:", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Ondertitels", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Vorig nummer", + "ButtonNextTrack": "Volgend nummer", "ButtonStop": "Stop", "ButtonPause": "Pauze", "LabelGroupMoviesIntoCollections": "Groepeer films in verzamelingen", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Startpagina sectie twee:", "LabelHomePageSection3": "Startpagina sectie drie:", "LabelHomePageSection4": "Startpagina sectie vier", - "OptionMyLibraryButtons": "Mijn bibliotheek (knoppen)", - "OptionMyLibrary": "Mijn bibliotheek", - "OptionMyLibrarySmall": "Mijn bibliotheek (klein)", + "OptionMyViewsButtons": "Mijn weergaves (knoppen)", + "OptionMyViews": "Mijn weergaves", + "OptionMyViewsSmall": "weergaves (klein)", "OptionResumablemedia": "Hervatten", "OptionLatestMedia": "Nieuwste media", "OptionLatestChannelMedia": "Nieuwste kanaal items", @@ -846,7 +817,9 @@ "LabelSelectFolderGroups": "De volgende mappen automatisch groeperen in de secties zoals Films, Muziek en TV:", "LabelSelectFolderGroupsHelp": "Mappen die niet aangevinkt zijn worden in hun eigen sectie weergegeven.", "OptionDisplayAdultContent": "Toon Inhoud voor volwassen", - "OptionLibraryFolders": "Mapweergave", + "OptionLibraryFolders": "Media mappen", "TitleRemoteControl": "Beheer op afstand", - "OptionLatestTvRecordings": "Nieuwste opnames" + "OptionLatestTvRecordings": "Nieuwste opnames", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "De waarde die wordt gebruikt bij het reageren op GetProtocolInfo verzoeken van het apparaat." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json index f83c90a757..31282dfeed 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Notificar usu\u00e1rios administradores quando:", - "HeaderEnableNotificationForPlayback": "Notificar quando os usu\u00e1rios reproduzirem:", - "OptionNotifyOnUpdates": "Atualiza\u00e7\u00f5es estiverem disponiveis", - "OptionNotifyOnVideoPlayback": "V\u00eddeo", - "OptionNotifyOnAudioPlayback": "\u00c1udio", - "OptionNotifyOnGamePlayback": "Jogos", - "OptionNotifyOnFailedTasks": "Tarefas agendadas falharem", - "OptionNotifyOnNewLibraryContent": "Novo conte\u00fado for adicionado \u00e0 biblioteca", - "OptionNotifyOnServerRestartRequired": "O servidor necessita ser reiniciado", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Atualiza\u00e7\u00f5es", - "HeaderUpdateLevel": "N\u00edvel de Atualiza\u00e7\u00e3o", - "LabelRequireTextSubtitles": "Transferir mesmo se o v\u00eddeo possuir legendas gr\u00e1ficas", - "LabelRequireTextSubtitlesHelp": "Manter vers\u00f5es das legendas em texto resultar\u00e1 em uma entrega mais eficiente para os clientes m\u00f3veis.", - "HeaderSubtitleDownloadingMoreHelp": "Ser\u00e1 considerado que faltam legendas quando a faixa de \u00e1udio estiver em um idioma estrangeiro e n\u00e3o existirem legendas dispon\u00edveis no idioma preferido.", - "LabelDisplayForcedSubtitlesOnly": "Exibir apenas legendas for\u00e7adas", - "HeaderCustomizeOptionsPerMediaType": "Personalize op\u00e7\u00f5es por tipo de m\u00eddia", - "LabelAudioLanguagePreferenceHelp": "Se estiver em branco, a faixa de \u00e1udio padr\u00e3o ser\u00e1 selecionada, independente do idioma.", - "TabCustomizations": "Personaliza\u00e7\u00f5es", - "HeaderAllDevices": "Todos os Dispositivos", - "HeaderThisDevice": "Este Dispositivo", - "OptionLibraryButtons": "Bot\u00f5es da biblioteca", - "OptionLibraryTiles": "Tiles da biblioteca (grandes)", - "OptionSmallLibraryTiles": "Tiles da biblioteca (pequenas)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Falhou", - "LabelSeries": "S\u00e9rie:", - "ButtonPreviousTrack": "Faixa Anterior", - "ButtonNextTrack": "Pr\u00f3xima Faixa", - "HeaderMyLibrary": "Minha Biblioteca", - "HeaderLibraryViews": "Visualiza\u00e7\u00f5es da Biblioteca", "LabelExit": "Sair", "LabelVisitCommunity": "Visitar a Comunidade", "LabelGithubWiki": "Wiki do Github", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Elenco & Equipe", "HeaderAdditionalParts": "Partes Adicionais", "ButtonSplitVersionsApart": "Separar Vers\u00f5es", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Ausente", "LabelOffline": "Desconectado", "PathSubstitutionHelp": "Substitui\u00e7\u00f5es de caminho s\u00e3o usadas para mapear um caminho no servidor que possa ser acessado pelos clientes. Ao permitir o acesso dos clientes \u00e0 m\u00eddia no servidor, eles podem reproduzir diretamente atrav\u00e9s da rede e evitar o uso de recursos do servidor para fazer stream ou transcodifica\u00e7\u00e3o.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programa", "HeaderClients": "Clientes", "LabelCompleted": "Completado", + "LabelFailed": "Falhou", "LabelSkipped": "Ignorado", "HeaderEpisodeOrganization": "Organiza\u00e7\u00e3o do Epis\u00f3dio", + "LabelSeries": "S\u00e9rie:", "LabelSeasonNumber": "N\u00famero da temporada", "LabelEpisodeNumber": "N\u00famero do epis\u00f3dio", "LabelEndingEpisodeNumber": "N\u00famero do epis\u00f3dio final", @@ -661,6 +630,8 @@ "ButtonScenes": "Cenas", "ButtonSubtitles": "Legendas", "ButtonAudioTracks": "Faixas de \u00e1udio", + "ButtonPreviousTrack": "Faixa anterior", + "ButtonNextTrack": "Pr\u00f3xima faixa", "ButtonStop": "Parar", "ButtonPause": "Pausar", "LabelGroupMoviesIntoCollections": "Agrupar filmes nas cole\u00e7\u00f5es", @@ -784,7 +755,7 @@ "LabelTypeText": "Texto", "HeaderSearchForSubtitles": "Buscar Legendas", "MessageNoSubtitleSearchResultsFound": "N\u00e3o foi encontrado nenhum resultado.", - "TabDisplay": "Exibir", + "TabDisplay": "Exibi\u00e7\u00e3o", "TabLanguages": "Idiomas", "TabWebClient": "Cliente Web", "LabelEnableThemeSongs": "Ativar m\u00fasicas-tema", @@ -799,14 +770,14 @@ "LabelHomePageSection1": "Se\u00e7\u00e3o um da tela de in\u00edcio:", "LabelHomePageSection2": "Se\u00e7\u00e3o dois da tela de in\u00edcio:", "LabelHomePageSection3": "Se\u00e7\u00e3o tr\u00eas da tela de in\u00edcio:", - "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "Minha biblioteca (bot\u00f5es)", - "OptionMyLibrary": "Minha biblioteca", - "OptionMyLibrarySmall": "Minha biblioteca (pequena)", + "LabelHomePageSection4": "Se\u00e7\u00e3o quatro da tela de inicio", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Retomar", "OptionLatestMedia": "M\u00eddias recentes", - "OptionLatestChannelMedia": "Latest channel items", - "HeaderLatestChannelItems": "Latest Channel Items", + "OptionLatestChannelMedia": "Itens recentes de canal", + "HeaderLatestChannelItems": "Itens Recentes de Canal", "OptionNone": "Nenhum", "HeaderLiveTv": "TV ao Vivo", "HeaderReports": "Relat\u00f3rios", @@ -842,11 +813,13 @@ "ViewTypeChannels": "Canais", "ViewTypeLiveTV": "TV ao Vivo", "HeaderOtherDisplaySettings": "Ajustes de Exibi\u00e7\u00e3o", - "HeaderMyViews": "My Views", + "HeaderMyViews": "Minhas Visualiza\u00e7\u00f5es", "LabelSelectFolderGroups": "Agrupar automaticamente o conte\u00fado das seguintes pastas dentro das visualiza\u00e7\u00f5es como Filmes, M\u00fasicas e TV:", "LabelSelectFolderGroupsHelp": "Pastas que n\u00e3o est\u00e3o marcadas ser\u00e3o exibidas em sua pr\u00f3pria visualiza\u00e7\u00e3o.", "OptionDisplayAdultContent": "Exibir conte\u00fado adulto", - "OptionLibraryFolders": "Visualiza\u00e7\u00e3o da pasta", - "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLibraryFolders": "Pastas de m\u00eddias", + "TitleRemoteControl": "Controle Remoto", + "OptionLatestTvRecordings": "\u00daltimas grava\u00e7\u00f5es", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json index 4578448147..412b681221 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "Quando utilizadores reproduzem conte\u00fados", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Atualiza\u00e7\u00f5es dispon\u00edveis", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Atualiza\u00e7\u00f5es", - "HeaderUpdateLevel": "N\u00edvel de atualiza\u00e7\u00e3o", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Mostrar apenas legendas for\u00e7adas", - "HeaderCustomizeOptionsPerMediaType": "Personalize as op\u00e7\u00f5es por tipo de conte\u00fado multim\u00e9dia", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Falhou", - "LabelSeries": "S\u00e9rie:", - "ButtonPreviousTrack": "Faixa Anterior", - "ButtonNextTrack": "Pr\u00f3xima Faixa", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Sair", "LabelVisitCommunity": "Visitar a Comunidade", "LabelGithubWiki": "Wiki do Github", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Elenco e Equipa", "HeaderAdditionalParts": "Partes Adicionais", "ButtonSplitVersionsApart": "Separar Vers\u00f5es", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Em falta", "LabelOffline": "Desconectado", "PathSubstitutionHelp": "Substitui\u00e7\u00f5es de localiza\u00e7\u00e3o s\u00e3o usadas para mapear uma localiza\u00e7\u00e3o no servidor que possa ser acedido pelos clientes. Ao permitir o acesso dos clientes ao conte\u00fado multim\u00e9dia no servidor, permite-lhes reproduzir diretamente atrav\u00e9s da rede e evitar o uso de recursos do servidor para fazer stream ou transcodifica\u00e7\u00e3o.", @@ -512,8 +479,10 @@ "HeaderProgram": "Programa", "HeaderClients": "Clientes", "LabelCompleted": "Terminado", + "LabelFailed": "Falhou", "LabelSkipped": "Ignorado", "HeaderEpisodeOrganization": "Organiza\u00e7\u00e3o dos Epis\u00f3dios", + "LabelSeries": "S\u00e9rie:", "LabelSeasonNumber": "N\u00famero da temporada", "LabelEpisodeNumber": "N\u00famero do epis\u00f3dio", "LabelEndingEpisodeNumber": "N\u00famero do epis\u00f3dio final", @@ -661,6 +630,8 @@ "ButtonScenes": "Cenas", "ButtonSubtitles": "Legendas", "ButtonAudioTracks": "Faixas de \u00e1udio", + "ButtonPreviousTrack": "Faixa Anterior", + "ButtonNextTrack": "Pr\u00f3xima Faixa", "ButtonStop": "Parar", "ButtonPause": "Pausar", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ru.json b/MediaBrowser.Server.Implementations/Localization/Server/ru.json index 8dd00090ac..203454e3f4 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/ru.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435", - "HeaderEnableNotificationForEvents": "\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043a\u043e\u0433\u0434\u0430:", - "HeaderEnableNotificationForPlayback": "\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438:", - "OptionNotifyOnUpdates": "\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", - "OptionNotifyOnVideoPlayback": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e", - "OptionNotifyOnAudioPlayback": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0430\u0443\u0434\u0438\u043e", - "OptionNotifyOnGamePlayback": "\u0417\u0430\u043f\u0443\u0441\u043a \u0438\u0433\u0440\u044b", - "OptionNotifyOnFailedTasks": "\u0421\u0431\u043e\u0439 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f", - "OptionNotifyOnNewLibraryContent": "\u041d\u043e\u0432\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443", - "OptionNotifyOnServerRestartRequired": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440", - "NotificationOptionUpdatesAvailable": "\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", - "NotificationOptionFailedTasks": "\u0421\u0431\u043e\u0439 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f", - "TabUpdates": "\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", - "HeaderUpdateLevel": "\u0421\u0442\u0435\u043f\u0435\u043d\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044b", - "HeaderCustomizeOptionsPerMediaType": "\u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u043e \u0442\u0438\u043f\u0443 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044f", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "\u0412\u0441\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430", - "HeaderThisDevice": "\u0414\u0430\u043d\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e", - "OptionLibraryButtons": "\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 - \u043a\u043d\u043e\u043f\u043a\u0438", - "OptionLibraryTiles": "\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 - \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u043b\u0438\u0442\u043a\u0438", - "OptionSmallLibraryTiles": "\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 - \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u043f\u043b\u0438\u0442\u043a\u0438", - "ButtonPlayTrailer": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440", - "LabelFailed": "\u041d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e", - "LabelSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", - "ButtonPreviousTrack": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", - "ButtonNextTrack": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", - "HeaderMyLibrary": "\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430", - "HeaderLibraryViews": "\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438", "LabelExit": "\u0412\u044b\u0445\u043e\u0434", "LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0435 \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430", "LabelGithubWiki": "\u0412\u0438\u043a\u0438 \u043d\u0430 Github", @@ -346,7 +312,7 @@ "HeaderUpcomingTV": "\u0421\u043a\u043e\u0440\u043e", "TabStatus": "\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435", "TabSettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b", - "ButtonRefreshGuideData": "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0433\u0438\u0434", + "ButtonRefreshGuideData": "\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u0438\u0434", "OptionPriority": "\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442", "OptionRecordOnAllChannels": "\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441\u043e \u0432\u0441\u0435\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432", "OptionRecordAnytime": "\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0432 \u043b\u044e\u0431\u043e\u0435 \u0432\u0440\u0435\u043c\u044f", @@ -430,6 +396,7 @@ "HeaderCastCrew": "\u0423\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0441\u044a\u0451\u043c\u043e\u043a", "HeaderAdditionalParts": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438", "ButtonSplitVersionsApart": "\u0420\u0430\u0441\u0449\u0435\u043f\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438", + "ButtonPlayTrailer": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440", "LabelMissing": "\u041f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e", "LabelOffline": "\u0410\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e", "PathSubstitutionHelp": "\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\u043c \u043f\u0443\u0442\u0435\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0443\u0442\u044c, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c. \u041f\u0440\u0438 \u043f\u0440\u044f\u043c\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043a \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044f\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0442\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u044f\u043c\u043e \u043f\u043e \u0441\u0435\u0442\u0438, \u043d\u0435 \u0442\u0440\u0430\u0442\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438.", @@ -512,8 +479,10 @@ "HeaderProgram": "\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430", "HeaderClients": "\u041a\u043b\u0438\u0435\u043d\u0442\u044b", "LabelCompleted": "\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e", + "LabelFailed": "\u041d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e", "LabelSkipped": "\u041e\u0442\u043b\u043e\u0436\u0435\u043d\u043e", "HeaderEpisodeOrganization": "\u0420\u0435\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u043f\u0438\u0437\u043e\u0434\u0430", + "LabelSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", "LabelSeasonNumber": "\u041d\u043e\u043c\u0435\u0440 \u0441\u0435\u0437\u043e\u043d\u0430", "LabelEpisodeNumber": "\u041d\u043e\u043c\u0435\u0440 \u044d\u043f\u0438\u0437\u043e\u0434\u0430", "LabelEndingEpisodeNumber": "\u041d\u043e\u043c\u0435\u0440 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u044d\u043f\u0438\u0437\u043e\u0434\u0430", @@ -661,6 +630,8 @@ "ButtonScenes": "\u0421\u0446\u0435\u043d\u044b", "ButtonSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b", "ButtonAudioTracks": "\u0410\u0443\u0434\u0438\u043e \u0434\u043e\u0440\u043e\u0436\u043a\u0438", + "ButtonPreviousTrack": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", + "ButtonNextTrack": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430", "ButtonStop": "\u0421\u0442\u043e\u043f", "ButtonPause": "\u041f\u0430\u0443\u0437\u0430", "LabelGroupMoviesIntoCollections": "\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u043c\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 - \u0440\u0430\u0437\u0434\u0435\u043b 2:", "LabelHomePageSection3": "\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 - \u0440\u0430\u0437\u0434\u0435\u043b 3:", "LabelHomePageSection4": "\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 - \u0440\u0430\u0437\u0434\u0435\u043b 4:", - "OptionMyLibraryButtons": "\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 (\u043a\u043d\u043e\u043f\u043a\u0438)", - "OptionMyLibrary": "\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430", - "OptionMyLibrarySmall": "\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 (\u043c\u0430\u043b\u044b\u0435)", + "OptionMyViewsButtons": "\u041c\u043e\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u043a\u043d\u043e\u043f\u043a\u0438)", + "OptionMyViews": "\u041c\u043e\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f", + "OptionMyViewsSmall": "\u041c\u043e\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u043c\u0430\u043b\u044b\u0435)", "OptionResumablemedia": "\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u043c\u044b\u0435", "OptionLatestMedia": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u0439", "OptionLatestChannelMedia": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u043a\u0430\u043d\u0430\u043b\u043e\u0432", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \"\u0434\u043b\u044f \u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0445\"", "OptionLibraryFolders": "\u041c\u0435\u0434\u0438\u0430\u043f\u0430\u043f\u043a\u0438", "TitleRemoteControl": "\u0423\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435", - "OptionLatestTvRecordings": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439" + "OptionLatestTvRecordings": "\u041d\u043e\u0432\u0438\u043d\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439", + "LabelProtocolInfo": "\u0421\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435:", + "LabelProtocolInfoHelp": "\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u043a\u043b\u0438\u043a\u0435 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b GetProtocolInfo \u043e\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 3b6bcdf512..fc050ec2d4 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -785,9 +785,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -833,5 +833,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/sv.json b/MediaBrowser.Server.Implementations/Localization/Server/sv.json index ea44176ed3..8d14dbf8e7 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/sv.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Meddela administrat\u00f6rer n\u00e4r:", - "HeaderEnableNotificationForPlayback": "Meddela n\u00e4r anv\u00e4ndare spelar:", - "OptionNotifyOnUpdates": "Uppdateringar \u00e4r tillg\u00e4ngliga", - "OptionNotifyOnVideoPlayback": "Video", - "OptionNotifyOnAudioPlayback": "Audio", - "OptionNotifyOnGamePlayback": "Spel", - "OptionNotifyOnFailedTasks": "Schemalagda aktiviteter misslyckas", - "OptionNotifyOnNewLibraryContent": "Nytt inneh\u00e5ll finns i biblioteket", - "OptionNotifyOnServerRestartRequired": "Servern m\u00e5ste startas om", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Uppdateringar", - "HeaderUpdateLevel": "Uppdatera versionsniv\u00e5", - "LabelRequireTextSubtitles": "Ladda ner \u00e4ven om videon redan inneh\u00e5ller grafiska undertexter", - "LabelRequireTextSubtitlesHelp": "Att spara textversioner av undertexter ger b\u00e4ttre resultat vid anv\u00e4ndning av mobila enheter.", - "HeaderSubtitleDownloadingMoreHelp": "Undertexter betraktas som saknade d\u00e5 ljudsp\u00e5ret \u00e4r p\u00e5 ett fr\u00e4mmande spr\u00e5k och undertexter p\u00e5 det \u00f6nskade spr\u00e5ket ej finns tillg\u00e4ngliga.", - "LabelDisplayForcedSubtitlesOnly": "Visa endast tvingande undertexter", - "HeaderCustomizeOptionsPerMediaType": "Inst\u00e4llningar baserade p\u00e5 typ av media", - "LabelAudioLanguagePreferenceHelp": "Om ej angivet kommer det f\u00f6rvalda ljudsp\u00e5ret att v\u00e4ljas, oavsett spr\u00e5k.", - "TabCustomizations": "Anpassningar", - "HeaderAllDevices": "Alla enheter", - "HeaderThisDevice": "Den h\u00e4r enheten", - "OptionLibraryButtons": "Biblioteksknappar", - "OptionLibraryTiles": "Biblioteksbrickor", - "OptionSmallLibraryTiles": "Biblioteksbrickor (sm\u00e5)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Misslyckades", - "LabelSeries": "Serie:", - "ButtonPreviousTrack": "F\u00f6reg\u00e5ende sp\u00e5r", - "ButtonNextTrack": "N\u00e4sta sp\u00e5r", - "HeaderMyLibrary": "Mitt bibliotek", - "HeaderLibraryViews": "Biblioteksvyer", "LabelExit": "Avsluta", "LabelVisitCommunity": "Bes\u00f6k v\u00e5rt diskussionsforum", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Rollista & bes\u00e4ttning", "HeaderAdditionalParts": "Ytterligare delar", "ButtonSplitVersionsApart": "Hantera olika versioner separat", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Saknas", "LabelOffline": "Offline", "PathSubstitutionHelp": "S\u00f6kv\u00e4gsutbyte betyder att en plats p\u00e5 servern kopplas till en lokal fils\u00f6kv\u00e4g p\u00e5 en klient. P\u00e5 s\u00e5 s\u00e4tt f\u00e5r klienten direkt tillg\u00e5ng till material p\u00e5 servern och kan spela upp det direkt via n\u00e4tverket utan att f\u00f6rbruka serverresurser f\u00f6r str\u00f6mning och omkodning.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Klienter", "LabelCompleted": "Klar", + "LabelFailed": "Misslyckades", "LabelSkipped": "Hoppades \u00f6ver", "HeaderEpisodeOrganization": "Katalogisering av avsnitt", + "LabelSeries": "Serie:", "LabelSeasonNumber": "S\u00e4songsnummer:", "LabelEpisodeNumber": "Avsnittsnummer:", "LabelEndingEpisodeNumber": "Avslutande avsnittsnummer:", @@ -661,6 +630,8 @@ "ButtonScenes": "Scener", "ButtonSubtitles": "Undertexter", "ButtonAudioTracks": "Ljudsp\u00e5r", + "ButtonPreviousTrack": "F\u00f6reg\u00e5ende sp\u00e5r", + "ButtonNextTrack": "N\u00e4sta sp\u00e5r", "ButtonStop": "Stopp", "ButtonPause": "Paus", "LabelGroupMoviesIntoCollections": "Gruppera filmer i samlingsboxar", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Hemsk\u00e4rmens del 2:", "LabelHomePageSection3": "Hemsk\u00e4rmens del 3:", "LabelHomePageSection4": "Hemsidans del 4:", - "OptionMyLibraryButtons": "Mitt bibliotek (knappar)", - "OptionMyLibrary": "Mitt bibliotek", - "OptionMyLibrarySmall": "Mitt bibliotek (litet)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "\u00c5teruppta", "OptionLatestMedia": "Nytillkommet", "OptionLatestChannelMedia": "Senaste objekten i Kanaler", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Visa erotiskt inneh\u00e5ll", "OptionLibraryFolders": "Mappvy", "TitleRemoteControl": "Fj\u00e4rrkontroll", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Senaste inspelningar", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/vi.json b/MediaBrowser.Server.Implementations/Localization/Server/vi.json index eca1f5a614..5298bd8b65 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/vi.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/vi.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "Updates", - "HeaderUpdateLevel": "Update Level", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles", - "HeaderCustomizeOptionsPerMediaType": "Customize options per media type", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "Trailer", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "Tho\u00e1t", "LabelVisitCommunity": "Gh\u00e9 th\u0103m trang C\u1ed9ng \u0111\u1ed3ng", "LabelGithubWiki": "Github Wiki", @@ -430,6 +396,7 @@ "HeaderCastCrew": "Cast & Crew", "HeaderAdditionalParts": "Additional Parts", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "Trailer", "LabelMissing": "Missing", "LabelOffline": "Offline", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Ch\u01b0\u01a1ng tr\u00ecnh", "HeaderClients": "C\u00e1c m\u00e1y kh\u00e1ch", "LabelCompleted": "Ho\u00e0n th\u00e0nh", + "LabelFailed": "Failed", "LabelSkipped": "B\u1ecf qua", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json index 838d947cd6..1642c22201 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json @@ -1,38 +1,4 @@ { - "LabelMediaBrowser": "Media Browser", - "OptionNotifyOnPlayback": "When users play content", - "HeaderEnableNotificationForEvents": "Nofity administrative users when:", - "HeaderEnableNotificationForPlayback": "Notify when users play:", - "OptionNotifyOnUpdates": "Updates available", - "OptionNotifyOnVideoPlayback": "Video playback", - "OptionNotifyOnAudioPlayback": "Audio playback", - "OptionNotifyOnGamePlayback": "Games playback", - "OptionNotifyOnFailedTasks": "Scheduled task failure", - "OptionNotifyOnNewLibraryContent": "New library content added", - "OptionNotifyOnServerRestartRequired": "Server restart required", - "NotificationOptionUpdatesAvailable": "Updates available", - "NotificationOptionFailedTasks": "Scheduled task failure", - "TabUpdates": "\u66f4\u65b0", - "HeaderUpdateLevel": "\u66f4\u65b0\u7d1a\u5225", - "LabelRequireTextSubtitles": "Download even if the video already contains graphical subtitles", - "LabelRequireTextSubtitlesHelp": "Keeping text versions of subtitles will result in more efficient delivery to mobile clients.", - "HeaderSubtitleDownloadingMoreHelp": "Subtitles are considered missing when the audio track is in a foreign language, and there are no subtitles available in the preferred language.", - "LabelDisplayForcedSubtitlesOnly": "\u53ea\u986f\u793a\u5f37\u5236\u5b57\u5e55", - "HeaderCustomizeOptionsPerMediaType": "\u81ea\u5b9a\u7fa9\u6bcf\u500b\u5a92\u9ad4\u985e\u578b\u7684\u9078\u9805", - "LabelAudioLanguagePreferenceHelp": "If empty, the default audio track will be selected, regardless of language.", - "TabCustomizations": "Customizations", - "HeaderAllDevices": "All Devices", - "HeaderThisDevice": "This Device", - "OptionLibraryButtons": "Library buttons", - "OptionLibraryTiles": "Library tiles (large)", - "OptionSmallLibraryTiles": "Library tiles (small)", - "ButtonPlayTrailer": "\u9810\u544a", - "LabelFailed": "Failed", - "LabelSeries": "Series:", - "ButtonPreviousTrack": "Previous track", - "ButtonNextTrack": "Next track", - "HeaderMyLibrary": "My Library", - "HeaderLibraryViews": "Library Views", "LabelExit": "\u96e2\u958b", "LabelVisitCommunity": "\u8a2a\u554f\u793e\u5340", "LabelGithubWiki": "Github \u7ef4\u57fa", @@ -430,6 +396,7 @@ "HeaderCastCrew": "\u62cd\u651d\u4eba\u54e1\u53ca\u6f14\u54e1", "HeaderAdditionalParts": "\u9644\u52a0\u90e8\u4efd", "ButtonSplitVersionsApart": "Split Versions Apart", + "ButtonPlayTrailer": "\u9810\u544a", "LabelMissing": "\u7f3a\u5c11", "LabelOffline": "\u96e2\u7dda", "PathSubstitutionHelp": "Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.", @@ -512,8 +479,10 @@ "HeaderProgram": "Program", "HeaderClients": "Clients", "LabelCompleted": "Completed", + "LabelFailed": "Failed", "LabelSkipped": "Skipped", "HeaderEpisodeOrganization": "Episode Organization", + "LabelSeries": "Series:", "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", @@ -661,6 +630,8 @@ "ButtonScenes": "Scenes", "ButtonSubtitles": "Subtitles", "ButtonAudioTracks": "Audio tracks", + "ButtonPreviousTrack": "Previous track", + "ButtonNextTrack": "Next track", "ButtonStop": "Stop", "ButtonPause": "Pause", "LabelGroupMoviesIntoCollections": "Group movies into collections", @@ -800,9 +771,9 @@ "LabelHomePageSection2": "Home page section two:", "LabelHomePageSection3": "Home page section three:", "LabelHomePageSection4": "Home page section four:", - "OptionMyLibraryButtons": "My library (buttons)", - "OptionMyLibrary": "My library", - "OptionMyLibrarySmall": "My library (small)", + "OptionMyViewsButtons": "My views (buttons)", + "OptionMyViews": "My views", + "OptionMyViewsSmall": "My views (small)", "OptionResumablemedia": "Resume", "OptionLatestMedia": "Latest media", "OptionLatestChannelMedia": "Latest channel items", @@ -848,5 +819,7 @@ "OptionDisplayAdultContent": "Display adult content", "OptionLibraryFolders": "Media folders", "TitleRemoteControl": "Remote Control", - "OptionLatestTvRecordings": "Latest recordings" + "OptionLatestTvRecordings": "Latest recordings", + "LabelProtocolInfo": "Protocol info:", + "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device." } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index afde4af93d..f48431dc1d 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -356,7 +356,7 @@ namespace MediaBrowser.Server.Implementations.Session private string GetSessionKey(string clientType, string appVersion, string deviceId) { - return clientType + deviceId + appVersion; + return clientType + deviceId; } /// diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 3ea45bc4fb..9e31fc800c 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Constants; using MediaBrowser.Common.Implementations.Logging; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations; diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 507a66f6f9..f5760a9f17 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.410 + 3.0.411 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 9d2aa3ffee..ac5b967c66 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.410 + 3.0.411 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 4ebea620d8..3a498b91d5 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.410 + 3.0.411 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + From 22fc0b442ac093e55058723782adf845f4465925 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 25 Jun 2014 11:12:39 -0400 Subject: [PATCH 002/131] add short overview --- MediaBrowser.Api/BaseApiService.cs | 11 +++-- MediaBrowser.Api/SessionsService.cs | 25 +++------- .../Session/ISessionManager.cs | 9 ++++ MediaBrowser.Dlna/PlayTo/TransportCommands.cs | 28 ----------- .../Savers/XmlSaverHelpers.cs | 6 +++ .../Resolvers/Audio/MusicAlbumResolver.cs | 49 ++++++++----------- .../Session/SessionManager.cs | 6 +++ .../Session/SessionWebSocketListener.cs | 18 ++----- 8 files changed, 62 insertions(+), 90 deletions(-) diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index ca5b8b63a4..569e125302 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -88,9 +88,14 @@ namespace MediaBrowser.Api { var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request); - return sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) && - string.Equals(i.Client, auth.Client) && - string.Equals(i.ApplicationVersion, auth.Version)); + var session = sessionManager.GetSession(auth.DeviceId, auth.Client, auth.Version); + + if (session == null) + { + throw new ArgumentException("Session not found."); + } + + return session; } /// diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs index 4cb48e9fe8..36f1d65778 100644 --- a/MediaBrowser.Api/SessionsService.cs +++ b/MediaBrowser.Api/SessionsService.cs @@ -285,7 +285,7 @@ namespace MediaBrowser.Api SeekPositionTicks = request.SeekPositionTicks }; - var task = _sessionManager.SendPlaystateCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -303,7 +303,7 @@ namespace MediaBrowser.Api ItemType = request.ItemType }; - var task = _sessionManager.SendBrowseCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendBrowseCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -318,7 +318,7 @@ namespace MediaBrowser.Api if (Enum.TryParse(request.Command, true, out commandType)) { - var currentSession = GetSession(); + var currentSession = GetSession(_sessionManager); var command = new GeneralCommand { @@ -345,7 +345,7 @@ namespace MediaBrowser.Api Text = request.Text }; - var task = _sessionManager.SendMessageCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendMessageCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -364,14 +364,14 @@ namespace MediaBrowser.Api StartPositionTicks = request.StartPositionTicks }; - var task = _sessionManager.SendPlayCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendPlayCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } public void Post(SendGeneralCommand request) { - var currentSession = GetSession(); + var currentSession = GetSession(_sessionManager); var command = new GeneralCommand { @@ -386,7 +386,7 @@ namespace MediaBrowser.Api public void Post(SendFullGeneralCommand request) { - var currentSession = GetSession(); + var currentSession = GetSession(_sessionManager); request.ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null; @@ -409,7 +409,7 @@ namespace MediaBrowser.Api { if (string.IsNullOrWhiteSpace(request.Id)) { - request.Id = GetSession().Id; + request.Id = GetSession(_sessionManager).Id; } _sessionManager.ReportCapabilities(request.Id, new SessionCapabilities { @@ -422,14 +422,5 @@ namespace MediaBrowser.Api MessageCallbackUrl = request.MessageCallbackUrl }); } - - private SessionInfo GetSession() - { - var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request); - - return _sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) && - string.Equals(i.Client, auth.Client) && - string.Equals(i.ApplicationVersion, auth.Version)); - } } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 8c2ece131f..74ad1b7ee6 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -239,5 +239,14 @@ namespace MediaBrowser.Controller.Session /// /// The device identifier. void ClearTranscodingInfo(string deviceId); + + /// + /// Gets the session. + /// + /// The device identifier. + /// The client. + /// The version. + /// SessionInfo. + SessionInfo GetSession(string deviceId, string client, string version); } } \ No newline at end of file diff --git a/MediaBrowser.Dlna/PlayTo/TransportCommands.cs b/MediaBrowser.Dlna/PlayTo/TransportCommands.cs index 2f2276a873..13b9b6b189 100644 --- a/MediaBrowser.Dlna/PlayTo/TransportCommands.cs +++ b/MediaBrowser.Dlna/PlayTo/TransportCommands.cs @@ -146,34 +146,6 @@ namespace MediaBrowser.Dlna.PlayTo return string.Format(CommandBase, action.Name, xmlNamesapce, stateString); } - public string BuildSearchPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "") - { - var stateString = string.Empty; - - foreach (var arg in action.ArgumentList) - { - if (arg.Direction == "out") - continue; - - if (arg.Name == "ObjectID") - stateString += BuildArgumentXml(arg, value.ToString()); - else if (arg.Name == "Filter") - stateString += BuildArgumentXml(arg, "*"); - else if (arg.Name == "StartingIndex") - stateString += BuildArgumentXml(arg, "0"); - else if (arg.Name == "RequestedCount") - stateString += BuildArgumentXml(arg, "200"); - else if (arg.Name == "BrowseFlag") - stateString += BuildArgumentXml(arg, null, "BrowseDirectChildren"); - else if (arg.Name == "SortCriteria") - stateString += BuildArgumentXml(arg, ""); - else - stateString += BuildArgumentXml(arg, value.ToString(), commandParameter); - } - - return string.Format(CommandBase, action.Name, xmlNamesapce, stateString); - } - public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary dictionary) { var stateString = string.Empty; diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index 6b9ebbfe93..d10422f78e 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -72,6 +72,7 @@ namespace MediaBrowser.Providers.Savers "MusicbrainzId", "Overview", + "ShortOverview", "Persons", "PlotKeywords", "PremiereDate", @@ -257,6 +258,11 @@ namespace MediaBrowser.Providers.Savers } } + if (!string.IsNullOrEmpty(item.Overview)) + { + builder.Append(""); + } + var hasShortOverview = item as IHasShortOverview; if (hasShortOverview != null) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 28d4769714..034894670d 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -67,32 +67,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// true if [is music album] [the specified data]; otherwise, false. public static bool IsMusicAlbum(string path, IDirectoryService directoryService) { - // If list contains at least 2 audio files or at least one and no video files consider it to contain music - var foundAudio = 0; - - foreach (var file in directoryService.GetFiles(path)) - { - var fullName = file.FullName; - - if (EntityResolutionHelper.IsAudioFile(fullName)) - { - // Don't resolve these into audio files - if (string.Equals(Path.GetFileNameWithoutExtension(fullName), BaseItem.ThemeSongFilename) && EntityResolutionHelper.IsAudioFile(fullName)) - { - continue; - } - - foundAudio++; - } - if (foundAudio >= 2) - { - return true; - } - if (EntityResolutionHelper.IsVideoFile(fullName)) return false; - } - - // or a single audio file and no video files - return foundAudio > 0; + return ContainsMusic(directoryService.GetFileSystemEntries(path)); } /// @@ -122,15 +97,31 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio // If list contains at least 2 audio files or at least one and no video files consider it to contain music var foundAudio = 0; - foreach (var file in list) + foreach (var fileSystemInfo in list) { - var fullName = file.FullName; + // TODO: Support disc 1, disc 2, etc + if ((fileSystemInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory) + { + continue; + } - if (EntityResolutionHelper.IsAudioFile(fullName)) foundAudio++; + var fullName = fileSystemInfo.FullName; + + if (EntityResolutionHelper.IsAudioFile(fullName)) + { + // Don't resolve these into audio files + if (string.Equals(Path.GetFileNameWithoutExtension(fullName), BaseItem.ThemeSongFilename) && EntityResolutionHelper.IsAudioFile(fullName)) + { + continue; + } + + foundAudio++; + } if (foundAudio >= 2) { return true; } + if (EntityResolutionHelper.IsVideoFile(fullName)) return false; if (EntityResolutionHelper.IsVideoPlaceHolder(fullName)) return false; } diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index f48431dc1d..4e2b3c7b78 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1516,5 +1516,11 @@ namespace MediaBrowser.Server.Implementations.Session { ReportTranscodingInfo(deviceId, null); } + + public SessionInfo GetSession(string deviceId, string client, string version) + { + return Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && + string.Equals(i.Client, client)); + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 365845f416..a50a6f02ef 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -113,21 +113,13 @@ namespace MediaBrowser.Server.Implementations.Session var version = vals[2]; var deviceName = vals.Length > 3 ? vals[3] : string.Empty; - var session = _sessionManager.Sessions - .FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && - string.Equals(i.Client, client) && - string.Equals(i.ApplicationVersion, version)); + var session = _sessionManager.GetSession(deviceId, client, version); if (session == null && !string.IsNullOrEmpty(deviceName)) { _logger.Debug("Logging session activity"); - await _sessionManager.LogSessionActivity(client, version, deviceId, deviceName, message.Connection.RemoteEndPoint, null).ConfigureAwait(false); - - session = _sessionManager.Sessions - .FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && - string.Equals(i.Client, client) && - string.Equals(i.ApplicationVersion, version)); + session = await _sessionManager.LogSessionActivity(client, version, deviceId, deviceName, message.Connection.RemoteEndPoint, null).ConfigureAwait(false); } if (session != null) @@ -197,7 +189,7 @@ namespace MediaBrowser.Server.Implementations.Session } private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - + /// /// Reports the playback start. /// @@ -284,7 +276,7 @@ namespace MediaBrowser.Server.Implementations.Session _sessionManager.OnPlaybackProgress(info); } } - + /// /// Reports the playback progress. /// @@ -362,7 +354,7 @@ namespace MediaBrowser.Server.Implementations.Session _sessionManager.OnPlaybackStopped(info); } } - + /// /// Reports the playback stopped. /// From a49e513bc2e772905da1a2c3a7e56ce96abb8a11 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 Jun 2014 13:04:11 -0400 Subject: [PATCH 003/131] get more exact hls segment times --- MediaBrowser.Api/ApiEntryPoint.cs | 36 ++-- MediaBrowser.Api/Library/LibraryService.cs | 1 + .../Playback/BaseStreamingService.cs | 28 +-- .../Playback/Hls/BaseHlsService.cs | 62 +++---- .../Playback/Hls/DynamicHlsService.cs | 170 ++++++++++++++++-- .../Playback/Hls/HlsSegmentService.cs | 2 +- .../Playback/Hls/VideoHlsService.cs | 5 +- .../Progressive/ProgressiveStreamWriter.cs | 21 ++- .../MediaEncoding/IMediaEncoder.cs | 7 + .../Encoder/MediaEncoder.cs | 54 ++---- .../ApplicationHost.cs | 2 +- 11 files changed, 254 insertions(+), 134 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 3e9a0926be..154966240f 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Api /// /// The logger. /// The application paths. + /// The session manager. public ApiEntryPoint(ILogger logger, IServerApplicationPaths appPaths, ISessionManager sessionManager) { Logger = logger; @@ -99,7 +100,7 @@ namespace MediaBrowser.Api { var jobCount = _activeTranscodingJobs.Count; - Parallel.ForEach(_activeTranscodingJobs.ToList(), j => KillTranscodingJob(j, true)); + Parallel.ForEach(_activeTranscodingJobs.ToList(), j => KillTranscodingJob(j, FileDeleteMode.All)); // Try to allow for some time to kill the ffmpeg processes and delete the partial stream files if (jobCount > 0) @@ -119,14 +120,12 @@ namespace MediaBrowser.Api /// The path. /// The type. /// The process. - /// The start time ticks. /// The device id. /// The state. /// The cancellation token source. public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process, - long? startTimeTicks, string deviceId, StreamState state, CancellationTokenSource cancellationTokenSource) @@ -139,7 +138,6 @@ namespace MediaBrowser.Api Path = path, Process = process, ActiveRequestCount = 1, - StartTimeTicks = startTimeTicks, DeviceId = deviceId, CancellationTokenSource = cancellationTokenSource }); @@ -214,10 +212,15 @@ namespace MediaBrowser.Api /// The type. /// true if [has active transcoding job] [the specified path]; otherwise, false. public bool HasActiveTranscodingJob(string path, TranscodingJobType type) + { + return GetTranscodingJob(path, type) != null; + } + + public TranscodingJob GetTranscodingJob(string path, TranscodingJobType type) { lock (_activeTranscodingJobs) { - return _activeTranscodingJobs.Any(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); + return _activeTranscodingJobs.FirstOrDefault(j => j.Type == type && j.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); } } @@ -290,16 +293,16 @@ namespace MediaBrowser.Api { var job = (TranscodingJob)state; - KillTranscodingJob(job, true); + KillTranscodingJob(job, FileDeleteMode.All); } /// /// Kills the single transcoding job. /// /// The device id. - /// if set to true [delete files]. + /// The delete mode. /// sourcePath - internal void KillTranscodingJobs(string deviceId, bool deleteFiles) + internal void KillTranscodingJobs(string deviceId, FileDeleteMode deleteMode) { if (string.IsNullOrEmpty(deviceId)) { @@ -317,7 +320,7 @@ namespace MediaBrowser.Api foreach (var job in jobs) { - KillTranscodingJob(job, deleteFiles); + KillTranscodingJob(job, deleteMode); } } @@ -325,8 +328,8 @@ namespace MediaBrowser.Api /// Kills the transcoding job. /// /// The job. - /// if set to true [delete files]. - private void KillTranscodingJob(TranscodingJob job, bool deleteFiles) + /// The delete mode. + private void KillTranscodingJob(TranscodingJob job, FileDeleteMode deleteMode) { lock (_activeTranscodingJobs) { @@ -378,7 +381,7 @@ namespace MediaBrowser.Api } } - if (deleteFiles) + if (deleteMode == FileDeleteMode.All) { DeletePartialStreamFiles(job.Path, job.Type, 0, 1500); } @@ -486,12 +489,13 @@ namespace MediaBrowser.Api /// The kill timer. public Timer KillTimer { get; set; } - public long? StartTimeTicks { get; set; } public string DeviceId { get; set; } public CancellationTokenSource CancellationTokenSource { get; set; } public object ProcessLock = new object(); + + public bool HasExited { get; set; } } /// @@ -508,4 +512,10 @@ namespace MediaBrowser.Api /// Hls } + + public enum FileDeleteMode + { + None, + All + } } diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 802df5cca6..e1494700c8 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -213,6 +213,7 @@ namespace MediaBrowser.Api.Library } + [Route("/Library/Series/Added", "POST")] [Route("/Library/Series/Updated", "POST")] [Api(Description = "Reports that new episodes of a series have been added by an external source")] public class PostUpdatedSeries : IReturnVoid diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 1b3ff8d689..235675b983 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -138,14 +138,9 @@ namespace MediaBrowser.Api.Playback { var time = request.StartTimeTicks; - if (time.HasValue) + if (time.HasValue && time.Value > 0) { - var seconds = TimeSpan.FromTicks(time.Value).TotalSeconds; - - if (seconds > 0) - { - return string.Format("-ss {0}", seconds.ToString(UsCulture)); - } + return string.Format("-ss {0}", MediaEncoder.GetTimeParameter(time.Value)); } return string.Empty; @@ -586,7 +581,7 @@ namespace MediaBrowser.Api.Playback protected string GetTextSubtitleParam(StreamState state, CancellationToken cancellationToken) { - var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds; + var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds); if (state.SubtitleStream.IsExternal) { @@ -608,13 +603,13 @@ namespace MediaBrowser.Api.Playback return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), charsetParam, - Math.Round(seconds).ToString(UsCulture)); + seconds.ToString(UsCulture)); } return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", state.MediaPath.Replace('\\', '/').Replace(":/", "\\:/"), state.InternalSubtitleStreamOffset.ToString(UsCulture), - Math.Round(seconds).ToString(UsCulture)); + seconds.ToString(UsCulture)); } /// @@ -849,7 +844,6 @@ namespace MediaBrowser.Api.Playback ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process, - state.Request.StartTimeTicks, state.Request.DeviceId, state, cancellationTokenSource); @@ -866,7 +860,7 @@ namespace MediaBrowser.Api.Playback var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(commandLineLogMessage + Environment.NewLine + Environment.NewLine); await state.LogFileStream.WriteAsync(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length, cancellationTokenSource.Token).ConfigureAwait(false); - process.Exited += (sender, args) => OnFfMpegProcessExited(process, state); + process.Exited += (sender, args) => OnFfMpegProcessExited(process, state, outputPath); try { @@ -1092,8 +1086,16 @@ namespace MediaBrowser.Api.Playback /// /// The process. /// The state. - private void OnFfMpegProcessExited(Process process, StreamState state) + /// The output path. + private void OnFfMpegProcessExited(Process process, StreamState state, string outputPath) { + var job = ApiEntryPoint.Instance.GetTranscodingJob(outputPath, TranscodingJobType); + + if (job != null) + { + job.HasExited = true; + } + Logger.Debug("Disposing stream resources"); state.Dispose(); diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 39163a1037..8957d9fa1c 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -1,14 +1,11 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.IO; using System; @@ -223,49 +220,34 @@ namespace MediaBrowser.Api.Playback.Hls protected async Task WaitForMinimumSegmentCount(string playlist, int segmentCount, CancellationToken cancellationToken) { - while (true) - { - cancellationToken.ThrowIfCancellationRequested(); - - string fileText; + var count = 0; - // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written - using (var fileStream = FileSystem.GetFileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) + // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written + using (var fileStream = FileSystem.GetFileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) + { + using (var reader = new StreamReader(fileStream)) { - using (var reader = new StreamReader(fileStream)) + while (true) { - fileText = await reader.ReadToEndAsync().ConfigureAwait(false); + if (!reader.EndOfStream) + { + var line = await reader.ReadLineAsync().ConfigureAwait(false); + + if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) + { + count++; + if (count >= segmentCount) + { + return; + } + } + } + await Task.Delay(25, cancellationToken).ConfigureAwait(false); } } - - if (CountStringOccurrences(fileText, "#EXTINF:") >= segmentCount) - { - break; - } - - await Task.Delay(25, cancellationToken).ConfigureAwait(false); } } - /// - /// Count occurrences of strings. - /// - /// The text. - /// The pattern. - /// System.Int32. - private static int CountStringOccurrences(string text, string pattern) - { - // Loop through all instances of the string 'text'. - var count = 0; - var i = 0; - while ((i = text.IndexOf(pattern, i, StringComparison.OrdinalIgnoreCase)) != -1) - { - i += pattern.Length; - count++; - } - return count; - } - /// /// Gets the command line arguments. /// @@ -290,7 +272,7 @@ namespace MediaBrowser.Api.Playback.Hls // If isEncoding is true we're actually starting ffmpeg var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0"; - var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"", + var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"", itsOffset, inputModifier, GetInputArgument(state), diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 352cbf365c..1c274d7079 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -58,7 +59,8 @@ namespace MediaBrowser.Api.Playback.Hls public class DynamicHlsService : BaseHlsService { - public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) + public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, ILiveTvManager liveTvManager, IDlnaManager dlnaManager, IChannelManager channelManager, ISubtitleEncoder subtitleEncoder) + : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, liveTvManager, dlnaManager, channelManager, subtitleEncoder) { } @@ -82,6 +84,11 @@ namespace MediaBrowser.Api.Playback.Hls private static readonly SemaphoreSlim FfmpegStartLock = new SemaphoreSlim(1, 1); private async Task GetDynamicSegment(GetDynamicHlsVideoSegment request, bool isMain) { + if ((request.StartTimeTicks ?? 0) > 0) + { + throw new ArgumentException("StartTimeTicks is not allowed."); + } + var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; @@ -96,7 +103,7 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType.Hls); - return GetSegementResult(segmentPath); + return await GetSegmentResult(playlistPath, segmentPath, index, cancellationToken).ConfigureAwait(false); } await FfmpegStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); @@ -105,16 +112,26 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType.Hls); - return GetSegementResult(segmentPath); + return await GetSegmentResult(playlistPath, segmentPath, index, cancellationToken).ConfigureAwait(false); } else { - if (index == 0) + var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath); + + if (currentTranscodingIndex == null || index < currentTranscodingIndex.Value || (index - currentTranscodingIndex.Value) > 3) { // If the playlist doesn't already exist, startup ffmpeg try { - ApiEntryPoint.Instance.KillTranscodingJobs(state.Request.DeviceId, false); + if (currentTranscodingIndex.HasValue) + { + ApiEntryPoint.Instance.KillTranscodingJobs(state.Request.DeviceId, FileDeleteMode.None); + + DeleteLastFile(playlistPath, 0); + } + + var startSeconds = index * state.SegmentLength; + request.StartTimeTicks = TimeSpan.FromSeconds(startSeconds).Ticks; await StartFfMpeg(state, playlistPath, cancellationTokenSource).ConfigureAwait(false); } @@ -124,7 +141,7 @@ namespace MediaBrowser.Api.Playback.Hls throw; } - await WaitForMinimumSegmentCount(playlistPath, 2, cancellationTokenSource.Token).ConfigureAwait(false); + await WaitForMinimumSegmentCount(playlistPath, 1, cancellationTokenSource.Token).ConfigureAwait(false); } } } @@ -140,12 +157,75 @@ namespace MediaBrowser.Api.Playback.Hls } Logger.Info("returning {0}", segmentPath); - return GetSegementResult(segmentPath); + return await GetSegmentResult(playlistPath, segmentPath, index, cancellationToken).ConfigureAwait(false); + } + + public int? GetCurrentTranscodingIndex(string playlist) + { + var file = GetLastTranscodingFile(playlist, FileSystem); + + if (file == null) + { + return null; + } + + var playlistFilename = Path.GetFileNameWithoutExtension(playlist); + + var indexString = Path.GetFileNameWithoutExtension(file.Name).Substring(playlistFilename.Length); + + return int.Parse(indexString, NumberStyles.Integer, UsCulture); + } + + private void DeleteLastFile(string path, int retryCount) + { + if (retryCount >= 5) + { + return; + } + + var file = GetLastTranscodingFile(path, FileSystem); + + if (file != null) + { + try + { + File.Delete(file.FullName); + } + catch (IOException ex) + { + Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName); + + Thread.Sleep(100); + DeleteLastFile(path, retryCount + 1); + } + catch (Exception ex) + { + Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName); + } + } + } + + private static FileInfo GetLastTranscodingFile(string playlist, IFileSystem fileSystem) + { + var folder = Path.GetDirectoryName(playlist); + + try + { + return new DirectoryInfo(folder) + .EnumerateFiles("*", SearchOption.TopDirectoryOnly) + .Where(i => string.Equals(i.Extension, ".ts", StringComparison.OrdinalIgnoreCase)) + .OrderByDescending(fileSystem.GetLastWriteTimeUtc) + .FirstOrDefault(); + } + catch (DirectoryNotFoundException) + { + return null; + } } protected override int GetStartNumber(StreamState state) { - var request = (GetDynamicHlsVideoSegment) state.Request; + var request = (GetDynamicHlsVideoSegment)state.Request; return int.Parse(request.SegmentId, NumberStyles.Integer, UsCulture); } @@ -159,10 +239,65 @@ namespace MediaBrowser.Api.Playback.Hls return Path.Combine(folder, filename + index.ToString(UsCulture) + ".ts"); } - private object GetSegementResult(string path) + private async Task GetSegmentResult(string playlistPath, string segmentPath, int segmentIndex, CancellationToken cancellationToken) { - // TODO: Handle if it's currently being written to - return ResultFactory.GetStaticFileResult(Request, path, FileShare.ReadWrite); + // If all transcoding has completed, just return immediately + if (!IsTranscoding(playlistPath)) + { + return ResultFactory.GetStaticFileResult(Request, segmentPath, FileShare.ReadWrite); + } + + var segmentFilename = Path.GetFileName(segmentPath); + + // If it appears in the playlist, it's done + if (File.ReadAllText(playlistPath).IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + { + return ResultFactory.GetStaticFileResult(Request, segmentPath, FileShare.ReadWrite); + } + + // if a different file is encoding, it's done + //var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath); + //if (currentTranscodingIndex > segmentIndex) + //{ + // return ResultFactory.GetStaticFileResult(Request, segmentPath, FileShare.ReadWrite); + //} + + // Wait for the file to stop being written to, then stream it + var length = new FileInfo(segmentPath).Length; + var eofCount = 0; + + while (eofCount < 10) + { + var info = new FileInfo(segmentPath); + + if (!info.Exists) + { + break; + } + + var newLength = info.Length; + + if (newLength == length) + { + eofCount++; + } + else + { + eofCount = 0; + } + + length = newLength; + await Task.Delay(100, cancellationToken).ConfigureAwait(false); + } + + return ResultFactory.GetStaticFileResult(Request, segmentPath, FileShare.ReadWrite); + } + + private bool IsTranscoding(string playlistPath) + { + var job = ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType); + + return job != null && !job.HasExited; } private async Task GetAsync(GetMasterHlsVideoStream request) @@ -312,9 +447,8 @@ namespace MediaBrowser.Api.Playback.Hls return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy"; } - var keyFrameArg = state.ReadInputAtNativeFramerate ? - " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+1))" : - " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))"; + var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + state.SegmentLength.ToString(UsCulture)); var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; @@ -344,5 +478,13 @@ namespace MediaBrowser.Api.Playback.Hls { return ".ts"; } + + protected override TranscodingJobType TranscodingJobType + { + get + { + return TranscodingJobType.Hls; + } + } } } diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs index 2099bcd3a5..f31671b1a1 100644 --- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs +++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Api.Playback.Hls public void Delete(StopEncodingProcess request) { - ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, true); + ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, FileDeleteMode.All); } /// diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index 2379fb0050..1a925378bb 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -159,9 +159,8 @@ namespace MediaBrowser.Api.Playback.Hls return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy"; } - var keyFrameArg = state.ReadInputAtNativeFramerate ? - " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+1))" : - " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))"; + var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + state.SegmentLength.ToString(UsCulture)); var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index f99cef8eb8..36ae7f1002 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.IO; using MediaBrowser.Model.Logging; using ServiceStack.Web; -using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; @@ -60,7 +59,7 @@ namespace MediaBrowser.Api.Playback.Progressive { try { - await StreamFile(Path, responseStream).ConfigureAwait(false); + await new ProgressiveFileCopier(_fileSystem).StreamFile(Path, responseStream).ConfigureAwait(false); } catch { @@ -73,14 +72,18 @@ namespace MediaBrowser.Api.Playback.Progressive ApiEntryPoint.Instance.OnTranscodeEndRequest(Path, TranscodingJobType.Progressive); } } + } - /// - /// Streams the file. - /// - /// The path. - /// The output stream. - /// Task{System.Boolean}. - private async Task StreamFile(string path, Stream outputStream) + public class ProgressiveFileCopier + { + private readonly IFileSystem _fileSystem; + + public ProgressiveFileCopier(IFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + + public async Task StreamFile(string path, Stream outputStream) { var eofCount = 0; long position = 0; diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index f7e8554d1b..9468fd9875 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -68,5 +68,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The protocol. /// System.String. string GetInputArgument(string[] inputFiles, MediaProtocol protocol); + + /// + /// Gets the time parameter. + /// + /// The ticks. + /// System.String. + string GetTimeParameter(long ticks); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 5ee119e133..1087c905c8 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -1,5 +1,3 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -11,7 +9,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -27,11 +24,6 @@ namespace MediaBrowser.MediaEncoding.Encoder /// private readonly ILogger _logger; - /// - /// The _app paths - /// - private readonly IApplicationPaths _appPaths; - /// /// Gets the json serializer. /// @@ -53,23 +45,17 @@ namespace MediaBrowser.MediaEncoding.Encoder /// private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2); - private readonly IFileSystem _fileSystem; - public string FFMpegPath { get; private set; } public string FFProbePath { get; private set; } public string Version { get; private set; } - public MediaEncoder(ILogger logger, IApplicationPaths appPaths, - IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, - IFileSystem fileSystem) + public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version) { _logger = logger; - _appPaths = appPaths; _jsonSerializer = jsonSerializer; Version = version; - _fileSystem = fileSystem; FFProbePath = ffProbePath; FFMpegPath = ffMpegPath; } @@ -263,30 +249,6 @@ namespace MediaBrowser.MediaEncoding.Encoder ((Process)sender).Dispose(); } - private const int FastSeekOffsetSeconds = 1; - - protected string GetFastSeekCommandLineParameter(TimeSpan offset) - { - var seconds = offset.TotalSeconds - FastSeekOffsetSeconds; - - if (seconds > 0) - { - return string.Format("-ss {0} ", seconds.ToString(UsCulture)); - } - - return string.Empty; - } - - protected string GetSlowSeekCommandLineParameter(TimeSpan offset) - { - if (offset.TotalSeconds - FastSeekOffsetSeconds > 0) - { - return string.Format(" -ss {0}", FastSeekOffsetSeconds.ToString(UsCulture)); - } - - return string.Empty; - } - public Task ExtractAudioImage(string path, CancellationToken cancellationToken) { return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken); @@ -368,7 +330,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (offset.HasValue) { - args = string.Format("-ss {0} ", Convert.ToInt32(offset.Value.TotalSeconds)).ToString(UsCulture) + args; + args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args; } var process = new Process @@ -463,5 +425,17 @@ namespace MediaBrowser.MediaEncoding.Encoder _videoImageResourcePool.Dispose(); } } + + public string GetTimeParameter(long ticks) + { + var time = TimeSpan.FromTicks(ticks); + + return GetTimeParameter(time); + } + + public string GetTimeParameter(TimeSpan time) + { + return time.ToString(@"hh\:mm\:ss\.fff", UsCulture); + } } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index e93785bac2..d03c5fe3dc 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -588,7 +588,7 @@ namespace MediaBrowser.ServerApplication { var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo(progress).ConfigureAwait(false); - MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.EncoderPath, info.ProbePath, info.Version, FileSystemManager); + MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, info.EncoderPath, info.ProbePath, info.Version); RegisterSingleInstance(MediaEncoder); } From b1dd6365da6a2212555946d95b5d698a8af1ea4c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 27 Jun 2014 22:43:10 -0400 Subject: [PATCH 004/131] updates to dynamic hls --- .../Playback/Hls/DynamicHlsService.cs | 58 +++++++++++++++---- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 1c274d7079..5913e81db8 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -118,14 +118,14 @@ namespace MediaBrowser.Api.Playback.Hls { var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath); - if (currentTranscodingIndex == null || index < currentTranscodingIndex.Value || (index - currentTranscodingIndex.Value) > 3) + if (currentTranscodingIndex == null || index < currentTranscodingIndex.Value || (index - currentTranscodingIndex.Value) > 4) { // If the playlist doesn't already exist, startup ffmpeg try { if (currentTranscodingIndex.HasValue) { - ApiEntryPoint.Instance.KillTranscodingJobs(state.Request.DeviceId, FileDeleteMode.None); + ApiEntryPoint.Instance.KillTranscodingJobs(state.Request.DeviceId, playlistPath, FileDeleteMode.None); DeleteLastFile(playlistPath, 0); } @@ -318,12 +318,12 @@ namespace MediaBrowser.Api.Playback.Hls baselineStreamBitrate = hlsVideoRequest.BaselineStreamAudioBitRate ?? baselineStreamBitrate; } - var playlistText = GetMasterPlaylistFileText(videoBitrate + audioBitrate, appendBaselineStream, baselineStreamBitrate); + var playlistText = GetMasterPlaylistFileText(videoBitrate + audioBitrate); return ResultFactory.GetResult(playlistText, Common.Net.MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary()); } - private string GetMasterPlaylistFileText(int bitrate, bool includeBaselineStream, int baselineStreamBitrate) + private string GetMasterPlaylistFileText(int bitrate) { var builder = new StringBuilder(); @@ -340,14 +340,6 @@ namespace MediaBrowser.Api.Playback.Hls var playlistUrl = "main.m3u8" + queryString; builder.AppendLine(playlistUrl); - // Low bitrate stream - if (includeBaselineStream) - { - builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + baselineStreamBitrate.ToString(UsCulture)); - playlistUrl = "baseline.m3u8" + queryString; - builder.AppendLine(playlistUrl); - } - return builder.ToString(); } @@ -375,6 +367,7 @@ namespace MediaBrowser.Api.Playback.Hls builder.AppendLine("#EXT-X-VERSION:3"); builder.AppendLine("#EXT-X-TARGETDURATION:" + state.SegmentLength.ToString(UsCulture)); builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); + builder.AppendLine("#EXT-X-ALLOW-CACHE:NO"); var queryStringIndex = Request.RawUrl.IndexOf('?'); var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex); @@ -469,6 +462,47 @@ namespace MediaBrowser.Api.Playback.Hls return args; } + /// + /// Gets the command line arguments. + /// + /// The output path. + /// The state. + /// if set to true [is encoding]. + /// System.String. + protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding) + { + var hlsVideoRequest = state.VideoRequest as GetHlsVideoStream; + + var itsOffsetMs = hlsVideoRequest == null + ? 0 + : ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs; + + var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds.ToString(UsCulture)); + + var threads = GetNumberOfThreads(state, false); + + var inputModifier = GetInputModifier(state); + + // If isEncoding is true we're actually starting ffmpeg + var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0"; + + var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -flags -global_header {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"", + itsOffset, + inputModifier, + GetInputArgument(state), + threads, + GetMapArgs(state), + GetVideoArguments(state), + GetAudioArguments(state), + state.SegmentLength.ToString(UsCulture), + startNumberParam, + state.HlsListSize.ToString(UsCulture), + outputPath + ).Trim(); + + return args; + } + /// /// Gets the segment file extension. /// From 608ebf4829e7e394170bb2dec8a33c83600e9c08 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 28 Jun 2014 15:35:30 -0400 Subject: [PATCH 005/131] update video player layout --- MediaBrowser.Api/ApiEntryPoint.cs | 37 ++++++ .../Playback/BaseStreamingService.cs | 109 ++++++++++++------ .../Playback/Hls/BaseHlsService.cs | 2 +- MediaBrowser.Api/Playback/StreamRequest.cs | 2 +- MediaBrowser.Api/Playback/StreamState.cs | 4 + .../UserLibrary/ArtistsService.cs | 4 +- .../UserLibrary/GameGenresService.cs | 4 +- MediaBrowser.Api/UserLibrary/GenresService.cs | 4 +- .../UserLibrary/MusicGenresService.cs | 4 +- .../UserLibrary/PersonsService.cs | 4 +- .../UserLibrary/StudiosService.cs | 4 +- MediaBrowser.Api/UserLibrary/YearsService.cs | 4 +- MediaBrowser.Controller/Dto/IDtoService.cs | 10 -- .../LiveTv/LiveTvChannel.cs | 4 +- MediaBrowser.Dlna/PlayTo/Device.cs | 28 +---- MediaBrowser.Dlna/PlayTo/TransportCommands.cs | 6 +- MediaBrowser.Model/Dto/ChapterInfoDto.cs | 3 +- .../Dto/DtoService.cs | 40 +++++-- .../HttpServer/LoggerUtils.cs | 5 +- .../Api/DashboardService.cs | 1 - .../MediaBrowser.WebDashboard.csproj | 3 - 21 files changed, 167 insertions(+), 115 deletions(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 154966240f..5775546108 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -324,6 +324,35 @@ namespace MediaBrowser.Api } } + /// + /// Kills the transcoding jobs. + /// + /// The device identifier. + /// The output path. + /// The delete mode. + /// deviceId + internal void KillTranscodingJobs(string deviceId, string outputPath, FileDeleteMode deleteMode) + { + if (string.IsNullOrEmpty(deviceId)) + { + throw new ArgumentNullException("deviceId"); + } + + var jobs = new List(); + + lock (_activeTranscodingJobs) + { + // This is really only needed for HLS. + // Progressive streams can stop on their own reliably + jobs.AddRange(_activeTranscodingJobs.Where(i => string.Equals(deviceId, i.DeviceId, StringComparison.OrdinalIgnoreCase) && string.Equals(outputPath, i.Path, StringComparison.OrdinalIgnoreCase))); + } + + foreach (var job in jobs) + { + KillTranscodingJob(job, deleteMode); + } + } + /// /// Kills the transcoding job. /// @@ -443,6 +472,8 @@ namespace MediaBrowser.Api .Where(f => f.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1) .ToList(); + Exception e = null; + foreach (var file in filesToDelete) { try @@ -452,9 +483,15 @@ namespace MediaBrowser.Api } catch (IOException ex) { + e = ex; Logger.ErrorException("Error deleting HLS file {0}", ex, file); } } + + if (e != null) + { + throw e; + } } } diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 235675b983..3cb7b914ad 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -123,7 +123,11 @@ namespace MediaBrowser.Api.Playback var outputFileExtension = GetOutputFileExtension(state); - return Path.Combine(folder, GetCommandLineArguments("dummy\\dummy", state, false).GetMD5() + (outputFileExtension ?? string.Empty).ToLower()); + var data = GetCommandLineArguments("dummy\\dummy", state, false); + + data += "-" + (state.Request.DeviceId ?? string.Empty); + + return Path.Combine(folder, data.GetMD5().ToString("N") + (outputFileExtension ?? string.Empty).ToLower()); } protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); @@ -772,7 +776,7 @@ namespace MediaBrowser.Api.Playback /// /// The state. /// System.String. - protected string GetInputArgument(StreamState state) + protected virtual string GetInputArgument(StreamState state) { var protocol = state.InputProtocol; @@ -789,6 +793,58 @@ namespace MediaBrowser.Api.Playback return MediaEncoder.GetInputArgument(inputPath, protocol); } + private async Task AcquireResources(StreamState state, CancellationTokenSource cancellationTokenSource) + { + if (state.VideoType == VideoType.Iso && state.IsoType.HasValue && IsoManager.CanMount(state.MediaPath)) + { + state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false); + } + + if (string.IsNullOrEmpty(state.MediaPath)) + { + if (string.Equals(state.ItemType, typeof(LiveTvChannel).Name)) + { + var streamInfo = await LiveTvManager.GetChannelStream(state.Request.Id, cancellationTokenSource.Token).ConfigureAwait(false); + + state.LiveTvStreamId = streamInfo.Id; + + if (!string.IsNullOrEmpty(streamInfo.Path)) + { + state.MediaPath = streamInfo.Path; + state.InputProtocol = MediaProtocol.File; + + await Task.Delay(1000, cancellationTokenSource.Token).ConfigureAwait(false); + } + else if (!string.IsNullOrEmpty(streamInfo.Url)) + { + state.MediaPath = streamInfo.Url; + state.InputProtocol = MediaProtocol.Http; + } + } + + else if (string.Equals(state.ItemType, typeof(LiveTvVideoRecording).Name) || + string.Equals(state.ItemType, typeof(LiveTvAudioRecording).Name)) + { + var streamInfo = await LiveTvManager.GetRecordingStream(state.Request.Id, cancellationTokenSource.Token).ConfigureAwait(false); + + state.LiveTvStreamId = streamInfo.Id; + + if (!string.IsNullOrEmpty(streamInfo.Path)) + { + state.MediaPath = streamInfo.Path; + state.InputProtocol = MediaProtocol.File; + + await Task.Delay(1000, cancellationTokenSource.Token).ConfigureAwait(false); + } + else if (!string.IsNullOrEmpty(streamInfo.Url)) + { + state.MediaPath = streamInfo.Url; + state.InputProtocol = MediaProtocol.Http; + } + } + } + } + /// /// Starts the FFMPEG. /// @@ -806,10 +862,7 @@ namespace MediaBrowser.Api.Playback Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); - if (state.VideoType == VideoType.Iso && state.IsoType.HasValue && IsoManager.CanMount(state.MediaPath)) - { - state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false); - } + await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false); var commandLineArgs = GetCommandLineArguments(outputPath, state, true); @@ -1363,6 +1416,8 @@ namespace MediaBrowser.Api.Playback List mediaStreams = null; + state.ItemType = item.GetType().Name; + if (item is ILiveTvRecording) { var recording = await LiveTvManager.GetInternalRecording(request.Id, cancellationToken).ConfigureAwait(false); @@ -1379,16 +1434,8 @@ namespace MediaBrowser.Api.Playback mediaStreams = source.MediaStreams; - if (string.IsNullOrWhiteSpace(path) && string.IsNullOrWhiteSpace(mediaUrl)) - { - var streamInfo = await LiveTvManager.GetRecordingStream(request.Id, cancellationToken).ConfigureAwait(false); - - state.LiveTvStreamId = streamInfo.Id; - mediaStreams = streamInfo.MediaStreams; - - path = streamInfo.Path; - mediaUrl = streamInfo.Url; - } + // Just to prevent this from being null and causing other methods to fail + state.MediaPath = string.Empty; if (!string.IsNullOrEmpty(path)) { @@ -1421,30 +1468,16 @@ namespace MediaBrowser.Api.Playback state.VideoType = VideoType.VideoFile; state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase); - - var streamInfo = await LiveTvManager.GetChannelStream(request.Id, cancellationToken).ConfigureAwait(false); - - state.LiveTvStreamId = streamInfo.Id; - mediaStreams = streamInfo.MediaStreams; - - if (!string.IsNullOrEmpty(streamInfo.Path)) - { - state.MediaPath = streamInfo.Path; - state.InputProtocol = MediaProtocol.File; - - await Task.Delay(1000, cancellationToken).ConfigureAwait(false); - } - else if (!string.IsNullOrEmpty(streamInfo.Url)) - { - state.MediaPath = streamInfo.Url; - state.InputProtocol = MediaProtocol.Http; - } + mediaStreams = new List(); state.ReadInputAtNativeFramerate = true; state.OutputAudioSync = "1000"; state.DeInterlace = true; state.InputVideoSync = "-1"; state.InputAudioSync = "1"; + + // Just to prevent this from being null and causing other methods to fail + state.MediaPath = string.Empty; } else if (item is IChannelMediaItem) { @@ -1500,7 +1533,7 @@ namespace MediaBrowser.Api.Playback AttachMediaStreamInfo(state, mediaStreams, videoRequest, url); - state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 10; + state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 7; state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440; var container = Path.GetExtension(state.RequestedUrl); @@ -1928,7 +1961,7 @@ namespace MediaBrowser.Api.Playback videoRequest.Height = null; } - protected string GetInputModifier(StreamState state) + protected string GetInputModifier(StreamState state, bool genPts = true) { var inputModifier = string.Empty; @@ -1948,9 +1981,9 @@ namespace MediaBrowser.Api.Playback inputModifier += " " + GetFastSeekCommandLineParameter(state.Request); inputModifier = inputModifier.Trim(); - if (state.VideoRequest != null) + if (state.VideoRequest != null && genPts) { - inputModifier += " -fflags genpts"; + inputModifier += " -fflags +genpts"; } if (!string.IsNullOrEmpty(state.InputAudioSync)) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 8957d9fa1c..e41a331be9 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -272,7 +272,7 @@ namespace MediaBrowser.Api.Playback.Hls // If isEncoding is true we're actually starting ffmpeg var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0"; - var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"", + var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"", itsOffset, inputModifier, GetInputArgument(state), diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 0e4db45e31..dfb57ef0d7 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Playback /// The start time ticks. [ApiMember(Name = "StartTimeTicks", Description = "Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public long? StartTimeTicks { get; set; } - + /// /// Gets or sets the audio bit rate. /// diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 4737097cb4..c6f4544477 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -94,6 +94,10 @@ namespace MediaBrowser.Api.Playback public bool EnableMpegtsM2TsMode { get; set; } public TranscodeSeekInfo TranscodeSeekInfo { get; set; } + public long? EncodingDurationTicks { get; set; } + + public string ItemType { get; set; } + public string GetMimeType(string outputPath) { if (!string.IsNullOrEmpty(MimeType)) diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index 20b0f5fb1e..13027d30b5 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -88,10 +88,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs index 34eadc3c35..b1379ad5d6 100644 --- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs @@ -76,10 +76,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 58dec11f61..68f0e21edc 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -81,10 +81,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs index 9b7a941d84..538b165751 100644 --- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs @@ -76,10 +76,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs index f7ea4198d6..962effdeda 100644 --- a/MediaBrowser.Api/UserLibrary/PersonsService.cs +++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs @@ -93,10 +93,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs index 7eff5054be..4c38ba0d1f 100644 --- a/MediaBrowser.Api/UserLibrary/StudiosService.cs +++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs @@ -78,10 +78,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs index 8a3bc12b2b..4dda045c06 100644 --- a/MediaBrowser.Api/UserLibrary/YearsService.cs +++ b/MediaBrowser.Api/UserLibrary/YearsService.cs @@ -78,10 +78,10 @@ namespace MediaBrowser.Api.UserLibrary { var user = UserManager.GetUserById(request.UserId.Value); - return DtoService.GetItemByNameDto(item, fields.ToList(), user); + return DtoService.GetBaseItemDto(item, fields.ToList(), user); } - return DtoService.GetItemByNameDto(item, fields.ToList()); + return DtoService.GetBaseItemDto(item, fields.ToList()); } /// diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index 0482e140b0..f9d7cc21af 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -49,16 +49,6 @@ namespace MediaBrowser.Controller.Dto /// Task{BaseItemDto}. BaseItemDto GetBaseItemDto(BaseItem item, List fields, User user = null, BaseItem owner = null); - /// - /// Gets the item by name dto. - /// - /// The item. - /// The fields. - /// The user. - /// BaseItemDto. - BaseItemDto GetItemByNameDto(T item, List fields, User user = null) - where T : BaseItem, IItemByName; - /// /// Gets the chapter information dto. /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 01fed68c8a..f2fa912cad 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -3,13 +3,13 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; using System.Linq; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvChannel : BaseItem, IItemByName, IHasMediaSources + public class LiveTvChannel : BaseItem, IHasMediaSources { /// /// Gets the user data key. diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index a5c3a6038a..0580740279 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -289,7 +289,8 @@ namespace MediaBrowser.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, url, dictionary), header) + var post = AvCommands.BuildPost(command, service.ServiceType, url, dictionary); + await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header) .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); @@ -315,31 +316,6 @@ namespace MediaBrowser.Dlna.PlayTo return SecurityElement.Escape(value); } - public async Task SetNextAvTransport(string value, string header, string metaData) - { - var command = AvCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetNextAVTransportURI"); - if (command == null) - return; - - var dictionary = new Dictionary - { - {"NextURI", value}, - {"NextURIMetaData", CreateDidlMeta(metaData)} - }; - - var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); - - if (service == null) - { - throw new InvalidOperationException("Unable to find service"); - } - - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, value, dictionary), header) - .ConfigureAwait(false); - - RestartTimer(); - } - public async Task SetPlay() { var command = AvCommands.ServiceActions.FirstOrDefault(c => c.Name == "Play"); diff --git a/MediaBrowser.Dlna/PlayTo/TransportCommands.cs b/MediaBrowser.Dlna/PlayTo/TransportCommands.cs index 13b9b6b189..31e25a3676 100644 --- a/MediaBrowser.Dlna/PlayTo/TransportCommands.cs +++ b/MediaBrowser.Dlna/PlayTo/TransportCommands.cs @@ -165,12 +165,12 @@ namespace MediaBrowser.Dlna.PlayTo private string BuildArgumentXml(Argument argument, string value, string commandParameter = "") { - var state = StateVariables.FirstOrDefault(a => a.Name == argument.RelatedStateVariable); + var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase)); if (state != null) { - var sendValue = (state.AllowedValues.FirstOrDefault(a => a == commandParameter) ?? - state.AllowedValues.FirstOrDefault()) ?? + var sendValue = state.AllowedValues.FirstOrDefault(a => string.Equals(a, commandParameter, StringComparison.OrdinalIgnoreCase)) ?? + state.AllowedValues.FirstOrDefault() ?? value; return string.Format("<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}", argument.Name, state.DataType ?? "string", sendValue); diff --git a/MediaBrowser.Model/Dto/ChapterInfoDto.cs b/MediaBrowser.Model/Dto/ChapterInfoDto.cs index 09dd2d5820..1ec4251697 100644 --- a/MediaBrowser.Model/Dto/ChapterInfoDto.cs +++ b/MediaBrowser.Model/Dto/ChapterInfoDto.cs @@ -1,5 +1,4 @@ -using System; -using System.ComponentModel; +using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 061898176b..6684c4efbe 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -62,6 +62,26 @@ namespace MediaBrowser.Server.Implementations.Dto /// Task{DtoBaseItem}. /// item public BaseItemDto GetBaseItemDto(BaseItem item, List fields, User user = null, BaseItem owner = null) + { + var byName = item as IItemByName; + + if (byName != null) + { + var libraryItems = user != null ? + user.RootFolder.GetRecursiveChildren(user) : + _libraryManager.RootFolder.RecursiveChildren; + + var dto = GetBaseItemDtoInternal(item, fields, user); + + SetItemByNameInfo(item, dto, byName.GetTaggedItems(libraryItems).ToList(), user); + + return dto; + } + + return GetBaseItemDtoInternal(item, fields, user, owner); + } + + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, List fields, User user = null, BaseItem owner = null) { if (item == null) { @@ -141,20 +161,18 @@ namespace MediaBrowser.Server.Implementations.Dto return dto; } - public BaseItemDto GetItemByNameDto(T item, List fields, User user = null) - where T : BaseItem, IItemByName - { - var libraryItems = user != null ? user.RootFolder.GetRecursiveChildren(user) : - _libraryManager.RootFolder.RecursiveChildren; - - return GetItemByNameDto(item, fields, item.GetTaggedItems(libraryItems).ToList(), user); - } - public BaseItemDto GetItemByNameDto(T item, List fields, List taggedItems, User user = null) where T : BaseItem, IItemByName { - var dto = GetBaseItemDto(item, fields, user); + var dto = GetBaseItemDtoInternal(item, fields, user); + SetItemByNameInfo(item, dto, taggedItems, user); + + return dto; + } + + private void SetItemByNameInfo(BaseItem item, BaseItemDto dto, List taggedItems, User user = null) + { if (item is MusicArtist || item is MusicGenre) { dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); @@ -181,8 +199,6 @@ namespace MediaBrowser.Server.Implementations.Dto } dto.ChildCount = taggedItems.Count; - - return dto; } /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs index 0f7e94ac59..3c8f86b1e4 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Logging; +using System.Globalization; +using MediaBrowser.Model.Logging; using System; using System.Linq; using System.Net; @@ -45,7 +46,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer //log.AppendLine("Headers: " + string.Join(",", response.Headers.AllKeys.Select(k => k + "=" + response.Headers[k]))); - var responseTime = string.Format(". Response time: {0} ms", duration.TotalMilliseconds); + var responseTime = string.Format(". Response time: {0} ms. Content length: {1} bytes.", duration.TotalMilliseconds, response.ContentLength64.ToString(CultureInfo.InvariantCulture)); var msg = "HTTP Response " + statusCode + " to " + endPoint + responseTime; diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 40a9d8ed67..acdbc9d65f 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -668,7 +668,6 @@ namespace MediaBrowser.WebDashboard.Api { "site.css", "chromecast.css", - "contextmenu.css", "mediaplayer.css", "mediaplayer-video.css", "librarymenu.css", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1ae22d49ef..be05261b7b 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -113,9 +113,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From 690491979453b8f67b581f2035ede2e136e74a87 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 28 Jun 2014 22:30:20 -0400 Subject: [PATCH 006/131] add tagline to editing interface --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- MediaBrowser.Api/ItemUpdateService.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 5775546108..2177f90c2f 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -418,7 +418,7 @@ namespace MediaBrowser.Api private async void DeletePartialStreamFiles(string path, TranscodingJobType jobType, int retryCount, int delayMs) { - if (retryCount >= 8) + if (retryCount >= 10) { return; } diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 4feba82b0c..ad7da8e3c5 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -108,6 +108,12 @@ namespace MediaBrowser.Api hasTags.Tags = request.Tags; } + var hasTaglines = item as IHasTaglines; + if (hasTaglines != null) + { + hasTaglines.Taglines = request.Taglines; + } + var hasShortOverview = item as IHasShortOverview; if (hasShortOverview != null) { From 933443c2b948d43e4ec41d7f8c11fd6ab3a0ab7e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Jun 2014 13:35:05 -0400 Subject: [PATCH 007/131] added modular configuration --- MediaBrowser.Api/ConfigurationService.cs | 38 ++++++- MediaBrowser.Api/Dlna/DlnaServerService.cs | 9 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 1 + .../BaseApplicationHost.cs | 1 + .../Configuration/BaseConfigurationManager.cs | 91 +++++++++++++++-- .../ConfigurationUpdateEventArgs.cs | 18 ++++ .../Configuration/IConfigurationFactory.cs | 17 ++++ .../Configuration/IConfigurationManager.cs | 43 +++++++- .../MediaBrowser.Common.csproj | 2 + MediaBrowser.Common/Net/MimeTypes.cs | 5 + .../Chapters/IChapterManager.cs | 7 ++ .../MediaEncoding/IMediaEncoder.cs | 21 ++++ MediaBrowser.Dlna/ConfigurationExtension.cs | 29 ++++++ .../ContentDirectory/ContentDirectory.cs | 6 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 22 +++-- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 1 + MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 6 +- MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs | 6 +- .../Service/BaseControlHandler.cs | 2 +- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 30 +++--- .../Encoder/MediaEncoder.cs | 99 +++++++++++++++++-- .../Subtitles/SubtitleEncoder.cs | 11 +-- .../MediaBrowser.Model.Portable.csproj | 9 ++ .../MediaBrowser.Model.net35.csproj | 9 ++ .../Configuration/ChannelOptions.cs | 18 ++++ .../Configuration/ChapterOptions.cs | 27 +++++ .../Configuration/ServerConfiguration.cs | 61 ++---------- .../Configuration/SubtitlePlaybackMode.cs | 10 ++ .../Configuration/UserConfiguration.cs | 8 -- MediaBrowser.Model/MediaBrowser.Model.csproj | 3 + .../Chapters/ChapterManager.cs | 32 +++++- .../MediaInfo/FFProbeVideoInfo.cs | 6 +- .../MediaEncoder/EncodingManager.cs | 14 ++- .../ApplicationHost.cs | 27 ++++- 34 files changed, 563 insertions(+), 126 deletions(-) create mode 100644 MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs create mode 100644 MediaBrowser.Common/Configuration/IConfigurationFactory.cs create mode 100644 MediaBrowser.Dlna/ConfigurationExtension.cs create mode 100644 MediaBrowser.Model/Configuration/ChannelOptions.cs create mode 100644 MediaBrowser.Model/Configuration/ChapterOptions.cs create mode 100644 MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index b3191cd4b9..39fcc50d8f 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -8,8 +8,11 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using ServiceStack; +using ServiceStack.Text.Controller; +using ServiceStack.Web; using System; using System.Collections.Generic; +using System.IO; using System.Linq; namespace MediaBrowser.Api @@ -23,6 +26,13 @@ namespace MediaBrowser.Api } + [Route("/System/Configuration/{Key}", "GET", Summary = "Gets a named configuration")] + public class GetNamedConfiguration + { + [ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Key { get; set; } + } + /// /// Class UpdateConfiguration /// @@ -31,6 +41,15 @@ namespace MediaBrowser.Api { } + [Route("/System/Configuration/{Key}", "POST", Summary = "Updates named configuration")] + public class UpdateNamedConfiguration : IReturnVoid, IRequiresRequestStream + { + [ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Key { get; set; } + + public Stream RequestStream { get; set; } + } + [Route("/System/Configuration/MetadataOptions/Default", "GET", Summary = "Gets a default MetadataOptions object")] public class GetDefaultMetadataOptions : IReturn { @@ -88,6 +107,13 @@ namespace MediaBrowser.Api return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration); } + public object Get(GetNamedConfiguration request) + { + var result = _configurationManager.GetConfiguration(request.Key); + + return ToOptimizedResult(result); + } + /// /// Posts the specified configuraiton. /// @@ -95,7 +121,6 @@ namespace MediaBrowser.Api public void Post(UpdateConfiguration request) { // Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration - var json = _jsonSerializer.SerializeToString(request); var config = _jsonSerializer.DeserializeFromString(json); @@ -103,6 +128,17 @@ namespace MediaBrowser.Api _configurationManager.ReplaceConfiguration(config); } + public void Post(UpdateNamedConfiguration request) + { + var pathInfo = PathInfo.Parse(Request.PathInfo); + var key = pathInfo.GetArgumentValue(2); + + var configurationType = _configurationManager.GetConfigurationType(key); + var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, configurationType); + + _configurationManager.SaveConfiguration(key, configuration); + } + public object Get(GetDefaultMetadataOptions request) { return ToOptimizedSerializedResultUsingCache(new MetadataOptions()); diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs index 28de8ee174..82bd394f0c 100644 --- a/MediaBrowser.Api/Dlna/DlnaServerService.cs +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Dlna; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Model.Configuration; using ServiceStack; using ServiceStack.Text.Controller; using ServiceStack.Web; @@ -76,11 +78,14 @@ namespace MediaBrowser.Api.Dlna private readonly IContentDirectory _contentDirectory; private readonly IConnectionManager _connectionManager; - public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager) + private readonly IConfigurationManager _config; + + public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IConfigurationManager config) { _dlnaManager = dlnaManager; _contentDirectory = contentDirectory; _connectionManager = connectionManager; + _config = config; } public object Get(GetDescriptionXml request) diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 1e9ff9199e..3f1d9fe67d 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -101,6 +101,7 @@ + diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 7bd0ca7482..ebd6c6b59f 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -342,6 +342,7 @@ namespace MediaBrowser.Common.Implementations /// protected virtual void FindParts() { + ConfigurationManager.AddParts(GetExports()); Plugins = GetExports(); } diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 8c4840ea71..60abc14f1a 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -1,10 +1,13 @@ -using System.IO; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Threading; namespace MediaBrowser.Common.Implementations.Configuration @@ -25,6 +28,11 @@ namespace MediaBrowser.Common.Implementations.Configuration /// public event EventHandler ConfigurationUpdated; + /// + /// Occurs when [named configuration updated]. + /// + public event EventHandler NamedConfigurationUpdated; + /// /// Gets the logger. /// @@ -74,6 +82,9 @@ namespace MediaBrowser.Common.Implementations.Configuration } } + private ConfigurationStore[] _configurationStores = {}; + private IConfigurationFactory[] _configurationFactories; + /// /// Initializes a new instance of the class. /// @@ -89,10 +100,14 @@ namespace MediaBrowser.Common.Implementations.Configuration UpdateCachePath(); } - /// - /// The _save lock - /// - private readonly object _configurationSaveLock = new object(); + public void AddParts(IEnumerable factories) + { + _configurationFactories = factories.ToArray(); + + _configurationStores = _configurationFactories + .SelectMany(i => i.GetConfigurations()) + .ToArray(); + } /// /// Saves the configuration. @@ -103,7 +118,7 @@ namespace MediaBrowser.Common.Implementations.Configuration Directory.CreateDirectory(Path.GetDirectoryName(path)); - lock (_configurationSaveLock) + lock (_configurationSyncLock) { XmlSerializer.SerializeToFile(CommonConfiguration, path); } @@ -144,8 +159,8 @@ namespace MediaBrowser.Common.Implementations.Configuration /// private void UpdateCachePath() { - ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? - null : + ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? + null : CommonConfiguration.CachePath; } @@ -168,5 +183,63 @@ namespace MediaBrowser.Common.Implementations.Configuration } } } + + private readonly ConcurrentDictionary _configurations = new ConcurrentDictionary(); + + private string GetConfigurationFile(string key) + { + return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLower() + ".xml"); + } + + public object GetConfiguration(string key) + { + return _configurations.GetOrAdd(key, k => + { + var file = GetConfigurationFile(key); + + var configurationType = _configurationStores + .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase)) + .ConfigurationType; + + lock (_configurationSyncLock) + { + return ConfigurationHelper.GetXmlConfiguration(configurationType, file, XmlSerializer); + } + }); + } + + public void SaveConfiguration(string key, object configuration) + { + var configurationType = GetConfigurationType(key); + + if (configuration.GetType() != configurationType) + { + throw new ArgumentException("Expected configuration type is " + configurationType.Name); + } + + _configurations.AddOrUpdate(key, configuration, (k, v) => configuration); + + var path = GetConfigurationFile(key); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + lock (_configurationSyncLock) + { + XmlSerializer.SerializeToFile(configuration, path); + } + + EventHelper.FireEventIfNotNull(NamedConfigurationUpdated, this, new ConfigurationUpdateEventArgs + { + Key = key, + NewConfiguration = configuration + + }, Logger); + } + + public Type GetConfigurationType(string key) + { + return _configurationStores + .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase)) + .ConfigurationType; + } } } diff --git a/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs b/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs new file mode 100644 index 0000000000..310e2aa638 --- /dev/null +++ b/MediaBrowser.Common/Configuration/ConfigurationUpdateEventArgs.cs @@ -0,0 +1,18 @@ +using System; + +namespace MediaBrowser.Common.Configuration +{ + public class ConfigurationUpdateEventArgs : EventArgs + { + /// + /// Gets or sets the key. + /// + /// The key. + public string Key { get; set; } + /// + /// Gets or sets the new configuration. + /// + /// The new configuration. + public object NewConfiguration { get; set; } + } +} diff --git a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs new file mode 100644 index 0000000000..d418d0a423 --- /dev/null +++ b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Common.Configuration +{ + public interface IConfigurationFactory + { + IEnumerable GetConfigurations(); + } + + public class ConfigurationStore + { + public string Key { get; set; } + + public Type ConfigurationType { get; set; } + } +} diff --git a/MediaBrowser.Common/Configuration/IConfigurationManager.cs b/MediaBrowser.Common/Configuration/IConfigurationManager.cs index 0d0759b666..25698d9729 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationManager.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Configuration; using System; +using System.Collections.Generic; namespace MediaBrowser.Common.Configuration { @@ -9,7 +10,12 @@ namespace MediaBrowser.Common.Configuration /// Occurs when [configuration updated]. /// event EventHandler ConfigurationUpdated; - + + /// + /// Occurs when [named configuration updated]. + /// + event EventHandler NamedConfigurationUpdated; + /// /// Gets or sets the application paths. /// @@ -32,5 +38,40 @@ namespace MediaBrowser.Common.Configuration /// /// The new configuration. void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration); + + /// + /// Gets the configuration. + /// + /// The key. + /// System.Object. + object GetConfiguration(string key); + + /// + /// Gets the type of the configuration. + /// + /// The key. + /// Type. + Type GetConfigurationType(string key); + + /// + /// Saves the configuration. + /// + /// The key. + /// The configuration. + void SaveConfiguration(string key, object configuration); + + /// + /// Adds the parts. + /// + /// The factories. + void AddParts(IEnumerable factories); + } + + public static class ConfigurationManagerExtensions + { + public static T GetConfiguration(this IConfigurationManager manager, string key) + { + return (T)manager.GetConfiguration(key); + } } } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 2e7db5c351..9d59843171 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -55,7 +55,9 @@ Properties\SharedVersion.cs + + diff --git a/MediaBrowser.Common/Net/MimeTypes.cs b/MediaBrowser.Common/Net/MimeTypes.cs index d85a2fd1e0..0cc4fc6b4d 100644 --- a/MediaBrowser.Common/Net/MimeTypes.cs +++ b/MediaBrowser.Common/Net/MimeTypes.cs @@ -228,6 +228,11 @@ namespace MediaBrowser.Common.Net return "text/vtt"; } + if (ext.Equals(".bif", StringComparison.OrdinalIgnoreCase)) + { + return "application/octet-stream"; + } + throw new ArgumentException("Argument not supported: " + path); } } diff --git a/MediaBrowser.Controller/Chapters/IChapterManager.cs b/MediaBrowser.Controller/Chapters/IChapterManager.cs index b8f29d1ceb..676ef9c561 100644 --- a/MediaBrowser.Controller/Chapters/IChapterManager.cs +++ b/MediaBrowser.Controller/Chapters/IChapterManager.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Chapters; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Chapters @@ -70,5 +71,11 @@ namespace MediaBrowser.Controller.Chapters /// /// IEnumerable{ChapterProviderInfo}. IEnumerable GetProviders(); + + /// + /// Gets the configuration. + /// + /// ChapterOptions. + ChapterOptions GetConfiguration(); } } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 9468fd9875..38c2c83c47 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -43,6 +43,27 @@ namespace MediaBrowser.Controller.MediaEncoding /// Task{Stream}. Task ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); + /// + /// Extracts the video images on interval. + /// + /// The input files. + /// The protocol. + /// The threed format. + /// The interval. + /// The target directory. + /// The filename prefix. + /// The maximum width. + /// The cancellation token. + /// Task. + Task ExtractVideoImagesOnInterval(string[] inputFiles, + MediaProtocol protocol, + Video3DFormat? threedFormat, + TimeSpan interval, + string targetDirectory, + string filenamePrefix, + int? maxWidth, + CancellationToken cancellationToken); + /// /// Gets the media info. /// diff --git a/MediaBrowser.Dlna/ConfigurationExtension.cs b/MediaBrowser.Dlna/ConfigurationExtension.cs new file mode 100644 index 0000000000..821e21ccfb --- /dev/null +++ b/MediaBrowser.Dlna/ConfigurationExtension.cs @@ -0,0 +1,29 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Configuration; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna +{ + public static class ConfigurationExtension + { + public static DlnaOptions GetDlnaConfiguration(this IConfigurationManager manager) + { + return manager.GetConfiguration("dlna"); + } + } + + public class DlnaConfigurationFactory : IConfigurationFactory + { + public IEnumerable GetConfigurations() + { + return new List + { + new ConfigurationStore + { + Key = "dlna", + ConfigurationType = typeof (DlnaOptions) + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs index bb65f422c5..f594b4471d 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs @@ -89,9 +89,11 @@ namespace MediaBrowser.Dlna.ContentDirectory } } - if (!string.IsNullOrEmpty(_config.Configuration.DlnaOptions.DefaultUserId)) + var userId = _config.GetDlnaConfiguration().DefaultUserId; + + if (!string.IsNullOrEmpty(userId)) { - var user = _userManager.GetUserById(new Guid(_config.Configuration.DlnaOptions.DefaultUserId)); + var user = _userManager.GetUserById(new Guid(userId)); if (user != null) { diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 0485255881..5f2c1c49ae 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -58,34 +59,39 @@ namespace MediaBrowser.Dlna.Main StartSsdpHandler(); ReloadComponents(); - _config.ConfigurationUpdated += ConfigurationUpdated; + _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; } - void ConfigurationUpdated(object sender, EventArgs e) + void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) { - ReloadComponents(); + if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase)) + { + ReloadComponents(); + } } private void ReloadComponents() { var isServerStarted = _dlnaServerStarted; - if (_config.Configuration.DlnaOptions.EnableServer && !isServerStarted) + var options = _config.GetDlnaConfiguration(); + + if (options.EnableServer && !isServerStarted) { StartDlnaServer(); } - else if (!_config.Configuration.DlnaOptions.EnableServer && isServerStarted) + else if (!options.EnableServer && isServerStarted) { DisposeDlnaServer(); } var isPlayToStarted = _manager != null; - if (_config.Configuration.DlnaOptions.EnablePlayTo && !isPlayToStarted) + if (options.EnablePlayTo && !isPlayToStarted) { StartPlayToManager(); } - else if (!_config.Configuration.DlnaOptions.EnablePlayTo && isPlayToStarted) + else if (!options.EnablePlayTo && isPlayToStarted) { DisposePlayToManager(); } diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 10da21e52c..1d51fc60ff 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -51,6 +51,7 @@ Properties\SharedVersion.cs + diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 095c6a893c..1f8c33ee7d 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -181,7 +181,7 @@ namespace MediaBrowser.Dlna.PlayTo return; } - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)); var headerText = string.Join(",", headerTexts.ToArray()); @@ -220,7 +220,7 @@ namespace MediaBrowser.Dlna.PlayTo { _ssdpHandler.SendRendererSearchMessage(new IPEndPoint(localIp, 1900)); - var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds * 1000; + var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000; await Task.Delay(delay, _tokenSource.Token).ConfigureAwait(false); } @@ -250,7 +250,7 @@ namespace MediaBrowser.Dlna.PlayTo { socket.SendTo(request, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900)); - var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds * 1000; + var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000; await Task.Delay(delay).ConfigureAwait(false); } diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs index 22d4797a3e..ccc7d46e6e 100644 --- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs +++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; @@ -76,7 +76,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; @@ -103,7 +103,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url, UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging, + LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging, LogErrorResponseBody = true }; diff --git a/MediaBrowser.Dlna/Service/BaseControlHandler.cs b/MediaBrowser.Dlna/Service/BaseControlHandler.cs index 9f7e87088a..c2af1f5a12 100644 --- a/MediaBrowser.Dlna/Service/BaseControlHandler.cs +++ b/MediaBrowser.Dlna/Service/BaseControlHandler.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Dlna.Service { try { - if (Config.Configuration.DlnaOptions.EnableDebugLogging) + if (Config.GetDlnaConfiguration().EnableDebugLogging) { LogRequest(request); } diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 0fc7c579b5..0455dd674d 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -1,4 +1,4 @@ -using System.Text; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Controller.Configuration; using MediaBrowser.Dlna.Server; @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading; namespace MediaBrowser.Dlna.Ssdp @@ -42,12 +43,15 @@ namespace MediaBrowser.Dlna.Ssdp _config = config; _serverSignature = serverSignature; - _config.ConfigurationUpdated += _config_ConfigurationUpdated; + _config.NamedConfigurationUpdated += _config_ConfigurationUpdated; } - void _config_ConfigurationUpdated(object sender, EventArgs e) + void _config_ConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) { - ReloadAliveNotifier(); + if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase)) + { + ReloadAliveNotifier(); + } } public event EventHandler MessageReceived; @@ -142,7 +146,7 @@ namespace MediaBrowser.Dlna.Ssdp private void RespondToSearch(IPEndPoint endpoint, string deviceType) { - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("RespondToSearch"); } @@ -166,7 +170,7 @@ namespace MediaBrowser.Dlna.Ssdp SendDatagram(header, values, endpoint, null); - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("{1} - Responded to a {0} request to {2}", d.Type, endpoint, d.Address.ToString()); } @@ -255,14 +259,14 @@ namespace MediaBrowser.Dlna.Ssdp var received = (byte[])result.AsyncState; - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug(Encoding.ASCII.GetString(received)); } var args = SsdpHelper.ParseSsdpResponse(received, (IPEndPoint)endpoint); - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)); var headerText = string.Join(",", headerTexts.ToArray()); @@ -285,7 +289,7 @@ namespace MediaBrowser.Dlna.Ssdp public void Dispose() { - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + _config.NamedConfigurationUpdated -= _config_ConfigurationUpdated; _isDisposed = true; while (_messageQueue.Count != 0) @@ -337,7 +341,7 @@ namespace MediaBrowser.Dlna.Ssdp private void NotifyAll() { - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("Sending alive notifications"); } @@ -362,7 +366,7 @@ namespace MediaBrowser.Dlna.Ssdp values["NT"] = dev.Type; values["USN"] = dev.USN; - if (_config.Configuration.DlnaOptions.EnableDebugLogging) + if (_config.GetDlnaConfiguration().EnableDebugLogging) { _logger.Debug("{0} said {1}", dev.USN, type); } @@ -406,13 +410,13 @@ namespace MediaBrowser.Dlna.Ssdp private int _aliveNotifierIntervalMs; private void ReloadAliveNotifier() { - if (!_config.Configuration.DlnaOptions.BlastAliveMessages) + if (!_config.GetDlnaConfiguration().BlastAliveMessages) { DisposeNotificationTimer(); return; } - var intervalMs = _config.Configuration.DlnaOptions.BlastAliveMessageIntervalSeconds * 1000; + var intervalMs = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 1000; if (_notificationTimer == null || _aliveNotifierIntervalMs != intervalMs) { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 1087c905c8..ce761ff9c1 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.MediaEncoding.Encoder RedirectStandardError = true, FileName = FFProbePath, Arguments = string.Format(args, - probeSizeArgument, inputPath).Trim(), + probeSizeArgument, inputPath).Trim(), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -186,8 +186,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { process.BeginErrorReadLine(); - result = - _jsonSerializer.DeserializeFromStream(process.StandardOutput.BaseStream); + result = _jsonSerializer.DeserializeFromStream(process.StandardOutput.BaseStream); } catch { @@ -292,7 +291,6 @@ namespace MediaBrowser.MediaEncoding.Encoder // apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar then scale to width 600. // This filter chain may have adverse effects on recorded tv thumbnails if ar changes during presentation ex. commercials @ diff ar var vf = "scale=600:trunc(600/dar/2)*2"; - //crop=min(iw\,ih*dar):min(ih\,iw/dar):(iw-min(iw\,iw*sar))/2:(ih - min (ih\,ih/sar))/2,scale=600:(600/dar),thumbnail" -f image2 if (threedFormat.HasValue) { @@ -344,7 +342,8 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, RedirectStandardOutput = true, - RedirectStandardError = true + RedirectStandardError = true, + RedirectStandardInput = true } }; @@ -370,7 +369,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { _logger.Info("Killing ffmpeg process"); - process.Kill(); + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); } @@ -437,5 +436,93 @@ namespace MediaBrowser.MediaEncoding.Encoder { return time.ToString(@"hh\:mm\:ss\.fff", UsCulture); } + + public async Task ExtractVideoImagesOnInterval(string[] inputFiles, + MediaProtocol protocol, + Video3DFormat? threedFormat, + TimeSpan interval, + string targetDirectory, + string filenamePrefix, + int? maxWidth, + CancellationToken cancellationToken) + { + var resourcePool = _videoImageResourcePool; + + var inputArgument = GetInputArgument(inputFiles, protocol); + + var vf = "fps=fps=1/" + interval.TotalSeconds.ToString(UsCulture); + + if (maxWidth.HasValue) + { + var maxWidthParam = maxWidth.Value.ToString(UsCulture); + + vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam); + } + + Directory.CreateDirectory(targetDirectory); + var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); + + var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); + + var probeSize = GetProbeSizeArgument(new[] { inputArgument }, protocol); + + if (!string.IsNullOrEmpty(probeSize)) + { + args = probeSize + " " + args; + } + + var process = new Process + { + StartInfo = new ProcessStartInfo + { + CreateNoWindow = true, + UseShellExecute = false, + FileName = FFMpegPath, + Arguments = args, + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false, + RedirectStandardInput = true + } + }; + + _logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments); + + await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + process.Start(); + + var ranToCompletion = process.WaitForExit(120000); + + if (!ranToCompletion) + { + try + { + _logger.Info("Killing ffmpeg process"); + + process.StandardInput.WriteLine("q"); + + process.WaitForExit(1000); + } + catch (Exception ex) + { + _logger.ErrorException("Error killing process", ex); + } + } + + resourcePool.Release(); + + var exitCode = ranToCompletion ? process.ExitCode : -1; + + process.Dispose(); + + if (exitCode == -1) + { + var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); + + _logger.Error(msg); + + throw new ApplicationException(msg); + } + } } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 154541316d..ab9cd546aa 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -342,12 +342,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles { RedirectStandardOutput = false, RedirectStandardError = true, + RedirectStandardInput = true, CreateNoWindow = true, UseShellExecute = false, FileName = _mediaEncoder.EncoderPath, - Arguments = - string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath), + Arguments = string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -385,8 +385,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { _logger.Info("Killing ffmpeg subtitle conversion process"); - process.Kill(); - + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); await logTask.ConfigureAwait(false); @@ -520,6 +519,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles RedirectStandardOutput = false, RedirectStandardError = true, + RedirectStandardInput = true, FileName = _mediaEncoder.EncoderPath, Arguments = processArgs, @@ -559,8 +559,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { _logger.Info("Killing ffmpeg subtitle extraction process"); - process.Kill(); - + process.StandardInput.WriteLine("q"); process.WaitForExit(1000); } catch (Exception ex) diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ee6f05cc1c..3c34652c32 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -104,6 +104,12 @@ Configuration\BaseApplicationConfiguration.cs + + Configuration\ChannelOptions.cs + + + Configuration\ChapterOptions.cs + Configuration\DlnaOptions.cs @@ -152,6 +158,9 @@ Configuration\SubtitleOptions.cs + + Configuration\SubtitlePlaybackMode.cs + Configuration\TvFileOrganizationOptions.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index a2fa1aa949..9e3df382ef 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -91,6 +91,12 @@ Configuration\BaseApplicationConfiguration.cs + + Configuration\ChannelOptions.cs + + + Configuration\ChapterOptions.cs + Configuration\DlnaOptions.cs @@ -139,6 +145,9 @@ Configuration\SubtitleOptions.cs + + Configuration\SubtitlePlaybackMode.cs + Configuration\TvFileOrganizationOptions.cs diff --git a/MediaBrowser.Model/Configuration/ChannelOptions.cs b/MediaBrowser.Model/Configuration/ChannelOptions.cs new file mode 100644 index 0000000000..f0fc4d47c4 --- /dev/null +++ b/MediaBrowser.Model/Configuration/ChannelOptions.cs @@ -0,0 +1,18 @@ +namespace MediaBrowser.Model.Configuration +{ + public class ChannelOptions + { + public int? PreferredStreamingWidth { get; set; } + + public string DownloadPath { get; set; } + public int? MaxDownloadAge { get; set; } + + public string[] DownloadingChannels { get; set; } + + public ChannelOptions() + { + DownloadingChannels = new string[] { }; + MaxDownloadAge = 30; + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ChapterOptions.cs b/MediaBrowser.Model/Configuration/ChapterOptions.cs new file mode 100644 index 0000000000..8a059a0a4a --- /dev/null +++ b/MediaBrowser.Model/Configuration/ChapterOptions.cs @@ -0,0 +1,27 @@ +namespace MediaBrowser.Model.Configuration +{ + public class ChapterOptions + { + public bool EnableMovieChapterImageExtraction { get; set; } + public bool EnableEpisodeChapterImageExtraction { get; set; } + public bool EnableOtherVideoChapterImageExtraction { get; set; } + + public bool DownloadMovieChapters { get; set; } + public bool DownloadEpisodeChapters { get; set; } + + public string[] FetcherOrder { get; set; } + public string[] DisabledFetchers { get; set; } + + public ChapterOptions() + { + EnableMovieChapterImageExtraction = true; + EnableEpisodeChapterImageExtraction = false; + EnableOtherVideoChapterImageExtraction = false; + + DownloadMovieChapters = true; + + DisabledFetchers = new string[] { }; + FetcherOrder = new string[] { }; + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0d728ec75e..3d5e0a9c92 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -211,6 +211,7 @@ namespace MediaBrowser.Model.Configuration public string UICulture { get; set; } + [Obsolete] public DlnaOptions DlnaOptions { get; set; } public double DownMixAudioBoost { get; set; } @@ -223,6 +224,8 @@ namespace MediaBrowser.Model.Configuration public string[] ManualLoginClients { get; set; } public ChannelOptions ChannelOptions { get; set; } + + [Obsolete] public ChapterOptions ChapterOptions { get; set; } /// @@ -268,73 +271,27 @@ namespace MediaBrowser.Model.Configuration SeasonZeroDisplayName = "Specials"; - LiveTvOptions = new LiveTvOptions(); - - TvFileOrganizationOptions = new TvFileOrganizationOptions(); - EnableRealtimeMonitor = true; - List options = new List + UICulture = "en-us"; + + MetadataOptions = new List { new MetadataOptions(1, 1280) {ItemType = "Book"}, new MetadataOptions(1, 1280) {ItemType = "MusicAlbum"}, new MetadataOptions(1, 1280) {ItemType = "MusicArtist"}, new MetadataOptions(0, 1280) {ItemType = "Season"} - }; - MetadataOptions = options.ToArray(); - - DlnaOptions = new DlnaOptions(); - - UICulture = "en-us"; + }.ToArray(); NotificationOptions = new NotificationOptions(); SubtitleOptions = new SubtitleOptions(); ChannelOptions = new ChannelOptions(); - ChapterOptions = new ChapterOptions(); - } - } - public class ChannelOptions - { - public int? PreferredStreamingWidth { get; set; } - - public string DownloadPath { get; set; } - public int? MaxDownloadAge { get; set; } - - public string[] DownloadingChannels { get; set; } - - public ChannelOptions() - { - DownloadingChannels = new string[] { }; - MaxDownloadAge = 30; - } - } - - public class ChapterOptions - { - public bool EnableMovieChapterImageExtraction { get; set; } - public bool EnableEpisodeChapterImageExtraction { get; set; } - public bool EnableOtherVideoChapterImageExtraction { get; set; } - - public bool DownloadMovieChapters { get; set; } - public bool DownloadEpisodeChapters { get; set; } - - public string[] FetcherOrder { get; set; } - public string[] DisabledFetchers { get; set; } - - public ChapterOptions() - { - EnableMovieChapterImageExtraction = true; - EnableEpisodeChapterImageExtraction = false; - EnableOtherVideoChapterImageExtraction = false; - - DownloadMovieChapters = true; - - DisabledFetchers = new string[] { }; - FetcherOrder = new string[] { }; + LiveTvOptions = new LiveTvOptions(); + TvFileOrganizationOptions = new TvFileOrganizationOptions(); } } } diff --git a/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs b/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs new file mode 100644 index 0000000000..e6a3c3091e --- /dev/null +++ b/MediaBrowser.Model/Configuration/SubtitlePlaybackMode.cs @@ -0,0 +1,10 @@ +namespace MediaBrowser.Model.Configuration +{ + public enum SubtitlePlaybackMode + { + Default = 0, + Always = 1, + OnlyForced = 2, + None = 3 + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 885172bed7..94a41bdda0 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -91,12 +91,4 @@ namespace MediaBrowser.Model.Configuration ExcludeFoldersFromGrouping = new string[] { }; } } - - public enum SubtitlePlaybackMode - { - Default = 0, - Always = 1, - OnlyForced = 2, - None = 3 - } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 9efa63283d..5d753f9c29 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -73,6 +73,9 @@ + + + diff --git a/MediaBrowser.Providers/Chapters/ChapterManager.cs b/MediaBrowser.Providers/Chapters/ChapterManager.cs index 5f8664bec3..6e2cd77eb3 100644 --- a/MediaBrowser.Providers/Chapters/ChapterManager.cs +++ b/MediaBrowser.Providers/Chapters/ChapterManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -8,6 +9,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Chapters; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; @@ -192,8 +194,10 @@ namespace MediaBrowser.Providers.Chapters if (!includeDisabledProviders) { + var options = GetConfiguration(); + providers = providers - .Where(i => !_config.Configuration.ChapterOptions.DisabledFetchers.Contains(i.Name)) + .Where(i => !options.DisabledFetchers.Contains(i.Name)) .ToArray(); } @@ -224,8 +228,10 @@ namespace MediaBrowser.Providers.Chapters private int GetConfiguredOrder(IChapterProvider provider) { + var options = GetConfiguration(); + // See if there's a user-defined order - var index = Array.IndexOf(_config.Configuration.ChapterOptions.FetcherOrder, provider.Name); + var index = Array.IndexOf(options.FetcherOrder, provider.Name); if (index != -1) { @@ -257,5 +263,25 @@ namespace MediaBrowser.Providers.Chapters { return _itemRepo.SaveChapters(new Guid(itemId), chapters, cancellationToken); } + + public ChapterOptions GetConfiguration() + { + return _config.GetConfiguration("chapters"); + } + } + + public class ChapterConfigurationStore : IConfigurationFactory + { + public IEnumerable GetConfigurations() + { + return new List + { + new ConfigurationStore + { + Key = "chapters", + ConfigurationType = typeof (ChapterOptions) + } + }; + } } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 65faae3274..92b4616e71 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -492,9 +492,11 @@ namespace MediaBrowser.Providers.MediaInfo private async Task> DownloadChapters(Video video, List currentChapters, CancellationToken cancellationToken) { - if ((_config.Configuration.ChapterOptions.DownloadEpisodeChapters && + var options = _chapterManager.GetConfiguration(); + + if ((options.DownloadEpisodeChapters && video is Episode) || - (_config.Configuration.ChapterOptions.DownloadMovieChapters && + (options.DownloadMovieChapters && video is Movie)) { var results = await _chapterManager.Search(video, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 056a526f6c..d35282e55c 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -1,12 +1,15 @@ -using MediaBrowser.Common.IO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Globalization; @@ -14,7 +17,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Server.Implementations.MediaEncoder { @@ -61,23 +63,25 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder return false; } + var options = _chapterManager.GetConfiguration(); + if (video is Movie) { - if (!_config.Configuration.ChapterOptions.EnableMovieChapterImageExtraction) + if (!options.EnableMovieChapterImageExtraction) { return false; } } else if (video is Episode) { - if (!_config.Configuration.ChapterOptions.EnableEpisodeChapterImageExtraction) + if (!options.EnableEpisodeChapterImageExtraction) { return false; } } else { - if (!_config.Configuration.ChapterOptions.EnableOtherVideoChapterImageExtraction) + if (!options.EnableOtherVideoChapterImageExtraction) { return false; } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index d03c5fe3dc..8007e05062 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -41,6 +41,7 @@ using MediaBrowser.Dlna.Main; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.MediaEncoding.Encoder; using MediaBrowser.MediaEncoding.Subtitles; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; @@ -273,11 +274,35 @@ namespace MediaBrowser.ServerApplication public override Task Init(IProgress progress) { - DeleteDeprecatedModules(); + PerformVersionMigration(); return base.Init(progress); } + private void PerformVersionMigration() + { + DeleteDeprecatedModules(); + + MigrateModularConfigurations(); + } + + private void MigrateModularConfigurations() + { + if (ServerConfigurationManager.Configuration.DlnaOptions != null) + { + ServerConfigurationManager.SaveConfiguration("dlna", ServerConfigurationManager.Configuration.DlnaOptions); + ServerConfigurationManager.Configuration.DlnaOptions = null; + ServerConfigurationManager.SaveConfiguration(); + } + + if (ServerConfigurationManager.Configuration.ChapterOptions != null) + { + ServerConfigurationManager.SaveConfiguration("chapters", ServerConfigurationManager.Configuration.ChapterOptions); + ServerConfigurationManager.Configuration.ChapterOptions = null; + ServerConfigurationManager.SaveConfiguration(); + } + } + private void DeleteDeprecatedModules() { try From be5d7641bc6905cf9121805e4d47f3d0dc0e55bb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Jun 2014 13:35:18 -0400 Subject: [PATCH 008/131] added roku BIF generation endpoint --- MediaBrowser.Api/Playback/BifService.cs | 181 ++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 MediaBrowser.Api/Playback/BifService.cs diff --git a/MediaBrowser.Api/Playback/BifService.cs b/MediaBrowser.Api/Playback/BifService.cs new file mode 100644 index 0000000000..7a3a7d32dc --- /dev/null +++ b/MediaBrowser.Api/Playback/BifService.cs @@ -0,0 +1,181 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.MediaEncoding; +using ServiceStack; +using System; +using System.Collections.Concurrent; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Api.Playback +{ + [Route("/Videos/{Id}/index.bif", "GET")] + public class GetBifFile + { + [ApiMember(Name = "MediaSourceId", Description = "The media version id, if playing an alternate version", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string MediaSourceId { get; set; } + + [ApiMember(Name = "MaxWidth", Description = "Optional. The maximum horizontal resolution of the encoded video.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? MaxWidth { get; set; } + + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + public class BifService : BaseApiService + { + private readonly IServerApplicationPaths _appPaths; + private readonly ILibraryManager _libraryManager; + private readonly IMediaEncoder _mediaEncoder; + private readonly IFileSystem _fileSystem; + + public BifService(IServerApplicationPaths appPaths, ILibraryManager libraryManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem) + { + _appPaths = appPaths; + _libraryManager = libraryManager; + _mediaEncoder = mediaEncoder; + _fileSystem = fileSystem; + } + + public object Get(GetBifFile request) + { + return ToStaticFileResult(GetBifFile(request).Result); + } + + private async Task GetBifFile(GetBifFile request) + { + var widthVal = request.MaxWidth.HasValue ? request.MaxWidth.Value.ToString(CultureInfo.InvariantCulture) : string.Empty; + + var item = _libraryManager.GetItemById(request.Id); + var mediaSources = ((IHasMediaSources)item).GetMediaSources(false).ToList(); + var mediaSource = mediaSources.FirstOrDefault(i => string.Equals(i.Id, request.MediaSourceId)) ?? mediaSources.First(); + + var path = Path.Combine(_appPaths.ImageCachePath, "bif", request.Id, request.MediaSourceId, widthVal, "index.bif"); + + if (File.Exists(path)) + { + return path; + } + + var protocol = mediaSource.Protocol; + + var inputPath = MediaEncoderHelpers.GetInputArgument(mediaSource.Path, protocol, null, mediaSource.PlayableStreamFileNames); + + var semaphore = GetLock(path); + + await semaphore.WaitAsync().ConfigureAwait(false); + + try + { + await _mediaEncoder.ExtractVideoImagesOnInterval(inputPath, protocol, mediaSource.Video3DFormat, + TimeSpan.FromSeconds(10), Path.GetDirectoryName(path), "img_", request.MaxWidth, CancellationToken.None) + .ConfigureAwait(false); + + var images = new DirectoryInfo(Path.GetDirectoryName(path)) + .EnumerateFiles() + .Where(img => string.Equals(img.Extension, ".jpg", StringComparison.Ordinal)) + .OrderBy(i => i.FullName) + .ToList(); + + using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) + { + var magicNumber = new byte[] { 0x89, 0x42, 0x49, 0x46, 0x0d, 0x0a, 0x1a, 0x0a }; + await fs.WriteAsync(magicNumber, 0, magicNumber.Length); + + // version + var bytes = GetBytes(0); + await fs.WriteAsync(bytes, 0, bytes.Length); + + // image count + bytes = GetBytes(images.Count); + await fs.WriteAsync(bytes, 0, bytes.Length); + + // interval in ms + bytes = GetBytes(10000); + await fs.WriteAsync(bytes, 0, bytes.Length); + + // reserved + for (var i = 20; i <= 63; i++) + { + bytes = new byte[] { 0x00 }; + await fs.WriteAsync(bytes, 0, bytes.Length); + } + + // write the bif index + var index = 0; + long imageOffset = 64 + (8 * images.Count) + 8; + + foreach (var img in images) + { + bytes = GetBytes(index); + await fs.WriteAsync(bytes, 0, bytes.Length); + + bytes = GetBytes(imageOffset); + await fs.WriteAsync(bytes, 0, bytes.Length); + + imageOffset += img.Length; + + index++; + } + + bytes = new byte[] { 0xff, 0xff, 0xff, 0xff }; + await fs.WriteAsync(bytes, 0, bytes.Length); + + bytes = GetBytes(imageOffset); + await fs.WriteAsync(bytes, 0, bytes.Length); + + // write the images + foreach (var img in images) + { + using (var imgStream = _fileSystem.GetFileStream(img.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true)) + { + await imgStream.CopyToAsync(fs).ConfigureAwait(false); + } + } + } + + return path; + } + finally + { + semaphore.Release(); + } + } + + private byte[] GetBytes(int value) + { + byte[] bytes = BitConverter.GetBytes(value); + if (BitConverter.IsLittleEndian) + Array.Reverse(bytes); + return bytes; + } + + private byte[] GetBytes(long value) + { + var intVal = Convert.ToInt32(value); + return GetBytes(intVal); + + //byte[] bytes = BitConverter.GetBytes(value); + //if (BitConverter.IsLittleEndian) + // Array.Reverse(bytes); + //return bytes; + } + + private static readonly ConcurrentDictionary SemaphoreLocks = new ConcurrentDictionary(); + + /// + /// Gets the lock. + /// + /// The filename. + /// System.Object. + private static SemaphoreSlim GetLock(string filename) + { + return SemaphoreLocks.GetOrAdd(filename, key => new SemaphoreSlim(1, 1)); + } + } +} From b87f759460490792b7ceaf0513ab0d87a869e73b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Jun 2014 13:58:04 -0400 Subject: [PATCH 009/131] fixes #857 - Support album subfolders --- .../Entities/Audio/MusicAlbum.cs | 17 +++++++ .../Resolvers/Audio/MusicAlbumResolver.cs | 45 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index a4d9278e53..eef2c84321 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -71,6 +71,23 @@ namespace MediaBrowser.Controller.Entities.Audio /// The tags. public List Tags { get; set; } + /// + /// Gets the tracks. + /// + /// The tracks. + public IEnumerable