diff --git a/plexapi/media.py b/plexapi/media.py index bb5e92f72..ced70bbe1 100644 --- a/plexapi/media.py +++ b/plexapi/media.py @@ -367,6 +367,7 @@ class AudioStream(MediaPartStream): audioChannelLayout (str): The audio channel layout of the audio stream (ex: 5.1(side)). bitDepth (int): The bit depth of the audio stream (ex: 16). bitrateMode (str): The bitrate mode of the audio stream (ex: cbr). + canNormalizeLoudness (bool): True if the audio stream can be normalized for loudness. channels (int): The number of audio channels of the audio stream (ex: 6). duration (int): The duration of audio stream in milliseconds. profile (str): The profile of the audio stream. @@ -395,6 +396,7 @@ def _loadData(self, data): self.audioChannelLayout = data.attrib.get('audioChannelLayout') self.bitDepth = utils.cast(int, data.attrib.get('bitDepth')) self.bitrateMode = data.attrib.get('bitrateMode') + self.canNormalizeLoudness = utils.cast(bool, data.attrib.get('canNormalizeLoudness', '0')) self.channels = utils.cast(int, data.attrib.get('channels')) self.duration = utils.cast(int, data.attrib.get('duration')) self.profile = data.attrib.get('profile') diff --git a/plexapi/video.py b/plexapi/video.py index 44858db23..bcaa611ef 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -503,6 +503,11 @@ def hasPreviewThumbnails(self): """ Returns True if any of the media parts has generated preview (BIF) thumbnails. """ return any(part.hasPreviewThumbnails for media in self.media for part in media.parts) + @property + def canNormalizeLoudness(self): + """ Returns True if any of the media audio streams can normalize loudness. """ + return any(stream.canNormalizeLoudness for stream in self.audioStreams()) + def _prettyfilename(self): """ Returns a filename for use in download. """ return f'{self.title} ({self.year})' @@ -1213,6 +1218,11 @@ def hasPreviewThumbnails(self): """ Returns True if any of the media parts has generated preview (BIF) thumbnails. """ return any(part.hasPreviewThumbnails for media in self.media for part in media.parts) + @property + def canNormalizeLoudness(self): + """ Returns True if any of the media audio streams can normalize loudness. """ + return any(stream.canNormalizeLoudness for stream in self.audioStreams()) + def season(self): """" Return the episode's :class:`~plexapi.video.Season`. """ key = self._buildQueryKey(self.parentKey) diff --git a/tests/test_video.py b/tests/test_video.py index 6beec5084..a05bc659d 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -152,6 +152,7 @@ def test_video_Movie_attrs(movies): # noqa: C901 assert audio.bitDepth is None assert utils.is_int(audio.bitrate) assert audio.bitrateMode is None + assert audio.canNormalizeLoudness in (None, False) assert audio.channels in utils.AUDIOCHANNELS assert audio.codec in utils.CODECS assert audio.default is True