Compare commits
7 Commits
946b1605e0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
0bbf7a405e
|
|||
|
6452cb7f41
|
|||
|
740c892946
|
|||
|
e9827723f4
|
|||
|
89209fa675
|
|||
|
f8619aa66c
|
|||
|
b7ff56ced2
|
@@ -1,4 +1,5 @@
|
|||||||
# 0.1.2
|
# 0.1.2
|
||||||
|
|
||||||
- Extracted utility functions from JellyfinApiClient to JellyfinUtils
|
- Extracted utility functions from JellyfinApiClient to utils modules
|
||||||
- Keep client configuration in Settings class
|
- Keep client configuration in Settings class
|
||||||
|
- Use `OriginalTitle` instead of `Name` for media items when available to provide more accurate titles in Discord Rich Presence
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
from settings import settings
|
from settings import settings
|
||||||
from jellyfin_apiclient_python import JellyfinClient
|
from jellyfin_apiclient_python import JellyfinClient
|
||||||
from jellyfin.models import JellyfinMediaItem, JellyfinMediaType, JellyfinMusicMediaMetadata, JellyfinMovieMediaMetadata, JellyfinEpisodeMediaMetadata
|
from jellyfin.models import (
|
||||||
from jellyfin.utils import JellyfinUtils
|
JellyfinMediaItem,
|
||||||
from datetime import datetime
|
JellyfinMediaType,
|
||||||
from typing import Optional, Tuple
|
JellyfinMusicMediaMetadata,
|
||||||
|
JellyfinMovieMediaMetadata,
|
||||||
|
JellyfinEpisodeMediaMetadata
|
||||||
|
)
|
||||||
|
from jellyfin.utils.config import configure_client
|
||||||
|
from jellyfin.utils.image import get_image_url
|
||||||
|
from jellyfin.utils.models import episode, movie, audio
|
||||||
|
from typing import Optional
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -26,7 +33,7 @@ class JellyfinApiClient:
|
|||||||
self.logger.info("Connecting to Jellyfin server...")
|
self.logger.info("Connecting to Jellyfin server...")
|
||||||
|
|
||||||
self.client = JellyfinClient()
|
self.client = JellyfinClient()
|
||||||
JellyfinUtils.configure_client(self.client)
|
configure_client(self.client)
|
||||||
|
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
self.logger.info("Connected to Jellyfin server.")
|
self.logger.info("Connected to Jellyfin server.")
|
||||||
@@ -45,9 +52,9 @@ class JellyfinApiClient:
|
|||||||
self.last_auth_time = time.time()
|
self.last_auth_time = time.time()
|
||||||
self.logger.info("Authenticated with Jellyfin server.")
|
self.logger.info("Authenticated with Jellyfin server.")
|
||||||
|
|
||||||
def get_current_playback(self) -> Optional[JellyfinMediaItem]:
|
def get_current_media(self) -> Optional[JellyfinMediaItem]:
|
||||||
"""
|
"""
|
||||||
Fetches the current playback information from the Jellyfin server.
|
Fetches the current media information from the Jellyfin server.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[JellyfinMediaItem]: The current playback media item or None if no active playback is found.
|
Optional[JellyfinMediaItem]: The current playback media item or None if no active playback is found.
|
||||||
@@ -74,18 +81,6 @@ class JellyfinApiClient:
|
|||||||
self.logger.info("No active playback found.")
|
self.logger.info("No active playback found.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_image_url(self, media_id: str) -> str:
|
|
||||||
"""
|
|
||||||
Constructs the image URL for a given media item.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
media_id (str): The ID of the media item.
|
|
||||||
Returns:
|
|
||||||
str: The constructed image URL.
|
|
||||||
"""
|
|
||||||
server_address = settings.jellyfin_server_url.rstrip('/')
|
|
||||||
return f"{server_address}/Items/{media_id}/Images/Primary?maxWidth=300&maxHeight=300"
|
|
||||||
|
|
||||||
def to_model(self, item: dict) -> JellyfinMediaItem:
|
def to_model(self, item: dict) -> JellyfinMediaItem:
|
||||||
"""
|
"""
|
||||||
Converts a Jellyfin media item dictionary to a JellyfinMediaItem model.
|
Converts a Jellyfin media item dictionary to a JellyfinMediaItem model.
|
||||||
@@ -98,126 +93,8 @@ class JellyfinApiClient:
|
|||||||
media_type = item.get('Type')
|
media_type = item.get('Type')
|
||||||
|
|
||||||
if media_type == 'Audio':
|
if media_type == 'Audio':
|
||||||
return self.to_music_model(item)
|
return audio.to_media_item(item)
|
||||||
elif media_type == 'Episode':
|
elif media_type == 'Episode':
|
||||||
return self.to_episode_model(item)
|
return episode.to_media_item(item, self.client)
|
||||||
elif media_type == 'Movie':
|
elif media_type == 'Movie':
|
||||||
return self.to_movie_model(item)
|
return movie.to_media_item(item)
|
||||||
|
|
||||||
def get_playback_info(
|
|
||||||
self, media: dict) -> Tuple[Optional[int], Optional[int]]:
|
|
||||||
"""
|
|
||||||
Extracts playback start and end timestamps from a media item.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
media (dict): The Jellyfin media item dictionary.
|
|
||||||
Returns:
|
|
||||||
Tuple[Optional[int], Optional[int]]: A tuple containing the start and end timestamps in seconds, or (None, None) if the media is paused.
|
|
||||||
"""
|
|
||||||
play_state = media.get('PlayState')
|
|
||||||
is_paused = play_state.get('IsPaused')
|
|
||||||
|
|
||||||
if is_paused:
|
|
||||||
return (None, None)
|
|
||||||
|
|
||||||
runtime_ticks = media.get('RunTimeTicks')
|
|
||||||
total_runtime_seconds = runtime_ticks // 10_000_000
|
|
||||||
|
|
||||||
playback_position_ticks = play_state.get('PositionTicks')
|
|
||||||
playback_position_seconds = playback_position_ticks // 10_000_000
|
|
||||||
|
|
||||||
start = int(datetime.now().timestamp()) - playback_position_seconds
|
|
||||||
end = start + total_runtime_seconds
|
|
||||||
|
|
||||||
return (start, end)
|
|
||||||
|
|
||||||
def to_music_model(self, item: dict) -> JellyfinMediaItem:
|
|
||||||
"""
|
|
||||||
Converts a Jellyfin music media item dictionary to a JellyfinMediaItem model.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
item (dict): The Jellyfin music media item dictionary.
|
|
||||||
Returns:
|
|
||||||
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
|
||||||
"""
|
|
||||||
media_id = item.get('Id')
|
|
||||||
parent_id = item.get('ParentId')
|
|
||||||
premiere_date = item.get('PremiereDate')
|
|
||||||
premiere_year = datetime.fromisoformat(
|
|
||||||
premiere_date).year if premiere_date else None
|
|
||||||
|
|
||||||
metadata = JellyfinMusicMediaMetadata(
|
|
||||||
artist=item.get('AlbumArtist'), album=f"{
|
|
||||||
item.get('Album')} ({premiere_year})" if premiere_date else item.get('Album'))
|
|
||||||
|
|
||||||
(start, end) = self.get_playback_info(item)
|
|
||||||
|
|
||||||
return JellyfinMediaItem(
|
|
||||||
id=media_id,
|
|
||||||
name=item.get('Name'),
|
|
||||||
type=JellyfinMediaType.AUDIO,
|
|
||||||
image_url=self.get_image_url(parent_id),
|
|
||||||
start=start,
|
|
||||||
end=end,
|
|
||||||
metadata=metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
def to_movie_model(self, item: dict) -> JellyfinMediaItem:
|
|
||||||
"""
|
|
||||||
Converts a Jellyfin movie media item dictionary to a JellyfinMediaItem model.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
item (dict): The Jellyfin movie media item dictionary.
|
|
||||||
Returns:
|
|
||||||
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
|
||||||
"""
|
|
||||||
media_id = item.get('Id')
|
|
||||||
premiere_date = item.get('PremiereDate')
|
|
||||||
|
|
||||||
metadata = JellyfinMovieMediaMetadata(date=datetime.fromisoformat(
|
|
||||||
premiere_date).strftime('%d/%m/%Y') if premiere_date else None)
|
|
||||||
|
|
||||||
(start, end) = self.get_playback_info(item)
|
|
||||||
|
|
||||||
return JellyfinMediaItem(
|
|
||||||
id=media_id,
|
|
||||||
name=item.get('Name'),
|
|
||||||
type=JellyfinMediaType.MOVIE,
|
|
||||||
image_url=self.get_image_url(media_id),
|
|
||||||
start=start,
|
|
||||||
end=end,
|
|
||||||
metadata=metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
def to_episode_model(self, item: dict) -> JellyfinMediaItem:
|
|
||||||
"""
|
|
||||||
Converts a Jellyfin episode media item dictionary to a JellyfinMediaItem model.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
item (dict): The Jellyfin episode media item dictionary.
|
|
||||||
Returns:
|
|
||||||
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
|
||||||
"""
|
|
||||||
media_id = item.get('Id')
|
|
||||||
parent = self.client.jellyfin.get_item(item.get('ParentId'))
|
|
||||||
parent_id = parent.get('ParentId')
|
|
||||||
series_name = item.get('SeriesName')
|
|
||||||
season_number = item.get('ParentIndexNumber')
|
|
||||||
episode_number = item.get('IndexNumber')
|
|
||||||
|
|
||||||
metadata = JellyfinEpisodeMediaMetadata(
|
|
||||||
subtitle=f"S{
|
|
||||||
season_number:02}E{
|
|
||||||
episode_number:02} of {series_name}")
|
|
||||||
|
|
||||||
(start, end) = self.get_playback_info(item)
|
|
||||||
|
|
||||||
return JellyfinMediaItem(
|
|
||||||
id=media_id,
|
|
||||||
name=item.get('Name'),
|
|
||||||
type=JellyfinMediaType.EPISODE,
|
|
||||||
image_url=self.get_image_url(parent_id),
|
|
||||||
start=start,
|
|
||||||
end=end,
|
|
||||||
metadata=metadata
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class JellyfinMusicMediaMetadata(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class JellyfinMovieMediaMetadata(BaseModel):
|
class JellyfinMovieMediaMetadata(BaseModel):
|
||||||
date: Optional[str]
|
year: Optional[int]
|
||||||
|
|
||||||
|
|
||||||
class JellyfinEpisodeMediaMetadata(BaseModel):
|
class JellyfinEpisodeMediaMetadata(BaseModel):
|
||||||
@@ -58,7 +58,7 @@ class JellyfinMediaItem(BaseModel):
|
|||||||
return DiscordRPCUpdatePayload(
|
return DiscordRPCUpdatePayload(
|
||||||
id=self.id,
|
id=self.id,
|
||||||
title=f"Watching {self.name}",
|
title=f"Watching {self.name}",
|
||||||
subtitle=self.metadata.date,
|
subtitle=str(self.metadata.year),
|
||||||
image_url=str(self.image_url),
|
image_url=str(self.image_url),
|
||||||
details=self.name,
|
details=self.name,
|
||||||
activity_type=ActivityType.WATCHING,
|
activity_type=ActivityType.WATCHING,
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
from jellyfin_apiclient_python import JellyfinClient
|
|
||||||
from getmac import get_mac_address
|
|
||||||
from settings import settings
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
class JellyfinUtils:
|
|
||||||
@staticmethod
|
|
||||||
def configure_client(client: JellyfinClient):
|
|
||||||
client.config.app(
|
|
||||||
settings.app_name,
|
|
||||||
settings.app_version,
|
|
||||||
JellyfinUtils.get_machine_name(),
|
|
||||||
JellyfinUtils.get_unique_id()
|
|
||||||
)
|
|
||||||
client.config.data['auth.ssl'] = settings.jellyfin_server_url.startswith(
|
|
||||||
'https://')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_machine_name() -> str:
|
|
||||||
"""
|
|
||||||
Retrieves the machine name of the current host.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The machine name.
|
|
||||||
"""
|
|
||||||
return os.uname().nodename
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_unique_id() -> str:
|
|
||||||
"""
|
|
||||||
Retrieves the MAC address of the localhost as a unique identifier.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The MAC address.
|
|
||||||
"""
|
|
||||||
return get_mac_address(hostname="localhost")
|
|
||||||
41
jellyfin/utils/config.py
Normal file
41
jellyfin/utils/config.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
from jellyfin_apiclient_python import JellyfinClient
|
||||||
|
from getmac import get_mac_address
|
||||||
|
from settings import settings
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def configure_client(client: JellyfinClient):
|
||||||
|
"""
|
||||||
|
Configures the Jellyfin client with application details and SSL settings.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
client (JellyfinClient): The Jellyfin client to configure.
|
||||||
|
"""
|
||||||
|
client.config.app(
|
||||||
|
settings.app_name,
|
||||||
|
settings.app_version,
|
||||||
|
get_machine_name(),
|
||||||
|
get_unique_id()
|
||||||
|
)
|
||||||
|
client.config.data['auth.ssl'] = settings.jellyfin_server_url.startswith(
|
||||||
|
'https://')
|
||||||
|
|
||||||
|
|
||||||
|
def get_machine_name() -> str:
|
||||||
|
"""
|
||||||
|
Retrieves the machine name of the current host.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The machine name.
|
||||||
|
"""
|
||||||
|
return os.uname().nodename
|
||||||
|
|
||||||
|
|
||||||
|
def get_unique_id() -> str:
|
||||||
|
"""
|
||||||
|
Retrieves the MAC address of the localhost as a unique identifier.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The MAC address.
|
||||||
|
"""
|
||||||
|
return get_mac_address(hostname="localhost")
|
||||||
14
jellyfin/utils/image.py
Normal file
14
jellyfin/utils/image.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from settings import settings
|
||||||
|
|
||||||
|
|
||||||
|
def get_image_url(media_id: str) -> str:
|
||||||
|
"""
|
||||||
|
Constructs the image URL for a given media item.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
media_id (str): The ID of the media item.
|
||||||
|
Returns:
|
||||||
|
str: The constructed image URL.
|
||||||
|
"""
|
||||||
|
server_address = settings.jellyfin_server_url.rstrip('/')
|
||||||
|
return f"{server_address}/Items/{media_id}/Images/Primary?maxWidth=300&maxHeight=300"
|
||||||
53
jellyfin/utils/models/audio.py
Normal file
53
jellyfin/utils/models/audio.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
from jellyfin.models import (
|
||||||
|
JellyfinMediaItem,
|
||||||
|
JellyfinMediaType,
|
||||||
|
JellyfinMusicMediaMetadata
|
||||||
|
)
|
||||||
|
from jellyfin.utils.playback import get_current_playback
|
||||||
|
from jellyfin.utils.image import get_image_url
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def to_media_item(
|
||||||
|
item: dict
|
||||||
|
) -> JellyfinMediaItem:
|
||||||
|
"""
|
||||||
|
Converts a Jellyfin audio media item dictionary to a JellyfinMediaItem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (dict): The Jellyfin music media item dictionary.
|
||||||
|
Returns:
|
||||||
|
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
||||||
|
"""
|
||||||
|
item_id = item.get('Id')
|
||||||
|
|
||||||
|
# Get album ID (for image)
|
||||||
|
album_id = item.get('ParentId')
|
||||||
|
|
||||||
|
# Construct album title (with year if available)
|
||||||
|
premiere_date = item.get('PremiereDate')
|
||||||
|
premiere_year = None
|
||||||
|
album = item.get('Album')
|
||||||
|
|
||||||
|
if premiere_date:
|
||||||
|
premiere_year = datetime.fromisoformat(premiere_date).year
|
||||||
|
album = f"{album} ({premiere_year})"
|
||||||
|
|
||||||
|
# Construct metadata
|
||||||
|
metadata = JellyfinMusicMediaMetadata(
|
||||||
|
artist=item.get('AlbumArtist'),
|
||||||
|
album=album
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get playback positions
|
||||||
|
(start, end) = get_current_playback(item)
|
||||||
|
|
||||||
|
return JellyfinMediaItem(
|
||||||
|
id=item_id,
|
||||||
|
name=item.get('Name'),
|
||||||
|
type=JellyfinMediaType.AUDIO,
|
||||||
|
image_url=get_image_url(album_id),
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
metadata=metadata
|
||||||
|
)
|
||||||
52
jellyfin/utils/models/episode.py
Normal file
52
jellyfin/utils/models/episode.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
from jellyfin.models import (
|
||||||
|
JellyfinMediaItem,
|
||||||
|
JellyfinMediaType,
|
||||||
|
JellyfinEpisodeMediaMetadata
|
||||||
|
)
|
||||||
|
from jellyfin_apiclient_python import JellyfinClient
|
||||||
|
from jellyfin.utils.playback import get_current_playback
|
||||||
|
from jellyfin.utils.image import get_image_url
|
||||||
|
|
||||||
|
|
||||||
|
def to_media_item(
|
||||||
|
item: dict,
|
||||||
|
client: JellyfinClient
|
||||||
|
) -> JellyfinMediaItem:
|
||||||
|
"""
|
||||||
|
Converts a Jellyfin episode media item dictionary to a JellyfinMediaItem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (dict): The Jellyfin episode media item dictionary.
|
||||||
|
client (JellyfinClient): The Jellyfin client instance.
|
||||||
|
Returns:
|
||||||
|
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
||||||
|
"""
|
||||||
|
item_id = item.get('Id')
|
||||||
|
|
||||||
|
# Construct SxxExx name
|
||||||
|
series_name = item.get('SeriesName')
|
||||||
|
season_number = item.get('ParentIndexNumber')
|
||||||
|
episode_number = item.get('IndexNumber')
|
||||||
|
name = f"{series_name} S{season_number:02}E{episode_number:02}"
|
||||||
|
|
||||||
|
# Get TV show ID (for image)
|
||||||
|
season = client.jellyfin.get_item(item.get('ParentId'))
|
||||||
|
show_id = season.get('ParentId')
|
||||||
|
|
||||||
|
# Construct metadata
|
||||||
|
metadata = JellyfinEpisodeMediaMetadata(
|
||||||
|
subtitle=item.get('Name'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get playback positions
|
||||||
|
(start, end) = get_current_playback(item)
|
||||||
|
|
||||||
|
return JellyfinMediaItem(
|
||||||
|
id=item_id,
|
||||||
|
name=name,
|
||||||
|
type=JellyfinMediaType.EPISODE,
|
||||||
|
image_url=get_image_url(show_id),
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
metadata=metadata
|
||||||
|
)
|
||||||
48
jellyfin/utils/models/movie.py
Normal file
48
jellyfin/utils/models/movie.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from jellyfin.models import (
|
||||||
|
JellyfinMediaItem,
|
||||||
|
JellyfinMediaType,
|
||||||
|
JellyfinMovieMediaMetadata
|
||||||
|
)
|
||||||
|
from jellyfin.utils.playback import get_current_playback
|
||||||
|
from jellyfin.utils.image import get_image_url
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def to_media_item(
|
||||||
|
item: dict
|
||||||
|
) -> JellyfinMediaItem:
|
||||||
|
"""
|
||||||
|
Converts a Jellyfin movie media item dictionary to a JellyfinMediaItem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (dict): The Jellyfin movie media item dictionary.
|
||||||
|
Returns:
|
||||||
|
JellyfinMediaItem: The converted JellyfinMediaItem model.
|
||||||
|
"""
|
||||||
|
item_id = item.get('Id')
|
||||||
|
|
||||||
|
# Get name
|
||||||
|
name = item.get('OriginalTitle')
|
||||||
|
if not name:
|
||||||
|
name = item.get('Name')
|
||||||
|
|
||||||
|
# Construct metadata
|
||||||
|
premiere_date = item.get('PremiereDate')
|
||||||
|
premiere_year = datetime.fromisoformat(premiere_date).year
|
||||||
|
|
||||||
|
metadata = JellyfinMovieMediaMetadata(
|
||||||
|
year=premiere_year
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get playback positions
|
||||||
|
(start, end) = get_current_playback(item)
|
||||||
|
|
||||||
|
return JellyfinMediaItem(
|
||||||
|
id=item_id,
|
||||||
|
name=name,
|
||||||
|
type=JellyfinMediaType.MOVIE,
|
||||||
|
image_url=get_image_url(item_id),
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
metadata=metadata
|
||||||
|
)
|
||||||
32
jellyfin/utils/playback.py
Normal file
32
jellyfin/utils/playback.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_playback(media: dict) -> Tuple[Optional[int], Optional[int]]:
|
||||||
|
"""
|
||||||
|
Extracts playback start and end positions from a Jellyfin media item dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
media (dict): The Jellyfin media item dictionary.
|
||||||
|
Returns:
|
||||||
|
Tuple[Optional[int], Optional[int]]: A tuple containing the start and end positions in seconds, or (None, None) if the media is paused.
|
||||||
|
"""
|
||||||
|
play_state = media.get('PlayState', {})
|
||||||
|
is_paused = play_state.get('IsPaused', False)
|
||||||
|
|
||||||
|
if is_paused:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
runtime_ticks = media.get('RunTimeTicks', -1)
|
||||||
|
playback_position_ticks = play_state.get('PositionTicks', -1)
|
||||||
|
|
||||||
|
if runtime_ticks < 0 or playback_position_ticks < 0:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
total_runtime_seconds = runtime_ticks // 10_000_000
|
||||||
|
playback_position_seconds = playback_position_ticks // 10_000_000
|
||||||
|
|
||||||
|
start = int(datetime.now().timestamp()) - playback_position_seconds
|
||||||
|
end = start + total_runtime_seconds
|
||||||
|
|
||||||
|
return (start, end)
|
||||||
2
main.py
2
main.py
@@ -16,7 +16,7 @@ def main():
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
media_item = jellyfin_api_client.get_current_playback()
|
media_item = jellyfin_api_client.get_current_media()
|
||||||
if not media_item:
|
if not media_item:
|
||||||
discord_rpc.clear()
|
discord_rpc.clear()
|
||||||
time.sleep(settings.poll_interval)
|
time.sleep(settings.poll_interval)
|
||||||
|
|||||||
Reference in New Issue
Block a user