Skip to content

Commit

Permalink
Add voice activity analysis (#1466)
Browse files Browse the repository at this point in the history
* Add hasVoiceActivity attribute to Media

* Update tests for voice activity analysis

* Fix movie year test

* Add canAutoSync attribute to SubtitleStream
  • Loading branch information
JonnyWong16 authored Sep 22, 2024
1 parent 23ffc01 commit 19582eb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 1 deletion.
4 changes: 4 additions & 0 deletions plexapi/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Media(PlexObject):
height (int): The height of the media in pixels (ex: 256).
id (int): The unique ID for this media on the server.
has64bitOffsets (bool): True if video has 64 bit offsets.
hasVoiceActivity (bool): True if video has voice activity analyzed.
optimizedForStreaming (bool): True if video is optimized for streaming.
parts (List<:class:`~plexapi.media.MediaPart`>): List of media part objects.
proxyType (int): Equals 42 for optimized versions.
Expand Down Expand Up @@ -61,6 +62,7 @@ def _loadData(self, data):
self.height = utils.cast(int, data.attrib.get('height'))
self.id = utils.cast(int, data.attrib.get('id'))
self.has64bitOffsets = utils.cast(bool, data.attrib.get('has64bitOffsets'))
self.hasVoiceActivity = utils.cast(bool, data.attrib.get('hasVoiceActivity', '0'))
self.optimizedForStreaming = utils.cast(bool, data.attrib.get('optimizedForStreaming'))
self.parts = self.findItems(data, MediaPart)
self.proxyType = utils.cast(int, data.attrib.get('proxyType'))
Expand Down Expand Up @@ -441,6 +443,7 @@ class SubtitleStream(MediaPartStream):
Attributes:
TAG (str): 'Stream'
STREAMTYPE (int): 3
canAutoSync (bool): True if the subtitle stream can be auto synced.
container (str): The container of the subtitle stream.
forced (bool): True if this is a forced subtitle.
format (str): The format of the subtitle stream (ex: srt).
Expand All @@ -459,6 +462,7 @@ class SubtitleStream(MediaPartStream):
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
super(SubtitleStream, self)._loadData(data)
self.canAutoSync = utils.cast(bool, data.attrib.get('canAutoSync'))
self.container = data.attrib.get('container')
self.forced = utils.cast(bool, data.attrib.get('forced', '0'))
self.format = data.attrib.get('format')
Expand Down
10 changes: 10 additions & 0 deletions plexapi/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,11 @@ def hasCreditsMarker(self):
""" Returns True if the movie has a credits marker. """
return any(marker.type == 'credits' for marker in self.markers)

@property
def hasVoiceActivity(self):
""" Returns True if any of the media has voice activity analyzed. """
return any(media.hasVoiceActivity for media in self.media)

@property
def hasPreviewThumbnails(self):
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
Expand Down Expand Up @@ -1077,6 +1082,11 @@ def hasCreditsMarker(self):
""" Returns True if the episode has a credits marker. """
return any(marker.type == 'credits' for marker in self.markers)

@property
def hasVoiceActivity(self):
""" Returns True if any of the media has voice activity analyzed. """
return any(media.hasVoiceActivity for media in self.media)

@property
def hasPreviewThumbnails(self):
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
Expand Down
6 changes: 5 additions & 1 deletion tests/test_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def test_video_Movie_attrs(movies):
assert "Animation" in [i.tag for i in movie.genres]
assert "imdb://tt1172203" in [i.id for i in movie.guids]
assert movie.guid == "plex://movie/5d776846880197001ec967c6"
assert movie.hasVoiceActivity is False
assert movie.hasPreviewThumbnails is False
assert utils.is_metadata(movie._initpath)
assert utils.is_metadata(movie.key)
Expand Down Expand Up @@ -108,7 +109,7 @@ def test_video_Movie_attrs(movies):
assert movie.userRating is None
assert movie.viewCount == 0
assert utils.is_int(movie.viewOffset, gte=0)
assert movie.year == 2009
assert movie.year >= 2008
# Audio
audio = movie.media[0].parts[0].audioStreams()[0]
if audio.audioChannelLayout:
Expand Down Expand Up @@ -150,6 +151,7 @@ def test_video_Movie_attrs(movies):
assert utils.is_int(media.id)
assert utils.is_metadata(media._initpath)
assert media.has64bitOffsets is False
assert media.hasVoiceActivity is False
assert media.optimizedForStreaming in [None, False, True]
assert media.proxyType is None
assert media._server._baseurl == utils.SERVER_BASEURL
Expand Down Expand Up @@ -1223,6 +1225,7 @@ def test_video_Episode_attrs(episode):
assert episode.grandparentTitle == "Game of Thrones"
assert episode.guid == "plex://episode/5d9c1275e98e47001eb84029"
assert "tvdb://3254641" in [i.id for i in episode.guids]
assert episode.hasVoiceActivity is False
assert episode.hasPreviewThumbnails is False
assert episode.index == 1
assert episode.episodeNumber == episode.index
Expand Down Expand Up @@ -1279,6 +1282,7 @@ def test_video_Episode_attrs(episode):
assert media.container in utils.CONTAINERS
assert utils.is_int(media.duration, gte=150000)
assert utils.is_int(media.height, gte=200)
assert media.hasVoiceActivity is False
assert utils.is_int(media.id)
assert utils.is_metadata(media._initpath)
if media.optimizedForStreaming:
Expand Down
1 change: 1 addition & 0 deletions tools/plex-bootstraptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ def alert_callback(data):
if not opts.unclaimed and account and account.subscriptionActive:
server.settings.get("GenerateIntroMarkerBehavior").set("never")
server.settings.get("GenerateCreditsMarkerBehavior").set("never")
server.settings.get("GenerateVADBehavior").set("never")
server.settings.get("MusicAnalysisBehavior").set("never")
server.settings.get("GenerateBIFBehavior").set("never")
server.settings.get("GenerateChapterThumbBehavior").set("never")
Expand Down

0 comments on commit 19582eb

Please sign in to comment.