Skip to content

fix: correctly display duration statistic in preview panel#1421

Open
ludvig-sandh wants to merge 3 commits into
TagStudioDev:mainfrom
ludvig-sandh:fix-thumb-panel-duration
Open

fix: correctly display duration statistic in preview panel#1421
ludvig-sandh wants to merge 3 commits into
TagStudioDev:mainfrom
ludvig-sandh:fix-thumb-panel-duration

Conversation

@ludvig-sandh

Copy link
Copy Markdown
Contributor

Summary

Fixes #1037, where previewing a video/audio didn't display the duration until selected again. Once selected again, duration was displayed, but a million times larger than expected.

The "million times larger" problem came from multiplying the duration in milliseconds by 1000. The fix was to divide by 1000 instead, to get seconds.

The problem of the duration not showing up was due to QMediaPlayer loading the duration asynchronously but the UI's trying to access it immediately. I fixed it by adding a signal that is triggered when the duration is available by QMediaPlayer. This signal causes the UI to update again via a callback, this time including the duration.

Some extra details:

  • I return early in the callback if the selected preview file has been changed by the user. This avoids displaying stale preview information.
  • The function updating the preview stats (in the UI) is called both immediately and upon the callback, making sure the immediately available data still shows up on screen even if QMediaPlayer would be slow/fail to load the duration.
  • Renamed PreviewThumbView.__filepath to PreviewThumbView.__thumb_filepath since we now store both the path to the thumb and media file in that class, and we want to distinguish them. Just makes everything clearer.
  • Previously this solution was used for formatting the duration:
    dur_str = str(timedelta(seconds=float(stats.duration)))[:-7]
    I think the idea was to strip out the microseconds (6 digits plus the decimal point). However, converting a timedelta to a string doesn't include microseconds. So this solution incorrectly pruned 7 characters from the valid duration string. I ended up replacing it with my own formatter for clarity.

Tasks Completed

Evidence of correct duration stats:
image

Also tried quickly selecting different files and verified that always the expected duration showed up on screen.

  • Platforms Tested:
    • Windows x86
    • Windows ARM
    • macOS x86
    • macOS ARM
    • Linux x86
    • Linux ARM
  • Tested For:
    • Basic functionality
    • PyInstaller executable

@CyanVoxel CyanVoxel added Type: UI/UX User interface and/or user experience Priority: Medium An issue that shouldn't be be saved for last Status: Review Needed A review of this is needed Type: Fix A fix for a bug, typo, or other issue labels Jul 4, 2026
@CyanVoxel CyanVoxel moved this to 🏓 Ready for Review in TagStudio Development Jul 4, 2026
Comment thread src/tagstudio/qt/views/preview_thumb_view.py Outdated
@CyanVoxel CyanVoxel added this to the Alpha v9.6.2 milestone Jul 11, 2026

@CyanVoxel CyanVoxel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved when remaining comments are addressed 👍

self.lib, driver
) # TODO: this should be name mangled, but is still needed on the controller side atm
self.__current_stats: FileAttributeData | None = None
self.__current_stats_filepath: Path | None = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't appear to be a purpose to this self.__current_stats_filepath variable, is that correct?

Comment on lines +41 to +49
def _format_duration(duration: int | float) -> str:
"""Format a duration in seconds as M:SS or H:MM:SS."""
try:
seconds = int(float(duration))
hours, seconds = divmod(seconds, 3600)
minutes, seconds = divmod(seconds, 60)
return f"{hours}:{minutes:02}:{seconds:02}" if hours else f"{minutes}:{seconds:02}"
except (OverflowError, ValueError):
return "-:--"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't have to be limited to this file - if it's going to be outside the FileAttributes class, it can be made a public function inside the src/tagstudio/core/utils/str_formatting.py file

"""The Preview Panel Widget."""

check_ffmpeg = Signal(bool)
stats_updated = Signal(object, object)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These types should be made more specific than object, e.g. Signal(Path, FileAttributeData)

@CyanVoxel CyanVoxel moved this from 🏓 Ready for Review to 👀 In review in TagStudio Development Jul 11, 2026
@CyanVoxel CyanVoxel removed the Status: Review Needed A review of this is needed label Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority: Medium An issue that shouldn't be be saved for last Type: Fix A fix for a bug, typo, or other issue Type: UI/UX User interface and/or user experience

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

[Bug]: File Duration Label Non-Functional

2 participants