Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions pyatv/protocols/mrp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,16 @@ def position() -> Optional[int]:
elapsed_timestamp = state.metadata_field("elapsedTimeTimestamp")

# If we don't have reference time, we can't do anything
if not elapsed_timestamp:
if not elapsed_timestamp or math.isnan(elapsed_timestamp):
return None

# Both fields are doubles in the protobuf definition and devices do report NaN
# for them, which is not convertible to an integer (NaN is also truthy, so "or"
# does not help here).
elapsed_time: float = state.metadata_field("elapsedTime") or 0.0
if math.isnan(elapsed_time):
return None

elapsed_time: int = state.metadata_field("elapsedTime") or 0
diff = (
datetime.datetime.now() - _cocoa_to_timestamp(elapsed_timestamp)
).total_seconds()
Expand Down
15 changes: 15 additions & 0 deletions tests/protocols/mrp/test_mrp_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,18 @@ async def test_metadata_position_calculation(metadata, playing_metadata, player_
player_state.playback_state = protobuf.PlaybackState.Playing
playing_metadata["playbackRate"] = 0.0
assert (await metadata.playing()).position == ELAPSED_TIME


async def test_metadata_position_nan(metadata, playing_metadata, player_state):
# Devices sometimes report NaN as elapsed time, which cannot be converted to an
# integer. Treat it as no position at all instead of raising ValueError.
playing_metadata["elapsedTime"] = math.nan

with faketime("pyatv", NOW_TIME):
# Paused state
assert (await metadata.playing()).position is None

# Playing state
player_state.playback_state = protobuf.PlaybackState.Playing
playing_metadata["playbackRate"] = 1.0
assert (await metadata.playing()).position is None