Spatial audio is one of the features for which I bought Airpods Pro, and it truly creates a more immersive movie-watching experience. Even on the small screen of my iPhone! However, there is one big caveat… not every app supports it.

Because reasons unknown to me Apple doesn’t just convert all surround audio to spatial audio but requires an API to make this happen. So right now we’re still waiting on Netflix and Youtube (among others) to implement this feature. However I also host my own Movies and TV Shows with Plex, this is great but until now didn’t support Spatial Audio. Or so I thought…

Meet custom profiles in Plex! These profiles allow us to change which codecs are sent to a certain type of device. So al we have to do is create a profile XML file with the right information and voilà… Spatial Audio!

How To

First up, set the Plex iOS app to use the “Old Video Player”. You can find the setting here:

Settings > Advanced > Use Old Video Player

Afterwards, locate and move to the /Plex Media Server folder on your server, check for your location here. For my Docker install we move to the folder with:

cd /config/Library/Application Support/Plex Media Server/

In here create a folder called Profiles and in there a file named iOS.xml. We can do this with the following commands:

mkdir Profiles
nano Profiles/iOS.xml

Paste the following XML data into the nano text editor:
(Big thanks to Saiks on the Plex Forums for the profile)

<?xml version="1.0" encoding="utf-8"?>
<Client name="iOS">
  <!-- Author: Plex Inc. -->
  <!-- This profile is used by A5 and higher devices (starting with iPhone 4S and iPad 3) -->
  <Settings>
    <Setting name="DirectPlayStreamSelection" value="true" />
    <Setting name="StreamUnselectedIncompatibleAudioStreams" value="true" />
  </Settings>
  <TranscodeTargets>
    <VideoProfile container="mp4" codec="h264" audioCodec="eac3" subtitleCodec="mov_text" context="static" />
	<VideoProfile protocol="hls" container="mp4" codec="h264" audioCodec="eac3" subtitleCodec="eia_608_embedded" context="streaming" />
	<VideoProfile protocol="hls" container="mp4" codec="hevc" audioCodec="eac3" subtitleCodec="eia_608_embedded" context="streaming" />
    <MusicProfile container="mp4" codec="aac" />
    <PhotoProfile container="jpeg" />
    <SubtitleProfile protocol="hls" container="webvtt" subtitleCodec="webvtt"/>
  </TranscodeTargets>
  <DirectPlayProfiles>
    <VideoProfile container="mp4" codec="h264" audioCodec="eac3" subtitleCodec="mov_text,tx3g,ttxt,text" />
    <VideoProfile container="mp4" codec="hevc" audioCodec="eac3" subtitleCodec="mov_text,tx3g,ttxt,text" />
    <VideoProfile container="mov" codec="h264" audioCodec="eac3" subtitleCodec="mov_text,tx3g,ttxt,text" />
    <!-- Allow Direct Play of HLS content  -->
	<VideoProfile protocol="hls" container="mpegts" codec="h264" audioCodec="eac3" />
	<VideoProfile protocol="hls" container="mp4" codec="h264" audioCodec="eac3" />
	<VideoProfile protocol="hls" container="mp4" codec="hevc" audioCodec="eac3" />
    <MusicProfile container="mp3" codec="mp3" />
    <MusicProfile container="mp4" codec="aac" />
    <MusicProfile container="mp4" codec="alac" />
	<MusicProfile container="flac" codec="flac" />
    <PhotoProfile container="jpeg,gif,bmp,png" />
  </DirectPlayProfiles>
  <CodecProfiles>
    <VideoCodec name="h264">
      <Limitations>
        <UpperBound name="video.width" value="3840" isRequired="true" />
        <UpperBound name="video.height" value="2160" isRequired="true" />
        <UpperBound name="video.bitDepth" value="8" />
        <NotMatch name="video.separateFields" value="1" />
      </Limitations>
    </VideoCodec>
    <VideoCodec name="hevc">
      <Limitations>
        <UpperBound name="video.width" value="3840" isRequired="true" />
        <UpperBound name="video.height" value="2160" isRequired="true" />
        <UpperBound name="video.bitDepth" value="10" />
        <NotMatch name="video.separateFields" value="1" />
        <UpperBound name="video.width" value="1920" onlyTranscodes="true" />
        <UpperBound name="video.height" value="1080" onlyTranscodes="true" />
        <UpperBound name="video.bitDepth" value="8" onlyTranscodes="true" />
      </Limitations>
    </VideoCodec>
    <VideoAudioCodec name="*">
      <Limitations>
        <UpperBound name="audio.channels" value="2" onlyTranscodes="true" />
      </Limitations>
    </VideoAudioCodec>
  </CodecProfiles>
</Client>

Save the file with Ctrl+O and exit with Ctrl+X. Afterwards restart your server and enjoy your Spatial Audio!

- Daan