mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-21 11:13:08 +00:00
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
This commit is contained in:
parent
23ffc01756
commit
19582eb649
4 changed files with 20 additions and 1 deletions
|
@ -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.
|
||||
|
@ -61,6 +62,7 @@ class Media(PlexObject):
|
|||
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'))
|
||||
|
@ -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).
|
||||
|
@ -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')
|
||||
|
|
|
@ -447,6 +447,11 @@ class Movie(
|
|||
""" 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. """
|
||||
|
@ -1077,6 +1082,11 @@ class Episode(
|
|||
""" 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. """
|
||||
|
|
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
|
|
@ -504,6 +504,7 @@ if __name__ == "__main__": # noqa: C901
|
|||
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")
|
||||
|
|
Loading…
Reference in a new issue