diff --git a/frontend/components/System/DlnaEntryEditor.vue b/frontend/components/System/DlnaEntryEditor.vue
new file mode 100644
index 00000000000..d44c878a4bd
--- /dev/null
+++ b/frontend/components/System/DlnaEntryEditor.vue
@@ -0,0 +1,154 @@
+
+
+
+ {{ $t('settings.dlna.entryEditor') }}
+
+ mdi-close
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.save') }}
+
+
+
+
+
+
+
+
diff --git a/frontend/components/System/DlnaProfileEditor.vue b/frontend/components/System/DlnaProfileEditor.vue
new file mode 100644
index 00000000000..fbcda0e27a5
--- /dev/null
+++ b/frontend/components/System/DlnaProfileEditor.vue
@@ -0,0 +1,565 @@
+
+
+
+ {{ selectedProfile.Name }}
+
+ mdi-close
+
+
+
+
+
+ {{ $t('settings.dlna.profile.' + i + '.title') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.info.general') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.info.mediaTypes.text') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.info.display.title') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.info.image.title') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.identification.device.title') }}
+
+
+
+ {{ $t('settings.dlna.profile.identification.device.info') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.identification.server.title') }}
+
+
+
+ {{ $t('settings.dlna.profile.identification.server.info') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.' + section + '.text') }}
+
+
+
+ {{ $t('settings.dlna.newEntry') }}
+
+
+
+
+
+
+
+ {{ JSON.stringify(item.Conditions) }}
+
+
+
+ mdi-pencil
+
+
+ mdi-delete
+
+
+
+
+
+
+
+ {{
+ isCustomProfile
+ ? $t('settings.dlna.profile.save')
+ : $t('settings.dlna.profile.saveNew')
+ }}
+
+
+ {{ $t('settings.devices.delete') }}
+
+
+
+
+
+
+
+
diff --git a/frontend/locales/en-US.json b/frontend/locales/en-US.json
index 6f397f8e98b..e4d3c729235 100644
--- a/frontend/locales/en-US.json
+++ b/frontend/locales/en-US.json
@@ -323,6 +323,223 @@
"revokeFailure": "Error revoking API key",
"revokeSuccess": "Successfully revoked API key"
},
+ "dlna": {
+ "dlna": "DLNA",
+ "EnablePlayTo": {
+ "text": "Enable DLNA PlayTo",
+ "description": "Detect devices within your network and offer the ability to control them remotely."
+ },
+ "savedSuccess": "Settings saved",
+ "savedError": "An error occurred saving the configuration",
+ "savedProfileSuccess": "Profile saved",
+ "savedProfileError": "An error occurred saving the profile",
+ "deleteSuccess": "Deleted profile",
+ "deleteError": "An error occurred deleting the profile",
+ "EnableDebugLog": {
+ "text": "Enable DLNA debug logging",
+ "description": "Create large log files and should only be used as needed for troubleshooting purposes."
+ },
+ "ClientDiscoveryIntervalSeconds": {
+ "text": "Client discovery interval",
+ "description": "Determines the duration in seconds between SSDP searches."
+ },
+ "EnableServer": {
+ "text": "Enable DLNA server",
+ "description": "Allows UPnP devices on your network to browse and play content."
+ },
+ "BlastAliveMessages": {
+ "text": "Blast alive messages",
+ "description": "Enable this if the server is not detected reliably by other UPnP devices on your network."
+ },
+ "AliveMessageIntervalSeconds": {
+ "text": "Alive message interval",
+ "description": "Determines the duration in seconds between blast alive messages."
+ },
+ "DefaultUserId": {
+ "text": "Default user",
+ "description": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles.",
+ "selector": "Select default user"
+ },
+ "EnablePlayToTracing": {
+ "text": "Enable PlayTo Tracing",
+ "description": "Enables debug logging for DLNA PlayTo"
+ },
+ "SendOnlyMatchedHost": {
+ "text": "Send only matched host",
+ "description": "Only send data if the host matches"
+ },
+ "AutoCreatePlayToProfiles": {
+ "text": "Automatically create PlayTo device profiles",
+ "description": ""
+ },
+ "profile": {
+ "new": "New Profile",
+ "name": "Profile name",
+ "custom": {
+ "text": "Custom profiles",
+ "subtitle": "Create a custom profile to target a new device or override a system profile."
+ },
+ "system": {
+ "text": "System profiles",
+ "subtitle": "System profiles are read-only. Changes to a system profile will be saved to a new custom profile."
+ },
+ "saveNew": "Save as new custom profile",
+ "save": "Save profile",
+ "info": {
+ "title": "Info",
+ "general": "General settings",
+ "Name": {
+ "text": "Name",
+ "info": "Set the name of this profile."
+ },
+ "UserId": {
+ "text": "User library",
+ "info": "Select which user library to display to the device. Leave empty to inherit the default setting."
+ },
+ "MaxStreamingBitrate": {
+ "text": "Maximum streaming quality",
+ "info": "Specify a maximum bitrate when streaming."
+ },
+ "MusicStreamingTranscodingBitrate": {
+ "text": "Music transcoding bitrate",
+ "info": "Specify a maximum bitrate when streaming music."
+ },
+ "mediaTypes": {
+ "text": "Supported Media Types",
+ "Audio": "Audio",
+ "Video": "Video",
+ "Photo": "Photo"
+ },
+ "display": {
+ "title": "Display Settings",
+ "RequiresPlainFolders": {
+ "text": "Display all folders as plain storage folders",
+ "info": "All folders are represented in DIDL as \"object.container.storageFolder\" instead of a more specific type, such as \"object.container.person.musicArtist\"."
+ },
+ "RequiresPlainVideoItems": {
+ "text": "Display all videos as plain video items",
+ "info": "All videos are represented in DIDL as \"object.item.videoItem\" instead of a more specific type, such as \"object.item.videoItem.movie\"."
+ }
+ },
+ "image": {
+ "title": "Image Settings",
+ "EnableAlbumArtInDidl": {
+ "text": "Embed album art in Didl",
+ "info": "Some devices prefer this method for obtaining album art. Others may fail to play with this option enabled."
+ },
+ "EnableSingleAlbumArtLimit": {
+ "text": "Limit to single embedded image",
+ "info": "Some devices will not render properly if multiple images are embedded within Didl."
+ },
+ "AlbumArtPn": {
+ "text": "Album art PN",
+ "info": "PN used for album art, within the dlna:profileID attribute on upnp:albumArtURI. Some devices require a specific value, regardless of the size of the image."
+ },
+ "MaxAlbumArtWidth": {
+ "text": "Album art max width",
+ "info": "Maximum resolution of album art exposed via the upnp:albumArtURI property."
+ },
+ "MaxAlbumArtHeight": {
+ "text": "Album art max height",
+ "info": "Maximum resolution of album art exposed via the upnp:albumArtURI property."
+ },
+ "MaxIconWidth": {
+ "text": "Icon maximum width",
+ "info": "Maximum resolution of icons exposed via the upnp:icon property."
+ },
+ "MaxIconHeight": {
+ "text": "Icon maximum height",
+ "info": "Maximum resolution of icons exposed via the upnp:icon property."
+ }
+ }
+ },
+ "identification": {
+ "title": "Identification",
+ "FriendlyName": "Friendly name",
+ "Manufacturer": "Manufacturer",
+ "ManufacturerUrl": "Manufacturer URL",
+ "ModelName": "Model name",
+ "ModelNumber": "Model number",
+ "ModelDescription": "Model description",
+ "ModelUrl": "Model URL",
+ "SerialNumber": "Serial number",
+ "ProtocolInfo": "Protocol info",
+ "SonyAggregationFlags": "Sony aggregation flags",
+ "extra": {
+ "ProtocolInfo": "The value that will be used when responding to GetProtocolInfo requests from the device.",
+ "SonyAggregationFlags": "Determines the content of the aggreagationFlags element in the urn:schemas-sonycom:av namespace."
+ },
+ "device": {
+ "title": "Device identification",
+ "info": "Enter at least one identification criteria.",
+ "infoText": "A case-insensitive substring or regex expression."
+ },
+ "server": {
+ "title": "Server identification",
+ "info": "These values control how the server will present itself to clients."
+ }
+ },
+ "SubtitleProfiles": {
+ "title": "Subtitle",
+ "text": "Subtitle profiles describe the subtitle formats supported by the device."
+ },
+ "DirectPlayProfiles": {
+ "title": "Direct Play",
+ "text": "Add direct play profiles to indicate which formats the device can handle natively."
+ },
+ "TranscodingProfiles": {
+ "title": "Transcoding",
+ "text": "Add transcoding profiles to indicate which formats should be used when transcoding is required."
+ },
+ "ContainerProfiles": {
+ "title": "Containers",
+ "text": "Container profiles indicate the limitations of a device when playing specific formats. If a limitation applies then the media will be transcoded, even if the format is configured for direct play."
+ },
+ "CodecProfiles": {
+ "title": "Codecs",
+ "text": "Codec profiles indicate the limitations of a device when playing specific codecs. If a limitation applies then the media will be transcoded, even if the codec is configured for direct play."
+ },
+ "ResponseProfiles": {
+ "title": "Responses",
+ "text": "Response profiles provide a way to customize information sent to the device when playing certain kinds of media."
+ },
+ "XmlRootAttributes": {
+ "title": "XML",
+ "text": "These attributes are applied to the root element of every XML response."
+ }
+ },
+ "table": {
+ "Format": "Format",
+ "Method": "Method",
+ "DidlMode": "DidlMode",
+ "Language": "Language",
+ "Container": "Container",
+ "AudioCodec": "Audio Codec",
+ "VideoCodec": "Video Codec",
+ "MaxAudioChannels": "Max Audio Channels",
+ "Protocol": "Protocol",
+ "Type": "Type",
+ "EstimateContentLength": "Estimate Content Length",
+ "EnableMpegtsM2TsMode": "Enable MpegtsM To Ts Mode",
+ "TranscodeSeekInfo": "Transcode Seek Info",
+ "CopyTimestamps": "Copy Time Stamps",
+ "Context": "Context",
+ "EnableSubtitlesInManifest": "Enable Subtitles in Manifest",
+ "MinSegments": "Min Segments",
+ "SegmentLength": "Segment length",
+ "BreakOnNonKeyFrames": "Break on non-keyframes",
+ "Conditions": "Conditions",
+ "ApplyConditions": "Apply Conditions",
+ "Codec": "Codec",
+ "MimeType": "Mime Type",
+ "OrgPn": "OrgPn",
+ "Name": "Name",
+ "Value": "Value",
+ "action": "Action"
+ },
+ "newEntry": "New Entry",
+ "entryEditor": "Entry Editor"
+ },
"devices": {
"appName": "App name",
"appVersion": "App version",
diff --git a/frontend/pages/settings/dlna.vue b/frontend/pages/settings/dlna.vue
new file mode 100644
index 00000000000..1b809fa31d0
--- /dev/null
+++ b/frontend/pages/settings/dlna.vue
@@ -0,0 +1,288 @@
+
+
+
+
+ {{ $t('settings.help') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.custom.text') }}
+
+
+ {{ $t('settings.dlna.profile.new') }}
+
+
+
+
+
+
+ {{ $t('settings.dlna.profile.system.text') }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/pages/settings/index.vue b/frontend/pages/settings/index.vue
index 6c1ab67b66a..d8c18e49c25 100644
--- a/frontend/pages/settings/index.vue
+++ b/frontend/pages/settings/index.vue
@@ -191,7 +191,8 @@ export default Vue.extend({
{
icon: 'mdi-dlna',
name: this.$t('settingsSections.dlna.name'),
- description: this.$t('settingsSections.dlna.description')
+ description: this.$t('settingsSections.dlna.description'),
+ link: 'settings/dlna'
},
{
icon: 'mdi-television-classic',