Skip to content

Commit 19582eb

Browse files
authored
Add voice activity analysis (#1466)
* Add hasVoiceActivity attribute to Media * Update tests for voice activity analysis * Fix movie year test * Add canAutoSync attribute to SubtitleStream
1 parent 23ffc01 commit 19582eb

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

plexapi/media.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Media(PlexObject):
2626
height (int): The height of the media in pixels (ex: 256).
2727
id (int): The unique ID for this media on the server.
2828
has64bitOffsets (bool): True if video has 64 bit offsets.
29+
hasVoiceActivity (bool): True if video has voice activity analyzed.
2930
optimizedForStreaming (bool): True if video is optimized for streaming.
3031
parts (List<:class:`~plexapi.media.MediaPart`>): List of media part objects.
3132
proxyType (int): Equals 42 for optimized versions.
@@ -61,6 +62,7 @@ def _loadData(self, data):
6162
self.height = utils.cast(int, data.attrib.get('height'))
6263
self.id = utils.cast(int, data.attrib.get('id'))
6364
self.has64bitOffsets = utils.cast(bool, data.attrib.get('has64bitOffsets'))
65+
self.hasVoiceActivity = utils.cast(bool, data.attrib.get('hasVoiceActivity', '0'))
6466
self.optimizedForStreaming = utils.cast(bool, data.attrib.get('optimizedForStreaming'))
6567
self.parts = self.findItems(data, MediaPart)
6668
self.proxyType = utils.cast(int, data.attrib.get('proxyType'))
@@ -441,6 +443,7 @@ class SubtitleStream(MediaPartStream):
441443
Attributes:
442444
TAG (str): 'Stream'
443445
STREAMTYPE (int): 3
446+
canAutoSync (bool): True if the subtitle stream can be auto synced.
444447
container (str): The container of the subtitle stream.
445448
forced (bool): True if this is a forced subtitle.
446449
format (str): The format of the subtitle stream (ex: srt).
@@ -459,6 +462,7 @@ class SubtitleStream(MediaPartStream):
459462
def _loadData(self, data):
460463
""" Load attribute values from Plex XML response. """
461464
super(SubtitleStream, self)._loadData(data)
465+
self.canAutoSync = utils.cast(bool, data.attrib.get('canAutoSync'))
462466
self.container = data.attrib.get('container')
463467
self.forced = utils.cast(bool, data.attrib.get('forced', '0'))
464468
self.format = data.attrib.get('format')

plexapi/video.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,11 @@ def hasCreditsMarker(self):
447447
""" Returns True if the movie has a credits marker. """
448448
return any(marker.type == 'credits' for marker in self.markers)
449449

450+
@property
451+
def hasVoiceActivity(self):
452+
""" Returns True if any of the media has voice activity analyzed. """
453+
return any(media.hasVoiceActivity for media in self.media)
454+
450455
@property
451456
def hasPreviewThumbnails(self):
452457
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
@@ -1077,6 +1082,11 @@ def hasCreditsMarker(self):
10771082
""" Returns True if the episode has a credits marker. """
10781083
return any(marker.type == 'credits' for marker in self.markers)
10791084

1085+
@property
1086+
def hasVoiceActivity(self):
1087+
""" Returns True if any of the media has voice activity analyzed. """
1088+
return any(media.hasVoiceActivity for media in self.media)
1089+
10801090
@property
10811091
def hasPreviewThumbnails(self):
10821092
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """

tests/test_video.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def test_video_Movie_attrs(movies):
7777
assert "Animation" in [i.tag for i in movie.genres]
7878
assert "imdb://tt1172203" in [i.id for i in movie.guids]
7979
assert movie.guid == "plex://movie/5d776846880197001ec967c6"
80+
assert movie.hasVoiceActivity is False
8081
assert movie.hasPreviewThumbnails is False
8182
assert utils.is_metadata(movie._initpath)
8283
assert utils.is_metadata(movie.key)
@@ -108,7 +109,7 @@ def test_video_Movie_attrs(movies):
108109
assert movie.userRating is None
109110
assert movie.viewCount == 0
110111
assert utils.is_int(movie.viewOffset, gte=0)
111-
assert movie.year == 2009
112+
assert movie.year >= 2008
112113
# Audio
113114
audio = movie.media[0].parts[0].audioStreams()[0]
114115
if audio.audioChannelLayout:
@@ -150,6 +151,7 @@ def test_video_Movie_attrs(movies):
150151
assert utils.is_int(media.id)
151152
assert utils.is_metadata(media._initpath)
152153
assert media.has64bitOffsets is False
154+
assert media.hasVoiceActivity is False
153155
assert media.optimizedForStreaming in [None, False, True]
154156
assert media.proxyType is None
155157
assert media._server._baseurl == utils.SERVER_BASEURL
@@ -1223,6 +1225,7 @@ def test_video_Episode_attrs(episode):
12231225
assert episode.grandparentTitle == "Game of Thrones"
12241226
assert episode.guid == "plex://episode/5d9c1275e98e47001eb84029"
12251227
assert "tvdb://3254641" in [i.id for i in episode.guids]
1228+
assert episode.hasVoiceActivity is False
12261229
assert episode.hasPreviewThumbnails is False
12271230
assert episode.index == 1
12281231
assert episode.episodeNumber == episode.index
@@ -1279,6 +1282,7 @@ def test_video_Episode_attrs(episode):
12791282
assert media.container in utils.CONTAINERS
12801283
assert utils.is_int(media.duration, gte=150000)
12811284
assert utils.is_int(media.height, gte=200)
1285+
assert media.hasVoiceActivity is False
12821286
assert utils.is_int(media.id)
12831287
assert utils.is_metadata(media._initpath)
12841288
if media.optimizedForStreaming:

tools/plex-bootstraptest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ def alert_callback(data):
504504
if not opts.unclaimed and account and account.subscriptionActive:
505505
server.settings.get("GenerateIntroMarkerBehavior").set("never")
506506
server.settings.get("GenerateCreditsMarkerBehavior").set("never")
507+
server.settings.get("GenerateVADBehavior").set("never")
507508
server.settings.get("MusicAnalysisBehavior").set("never")
508509
server.settings.get("GenerateBIFBehavior").set("never")
509510
server.settings.get("GenerateChapterThumbBehavior").set("never")

0 commit comments

Comments
 (0)