Introduction
This post describes the semantics of writing a DLNA client profile for Plex Media Server version 0.9.7.24 and above. It assumes you understand the basics of editing an XML file.
What's a client profile?
DLNA is a broad and flexible standard, on that's interpreted by different devices in different ways: some by design, some due to device bugs or accident. This makes it impossible for a media server that supports DLNA to provide a one-size-fits-all implementation of the standard. Instead, the server must adapt to different clients by recognizing them and changing its behavior accordingly.
The client profile is the basic unit of information that Plex Media Server uses to customize its behavior for different client devices.
Do I have to write my own profile?
If your device isn't supported in a profile out of the box, then you might need to. Devices without profiles may work using generic settings, but they might not work very well. The primary purpose of a profile is to define the media formats that the device can play natively, as well as which media format Plex Media Server will use to transcode video, music and photos when media is not natively supported by the device. Some devices also have hard requirements for particular aspects of DLNA or HTTP behavior, which can be altered through client profile settings.
The initial release of Plex Media Server's DLNA support comes with profiles that support a few devices, including Xbox 360 and PlayStation 3. Over time new profiles will be added as we test new devices and as our friends in these forums post working profiles for us to use.
Where are profiles located?
Plex Media Server uses two different kinds of profile files:
System profiles
System profiles are provided and supported by Plex Inc. and are updated automatically when a new version of the server is installed. System profile files are stored in the Plex Media Server installation, under the Resources/Profiles directory. They should be assumed to be read-only from a user's perspective, because any changes made will be lost when the server installation is updated.
User profiles
User profiles are authored by individual users and are never changed by the server. User profile files are located in the Plex Media Server user directory, in a directory called Profiles. If you have never authored a user profile before, this directory will not exist.
User profiles may provide support for devices not supported by system profiles, as well as override devices supported by system profiles. A system profile can be overridden by creating a client profile file with the same file name as the system profile file that is intended to be overridden.
How do I know if my user profiles are being used?
If you look at the contents of Plex DLNA Server.log after PMS starts up, you will see entries along the lines of the following:
Jul 08, 2013 13:16:18:024 [47244] DEBUG - Overriding system profile Xbox 360 with user profile
Jul 08, 2013 13:16:18:037 [47244] DEBUG - Reading user profile Xbox 720
The first line indicates an override, the second that a new user profile has been found. If the server has a problem parsing your file, it will report an error and continue execution. So it's important to double-check the log after you've made edits to your user profile files.
Elements of a client profile
A client profile consists of the following elements:
- Name: how Plex Media Server refers to the profile. Must be identical to the profile's file name.
- Identification: how Plex Media Server recognizes a device, given an incoming HTTP request.
- Protocol Info: how Plex Media Server reports its own DLNA protocol support to devices.
- Device Description: how Plex Media Server identifies itself to other devices during DLNA network discovery.
- Settings: configuration options that change the DLNA server's behavior when talking to a particular device.
- Transcode Targets: the video, music and photo media formats to which PMS will transcode content devices can't play natively.
- DirectPlay Profiles: the set of video, music and photo formats the device can play natively.
- Codec Profiles: settings and limitations on the video, music and photo formats that the device can play natively.
- Container Profiles: settings and limitations on the container formats that the device can play natively.
- Transcode Target Profiles: settings for transcode targets.
- DLNA Media Profiles: customization of media format representations for very picky DLNA devices.
Creating a client profile is essentially the process of filling out a form with all this information. Once that's complete, Plex Media Server will know how to recognize your device and how to serve up content to it in a way it can play natively.
Where would I find the information needed to create a profile?
Usually from your device manufacturer. E.g., Microsoft publishes information for
Xbox 360, Western Digital for the
WD Live TV, Sony for the
PS3, and so forth.
Failing that, you may be able to find information using a search engine, via the device's GetProtocolInfo method, or via ad-hoc experimentation. Other DLNA server products have put together similar profiles, and sometimes we reuse information from those, since we're all in this together. Such is the nature of DLNA.
![:) :)]()
How do I know whether my device is supported or not?
If the device works, then there's nothing you really need to do. If the device isn't working right with Plex Media Server, it may be unsupported. To determine this, you can search for an entry in the system profile file, or you can scan your Plex DLNA Server.log file. A recognized device will look like this in the log when the server sees it making a request:
Mar 30, 2012 14:15:59:760 [13304] DEBUG - Mapped client to profile Xbox 360
An unrecognized device will look like this:
Mar 30, 2012 14:12:53:688 [11524] DEBUG - Mapped client to generic profile: Cache-Control: no-cache; Connection: Close; Pragma: no-cache; Content-Type: text/xml; charset="utf-8";
User-Agent: Microsoft-Windows/6.1 UPnP/1.0 Windows-Media-Player/12.0.7601.17514 DLNADOC/1.50 (MS-DeviceCaps/1024); SOAPAction: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse";
Content-Length: 886; Host: 192.168.11.10:32469
Note the mapping to a generic profile, as well as the presence of the headers from the HTTP request. The server provides these to make it easier for profile authors to see what the device is actually sending the server when making a request.
What's the generic profile?
The generic profile is the profile that defines Plex Media Server's behavior when a device is unrecognized. The generic profile can be overridden by a user profile file, just like any other profile. The default behavior of the generic profile is to offer up all content as Direct Play, with no transcoding or limitations. This will work reasonably well with more capable devices, but will fail with pickier ones.
How do I know the right names to use for containers and codecs?
Here's a list of containers and codecs we've observed in the wild. This is not intended to be comprehensive or exhaustive, but most media you'll ever use will be on this list:
container = { asf, avi, mov, mp4, mkv, mpegts, wtv, mpeg, m4v }
video = { h264, mpeg1video, mpeg2video, mpeg4, msmpeg4, mjpeg, wmv2, wmv3, vc1, cinepak, h263 }
audio = { aac, ac3, truehd, eac3, dca, mp3, mp2, pcm, wmapro, wmav2, wmavoice, wmalossless }
That said, the best way to find the container and codec names for your specific media is to look at your Plex Media Server's XML. In the Plex Media Server web client, click on the media's Info button, then on "View XML". Here's an example:
<Video addedAt="1343078395" grandparentRatingKey="66" grandparentTitle="Neverwhere" guid="com.plexapp.agents.thetvdb://70490/1/3?lang=en" index="3" key="/library/metadata/70" lastViewedAt="1435091413" originallyAvailableAt="1996-09-26" parentIndex="1" rating="8.5" ratingKey="70" title="Earl's Court to Islington" type="episode" updatedAt="1343078422" viewOffset="680798" year="1996" duration="1711012">
<Media id="66" aspectRatio="1.33" audioChannels="2" audioCodec="aac" bitrate="1353" container="mp4" duration="1711012" height="480" optimizedForStreaming="1" videoCodec="h264" videoFrameRate="NTSC" videoResolution="480" width="640">
<Part id="68" container="mp4" duration="1711012" has64bitOffsets="0" optimizedForStreaming="1" size="289319079" transcodeState="transcoded" key="/library/parts/68/file.mp4">
<Stream bitDepth="8" bitrate="1088" cabac="1" chromaSubsampling="4:2:0" codec="h264" codecID="avc1" colorSpace="yuv" duration="1711012" frameRate="29.970" frameRateMode="cfr" hasScalingMatrix="0" height="480" index="0" level="30" profile="high" refFrames="4" scanType="progressive" streamIdentifier="1" streamType="1" width="640" id="1"/>
<Stream audioChannelLayout="stereo" bitrate="256" bitrateMode="cbr" channels="2" codec="aac" codecID="40" duration="1711006" index="1" profile="lc" samplingRate="48000" streamIdentifier="2" streamType="2" id="2" selected="1"/>
</Part>
</Media>
</Video>
From the full XML metadata, you can use the names from the Part's container attribute and the codec names on the streams. Video streams are of type 1 and audio streams of type 2.
(NB - if you see very little metadata on the streams, you may need to reanalyze your media. To do this, simply refresh the section.)
Profile XML details
Name
The name of a profile allows Plex Media Server to uniquely identify it. Usually this is the commercial name of the device. It is expressed as the name attribute on the Client element:
<Client name="Xbox 360">
Identification
The Identification section defines how Plex Media Server recognizes a device in order to apply a profile to a request. Two different identification mechanisms are used by the server: incoming HTTP header recognition, and IP address matching based on a-priori network discovery.
An Identification section consists of one or more Header or DeviceDescription elements. Multiple such elements represent alternative means of identification, and not multiple requirements.
A Header element allows the profile to detect clients using headers in an incoming HTTP request. A Header element must have a name attribute, containing the name of the relevant HTTP header in a case-insensitive manner. It also must have either a substring attribute or a regex attribute, but not both. The value of a substring attribute is any matching case-insensitive substring (no wildcards) inside the header's value, while the value of regex is a case-insensitive regular expression that applies to the value of the HTTP header.
If any of the elements under a Header element matches, the device is considered to match. I.e. multiple elements under a Header element are ORed together.
For example, a device that occasionally uses two different User-Agent headers could be identified as follows:
<Identification>
<Header name="User-Agent" substring="Xbox"/>
<Header name="User-Agent" substring="Xenon"/>
</Identification>
When authoring a new profile, it helps to know which headers are being sent by the device. As noted above, these can be found in the Plex DLNA Server.log file when the device is being mapped to the generic profile. A more complete way to monitor device activity is to use Wireshark or Microsoft Network Monitor.
One thing that's VERY IMPORTANT: when creating profiles for other people to use, you have to think about the device ecosystem in which your profile will be used. Most people using Plex Media Server won't have your device, but they may have a different device that sends vaguely similar headers. So when authoring this section, PLEASE make sure you're being as restrictive as possible when writing substrings or regular expressions for Header elements. Overly broad header elements can cause erroneous profiles matching, which people will find immensely confusing.
A DeviceDescription element allows the profile to detect clients using the properties they advertise in their device XML when responding to a search request. This is useful when a device does not provide a distinctive HTTP header on each request. For performance reasons, the HTTP header mechanism is preferable, when possible.
A DeviceDescription element may have a type element, indicating the type of device that exposes the relevant property. This is useful for DLNA clients that expose themselves as multiple devices in this XML, e.g. the Samsung LE32C650. In general, when using a DeviceDescription element, it is recommended to use this attribute with a specific device type. Otherwise, Plex Media Server will attempt to match these properties against any device type it sees, which may lead to unexpected results if the matching data is not unique.
The following sub-elements are supported inside a DeviceDescription element:
- FriendlyName
- ModelName
- ModelNumber
- ModelUrl
- ModelDescription
- Manufacturer
- ManufacturerUrl
- SerialNumber
Each element must have either a substring attribute or a regex attribute. These attributes follow the same rules as with the Header element. Multiple elements under a DeviceDescription must all match in order for the DeviceDescription to be considered a match. I.e. all sub-elements under a DeviceDescription element are ANDed together.
The following is a (fictional) example of a DeviceDescription element:
<Identification>
<DeviceDescription type="urn:samsung.com:device:RemoteControlReceiver:1">
<FriendlyName substring="LE32C650" />
<ModelName substring="UE" />
<ModelNumber substring="700" />
<ModelUrl substring="samsung.com" />
<ModelDescription substring="An nyoung ha seh yo" />
<Manufacturer substring="Samsung" />
<ManufacturerUrl substring="samsung.com" />
<SerialNumber substring="1234" />
</DeviceDescription>
</Identification>
A device's friendly name, device type and other properties can be discovered using the Device Spy tool from
http://opentools.homeip.net/dev-tools-for-upnp. The following is an real example of device XML provided by a DLNA client, in this case a version of Windows Media Player:
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
...
<device>
<friendlyName>SERVER: mfeingol:</friendlyName>
<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
<manufacturer>Microsoft Corporation</manufacturer>
<manufacturerURL>http://www.microsoft.com</manufacturerURL>
<modelName>Windows Media Player Sharing</modelName>
<modelNumber>12.0</modelNumber>
<modelURL>http://go.microsoft.com/fwlink/?LinkId=105926</modelURL>
<serialNumber>{06C328CF-8EC5-4F1E-BAA4-D67CDAD172FB}</serialNumber>
</device>
</root>
Protocol Info
When a DLNA client discovers a DLNA server on the network, it may inquire as to its capabilities. One important capability is the set of media formats supported by the server. Some DLNA clients (e.g. televisions) often have fairly strong opinions about which formats it wants to see. This section allows the response Plex Media Server provides to that question to be customized.
A ProtocolInfo element must have a single Source element. The inner value of that source element is the value that Plex Media Server will use when responding to GetProtocolInfo requests from the device.
For example:
<ProtocolInfo>
<Source>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000</Source>
</ProtocolInfo>
If no ProtocolInfo is specified, Plex Media Server will reply with a default value. That value is customizable by the user, and may change in different versions of Plex Media Server. The default is currently the following:
http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:video/vnd.dlna.mpeg-tts:*,http-get:*:video/avi:*,http-get:*:video/x-matroska:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/wtv:*,http-get:*:audio/mpeg:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/x-ms-wma*,http-get:*:audio/wav:*,http-get:*:audio/L16:*,http-get:*image/jpeg:*,http-get:*image/png:*,http-get:*image/gif:*,http-get:*image/tiff:*
Settings
The Settings section contains configuration options that change the DLNA server's behavior when a device is recognized. The following settings are currently supported:
- OnlyPlainVideoItems - true/false, default is false - all videos are represented in DIDL as "object.item.videoItem" instead of a more specific type, such as "object.item.videoItem.movie".
- OnlyStorageFolders - true/false, default is false - all folders are represented in DIDL as "object.container.storageFolder" instead of a more specific type, such as "object.container.person.musicArtist".
- IgnoreTranscodeByteRangeRequests - true/false, default is false - byte range requests issued for transcode video streams are handled as if no range request had been made
- EmitAlbumArtResources - true/false, default is false - emit res items inside video DIDL representing album art for the video in question. Some devices prefer this mechanism to others for obtaining album art. Other devices can't handle this and are unable to play video when this option is enabled.
- TimelineBufferOffset - integer representing seconds, default is zero - how far ahead the device generally buffers when playing video. Used to improve accuracy when recording playback progress on the server for a given video when the video is played by a DLNA device.
- IconResolution - string - resolution of icons exposed via upnp:icon, derived from Plex Media Server thumbnails. Default is 256x256.
- AlbumArtResolution - string - resolution of album art exposed via upnp:albumArtURI, derived from Plex Media Server album art or thumbnails. Default is 512x512.
- AlbumArtPN - string - the DLNA.ORG_PN value used for album art, aka the dlna:profileID attribute on upnp:albumArtURI. Default is JPEG_SM. (Some devices are very picky about wanting a specific value, regardless of the actual size of the image.)
To determine which settings to use when authoring a profile, the general rule of thumb is to fix on failure via trial and error. E.g. the OnlyStorageFolders setting is worth trying if the device can't seem to browse into folders, or thinks folders are media, or folders can be browsed, but no videos show up. If folders work after changing the setting, then it's worth keeping in the profile. Similarly, the OnlyPlainVideoItems setting is worth trying if folders containing video appear empty.
For example:
<Settings>
<Setting name="OnlyPlainVideoItems" value="true" />
<Setting name="OnlyStorageFolders" value="true" />
<Setting name="IgnoreTranscodeByteRangeRequests" value="true" />
<Setting name="TimelineBufferOffset" value="40" />
<Setting name="IconResolution" value="512x384" />
<Setting name="AlbumArtResolution" value="512x384" />
<Setting name="AlbumArtPN" value="JPEG_TN" />
</Settings>
Device Description
When a DLNA client discovers a DLNA server on the network, the client may use information provided by the server to deduce the server's characteristics. Which server is this? Who made it? Etc.
Some clients exhibit specific behaviors when these values are set to specific parameters. This DeviceDescription element allows Plex Media Server's device characteristics to be customized per client, influencing a set of fields in the device's XML description. These fields can also be left empty, specifying that no content is to be emitted, or elided entirely, in which case default values will be used. The default values used by Plex Media Server may vary from release to release, and can be observed in a program like Device Spy.
The following is an example of a default Plex Media Server device description:
<device>
<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
<friendlyName>Plex Media Server: Orpheus</friendlyName>
<manufacturer>Plex, Inc.</manufacturer>
<manufacturerURL>http://www.plexapp.com/</manufacturerURL>
<modelDescription>Plex Media Server</modelDescription>
<modelName>Plex Media Server</modelName><modelURL>http://www.plexapp.com/</modelURL>
<modelNumber>0.9.7.28</modelNumber>
<serialNumber/>
<UDN>uuid:6911532c-85f2-2072-9776-656536c01ca4</UDN>
<dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMS-1.50</dlna:X_DLNADOC>
...
</device>
The following fields can be overridden:
- FriendlyName: controls the content of the friendlyName element in the urn:schemas-upnp-org:device-1-0 namespace.
- Manufacturer: controls the content of the manufacturer element in the urn:schemas-upnp-org:device-1-0 namespace.
- ManufacturerUrl: controls the content of the manufacturer element in the urn:schemas-upnp-org:device-1-0 namespace.
- ModelName: controls the content of the manufacturerURL element in the urn:schemas-upnp-org:device-1-0 namespace.
- ModelNumber: controls the content of the modelNumber element in the urn:schemas-upnp-org:device-1-0 namespace.
- ModelUrl: controls the content of the modelUrl element in the urn:schemas-upnp-org:device-1-0 namespace.
- ModelDescription: controls the content of the modelDescription element in the urn:schemas-upnp-org:device-1-0 namespace.
- X-DlnaDoc: controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.
- X-DlnaCap: controls the content of the X_DLNACAP element in the urn:schemas-dlna-org:device-1-0 namespace.
- Sony-AggregationFlags: controls the content of the aggregationFlags element in the urn:schemas-sonycom:av.
For example:
<DeviceDescription>
<FriendlyName>Hi, I'm a friendly device</FriendlyName>
<Manufacturer>Microsoft Corporation</Manufacturer>
<ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
<ModelName>Windows Media Player Sharing</ModelName>
<ModelNumber>12.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
<ModelDescription>Something or other</ModelDescription>
<X-DlnaDoc>DMS-1.50</X-DlnaDoc>
<X-DlnaCap />
<Sony-AggregationFlags>10</Sony-AggregationFlags>
</DeviceDescription>
Transcode Targets
Transcode Targets define the video, music and photo formats to which PMS will transcode media when the media's format is not listed inside a DirectPlay Profile. A TranscodeTarget element contains a set of VideoProfile elements, a single MusicProfile element and a single PhotoProfile element. All elements are optional, in that the absence of a transcode target profile for a given media type simply means that no media of that type will be transcoded.
A VideoProfile element has the following attributes:
- protocol: either http (a standard video stream), slss (a Silverlight Smooth Streaming manifest + stream) or hls (an HTTP Live Streaming manifest + stream). No protocol attribute means http.
- container: the video container used to encapsulate the video. This should be mpegts or asf for the http protocol, mp4 for the slss protocol and mpegts for the hls protocol.
- codec: the video codec used to encode the video. This should generally be h264, but it could be any codec compatible with the chosen container. Some protocols may impose certain restrictions on this value.
- audioCodec: the audio codecs that may used to encode this video. This attribute can be a list of audio codecs representing Direct Streaming options. If the source codec matches none of these, generally the first codec in the list will be used.
- context: the context in which the video profile will be used. For DLNA profiles, this value should be set to streaming or elided entirely.
A VideoProfile element may also have Settings sub-elements, with name and value attributes. The following settings are supported:
- VideoEncodeFlags - string - provides additional command line arguments to the transcoder. Use this at your own peril.
- SubtitleSize - integer - a value from 25 to 500 representing scaling of burned subtitle font sizes, where 100 represents no scaling and is the default.
- AudioSyncFlags - integer - a value from 0 to 3, where 0 means no special audio sync handling, 1 means to sync audio on start, 2 means to sync audio on resume, and 3 means both.
- MpegtsM2tsMode - true/false, default is false - use M2TS mode when emitting mpegts streams, aka 192-byte packets with a valid timestamp.
A MusicProfile element has the following attributes:
- container: the audio container used to encapsulate the music. This should generally be mp3.
- codec: the audio codec used to encode the music. This should generally be mp3.
A PhotoProfile element has the following attributes:
- container: the image container used to encode the photo. This should generally be jpeg.
For example:
<TranscodeTargets>
<VideoProfile protocol="http" container="mpegts" codec="h264" audioCodec="aac,ac3,eac3" context="streaming">
<!-- Inspired by Handbrake's Universal profile -->
<Setting name="VideoEncodeFlags" value="-x264opts cabac=0" />
<Setting name="SubtitleSize" value="100" />
</VideoProfile>
<VideoProfile protocol="slss" container="mp4" codec="h264" audioCodec="aac" context="streaming">
<!-- Inspired by Handbrake's Universal profile -->
<Setting name="VideoEncodeFlags" value="-x264opts cabac=0:keyint=50:min_keyint=50:scenecut=0" />
<Setting name="SubtitleSize" value="100" />
<Setting name="AudioSyncFlags" value="3" />
</VideoProfile>
<VideoProfile protocol="hls" container="mpegts" codec="h264" audioCodec="aac" context="streaming">
<!-- Inspired by Handbrake's Universal profile -->
<Setting name="VideoEncodeFlags" value="-x264opts cabac=0" />
<Setting name="SubtitleSize" value="100" />
</VideoProfile>
<MusicProfile container="mp3" codec="mp3" />
<PhotoProfile container="jpeg" />
</TranscodeTargets>
The best combination for transcoded video is usually mpegts as container, h264 as video codec, and aac or ac3 as audio codecs. Older devices that cannot play h264 might prefer mpeg4 or mpeg2video as video codecs.
DirectPlay Profiles
DirectPlay Profiles define the set of video and photo formats that the device understands natively. If the device is highly capable, this may be a long list. A DirectPlayProfile element may contain multiple VideoProfile and PhotoProfile elements, each with its own set of attributes (as above). Each container, codec or audioCodec attribute may contain multiple entries, separated by commas. The cross-product of the combination of all attribute entries represent possible combinations of containers and codecs. For example, in the XML below, the asf container may contain various wmv codecs, but not h264.
<DirectPlayProfiles>
<VideoProfile container="asf" codec="wmv2,wmv3,vc1" audioCodec="wmav2,wmapro" />
<VideoProfile container="avi" codec="mpeg4" audioCodec="ac3,mp3" />
<VideoProfile container="mp4,mov,mpegts" codec="h264,mpeg4" audioCodec="ac3,aac" />
<PhotoProfile container="jpeg" />
</DirectPlayProfiles>
Codec Profiles
Codec Profiles provide a way to express the limitations of a device when playing specific video or music codecs. If the limitation applies to a given piece of media, then the media will be transcoded, even if the relevant codec is natively supported by the device.
A CodecProfiles element contains one or more VideoCodec, VideoAudioCodec or MusicCodec elements. Each element has a name attribute that identifies the relevant codec, as well as a set of limitations expressed under a Limitations element. The name attribute may also be "*", representing all codecs.
There are several types of limitation elements:
- Match: the value of the metadata attribute must match the value of the limitation.
- NotMatch: the value of the metadata attribute must not match the value of the limitation.
- UpperBound: the value of the metadata attribute must be less than or equal to the value of the limitation.
- LowerBound: the value of the metadata attribute must be greater than or equal to the value of the limitation.
Each limitation element must have a name attribute which identifies the name of the metadata to which the limitation applies, as well as a value, substring or regex attribute. The name of the limitation can be determined by viewing the metadata XML for a given video (see example above). The format of a name attribute is prefix.suffix. The suffix is the name of the relevant metadata attribute, while the prefix can be one of the following:
- video: applies to the selected video stream element of a media item.
- audio: applies to the selected audio stream of a media item.
- part: applies to the relevant part element of a media item.
- photo: applies to the media element of a photo media item.
A limitation may also have an isRequired attribute (set to true or false, and defaulting to true) indicating behavior if the metadata attribute is not present on the media. A required limitation whose name attribute that is absent in the media's metadata is considered to apply to the media, while the absence of a non-required attribute is not.
Some examples follow:
<CodecProfiles>
<VideoCodec name="mpeg4">
<Limitations>
<UpperBound name="part.size" value="4294967295" />
<UpperBound name="video.width" value="1280" />
<UpperBound name="video.height" value="720" />
<UpperBound name="video.videoFrameRate" value="30" />
<UpperBound name="video.bitrate" value="5120" />
</Limitations>
</VideoCodec>
<VideoCodec name="wmv2,wmv3,vc1">
<Limitations>
<UpperBound name="video.width" value="1920" />
<UpperBound name="video.height" value="1080" />
<UpperBound name="video.frameRate" value="30" />
<UpperBound name="video.bitrate" value="15360" />
</Limitations>
</VideoCodec>
<VideoAudioCodec name="ac3,wmav2,wmapro">
<Limitations>
<UpperBound name="audio.channels" value="6" />
</Limitations>
</VideoAudioCodec>
<VideoAudioCodec name="aac">
<Limitations>
<NotMatch name="audio.profile" substring="he-aac" />
</Limitations>
</VideoAudioCodec>
<MusicCodec name="mp3">
<Limitations>
<UpperBound name="audio.bitrate" value="320" />
<UpperBound name="audio.channels" value="2" />
</Limitations>
</MusicCodec>
</CodecProfiles>
Container Profiles
Container Profiles provide a way to express the limitations of a device when playing specific video containers. If the limitation applies to a given piece of media, then the media will be transcoded, even if the relevant container is natively supported by the device.
A ContainerProfiles element contains one or more VideoContainer, MusicContainer or PhotoContainer elements. Each element has a name attribute that identifies the relevant container, as well as a set of limitations expressed under a Limitations element. The Limitation elements are the same as the ones described in the section above.
For example, the following container profiles expresses two limitations: the device cannot handle mp4 containers with 64-bit offsets (aka co64 atoms), nor mkv containers whose video stream has stripped headers, nor very large jpegs:
<ContainerProfiles>
<VideoContainer name="mp4">
<Limitations>
<Match name="part.has64bitOffsets" value="0" />
</Limitations>
</VideoContainer>
<VideoContainer name="mkv">
<Limitations>
<Match name="video.headerStripping" value="0" isRequired="false" />
</Limitations>
</VideoContainer>
<PhotoContainer name="jpeg">
<Limitations>
<UpperBound name="photo.width" value="4096" />
<UpperBound name="photo.height" value="4096" />
</Limitations>
</PhotoContainer>
</ContainerProfiles>
Transcode Target Profiles
Transcode Target Profiles provide a way to express the limitations of a device when consuming transcoded video. If the limitation applies to a given piece of media, then the media will be transcoded instead of Direct Streamed, even if the relevant codec is natively supported for Direct Streaming by the device over the specified protocol.
A TranscodeTargetProfiles element contains one or more VideoTranscodeTarget elements. Each element has protocol and context attributes, which are used in the same manner as described in the Transcode Targets section. Each element also contains at least one VideoCodec or VideoAudioCodec elements. These elements use the same format as described in the Codec Profiles section.
For example:
<TranscodeTargetProfiles>
<!-- h264 with header stripping or compression doesn't Direct Stream correctly in hls streams-->
<VideoTranscodeTarget protocol="hls" context="streaming">
<VideoCodec name="*">
<Limitations>
<NotMatch name="video.headerStripping" value="1" isRequired="false" />
<Match name="video.headerCompression" value="" isRequired="false" />
<UpperBound name="video.bitDepth" value="8" isRequired="false" /> <!-- Nor does high-bitdepth video -->
</Limitations>
</VideoCodec>
</VideoTranscodeTarget>
<!-- h264 without cabac doesn't Direct Stream correctly in mpegts streams -->
<VideoTranscodeTarget protocol="http" context="streaming">
<VideoCodec name="h264">
<Limitations>
<NotMatch name="video.headerStripping" value="1" isRequired="false" />
<Match name="video.headerCompression" value="" isRequired="false" />
<UpperBound name="video.bitDepth" value="8" isRequired="false" />
<Match name="video.cabac" value="1" />
</Limitations>
</VideoCodec>
</VideoTranscodeTarget>
</TranscodeTargetProfiles>
DLNA Media Profiles
DLNA Media Profiles provide a way to customize the DLNA.ORG_PN values, mime types and file extensions reported by Plex Media Server for specific media types. This is often necessary when authoring profiles for the pickiest devices, such as various Sony products.
A DlnaMediaProfiles element contains one or more DlnaVideoProfile, DlnaMusicProfile or DlnaPhotoProfile elements. Each of these may have the following attributes:
- container, codec, audioCodec: similar to the attributes described in the Direct Play Profiles section
- pn: the overridden DLNA.ORG_PN value to be used for the specified media types. When multiple comma-separated values are provided, each value is used to generate a separate res element with the respective PN value. This is useful for devices with regional preferences, such as certain Sony televisions.
- mimeType: the overridden mime type to be used in Content-Type headers and DIDL for the specified media types
- extension: the file extension to be used in res elements for the specified media types
Each profile element may have a Limitations element, with the same syntax as the Codec Profiles section.
When DIDL is emitted for a media item, the client profile's DlnaMediaProfiles are evaluated in the order they appear in the profile. If the container and codecs match, and the limitations do not apply, then the overrides specified in the profile element's attributes are applied to the res element in DIDL. If no matching media profile exists, then the server's defaults are used.
For example:
<DlnaMediaProfiles>
<DlnaVideoProfile container="mpegts" codec="h264" audioCodec="ac3,aac,mp3" pn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T" mimeType="video/vnd.dlna.mpeg-tts">
<Limitations>
<Match name="video.packetLength" value="192" />
<Match name="video.timeStamp" value="1" />
</Limitations>
</DlnaVideoProfile>
<DlnaVideoProfile container="mpegts" codec="h264" audioCodec="ac3,aac,mp3" pn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO" mimeType="video/mpeg">
<Limitations>
<Match name="video.packetLength" value="188" />
</Limitations>
</DlnaVideoProfile>
<DlnaVideoProfile container="mpegts" codec="h264" audioCodec="ac3,aac" pn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU" mimeType="video/vnd.dlna.mpeg-tts" />
<DlnaVideoProfile container="mpegts" codec="mpeg2video" audioCodec="ac3" pn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO" mimeType="video/vnd.dlna.mpeg-tts" />
<DlnaVideoProfile container="mpeg" codec="mpeg1video,mpeg2video" pn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg" />
<DlnaVideoProfile container="mpeg" codec="mpeg1video,mpeg2video" pn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg" />
<DlnaVideoProfile container="mpeg" codec="mpeg1video,mpeg2video" pn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg" />
<DlnaMusicProfile container="wav" mimeType="audio/wav" />
</DlnaMediaProfiles>