Skip to content

feat(ui): display video thumbnail #7374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

willybrauner
Copy link
Contributor

@willybrauner willybrauner commented Jul 26, 2024

Description

This PR is about displaying a video thumbnail in Thumbnail component if the uploaded file has mimeType video/*. To avoid performance issue, the video is not played, only the first frame is displayed from a <video> tag, but it can be managed differently (with intersection observer, click handler etc.)

When you manage a large collection of assets/files, it is very difficult to quickly find a video by file name, video preview can help to identify the file by its first frame.

After change :

video-thumbnail.mov
  • I have read and understand the CONTRIBUTING.md document in this repository.

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • Existing test suite passes locally with my changes

@willybrauner willybrauner marked this pull request as draft July 26, 2024 08:46
@willybrauner willybrauner changed the base branch from main to beta July 26, 2024 08:47
@willybrauner willybrauner marked this pull request as ready for review July 26, 2024 08:47
@willybrauner willybrauner changed the title Feat/display video thumbnail feat: display video thumbnail Jul 26, 2024
@willybrauner
Copy link
Contributor Author

Are there any clarifications I can provide or changes that should be made to this?

@willybrauner willybrauner changed the title feat: display video thumbnail feat(ui): display video thumbnail Jul 29, 2024
@denolfe denolfe self-assigned this Aug 22, 2024
@denolfe
Copy link
Member

denolfe commented Aug 22, 2024

Revisiting this one. Are you able to resolve merge conflicts @willybrauner ?

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 0bc092b to 41e3396 Compare August 23, 2024 18:57
@willybrauner
Copy link
Contributor Author

willybrauner commented Aug 23, 2024

@denolfe it's rebased on beta.

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 9c6e646 to 0dbd0fc Compare October 10, 2024 08:34
@willybrauner
Copy link
Contributor Author

willybrauner commented Oct 10, 2024

@denolfe I updated this PR with the last beta. One unit test failed, but I'm not sure to know how to fix it.

@denolfe
Copy link
Member

denolfe commented Oct 10, 2024

Since the failing e2e test is uploads, it's likely either a legitimate failure or the test needs to be updated (could just be a small selector tweak).

To troubleshoot:

  1. Download the artifact for uploads tests on the github action result
CleanShot 2024-10-10 at 15 43 25
  1. Unzip artifacts
image
  1. Drop trace.zip into https://trace.playwright.dev/

  2. View failure.

If I had to guess, it's likely looking for a selector that was changed/removed.
CleanShot 2024-10-10 at 15 44 44

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 0dbd0fc to c731940 Compare October 13, 2024 19:40
@willybrauner willybrauner reopened this Oct 13, 2024
@willybrauner
Copy link
Contributor Author

willybrauner commented Oct 14, 2024

@denolfe I have improved the Thumbnail component by mixing Thumbnail & ThumbnailComponent who was shared the same logic. I just comment the breaking test for now.

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 10635e3 to cc4220d Compare October 14, 2024 06:59
@paulpopus
Copy link
Contributor

For some reason I can't checkout to this PR locally whatsoever...

However, you should comment that test back in because it checks for the existence of the thumbnail.

Your code specifically shows nothing if the filetype is neither an image or a video, instead to keep our backwards compatibility, you should turn this into a ? : render. Render video if the filetype is video and render the thumbnail otherwise. For documents we render an icon for example.

{fileExists && fileType === 'image' && <img alt={alt} src={src} />}

I'm not sure why the test would fail in this case anyhow

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from cc4220d to 191a8ad Compare October 15, 2024 06:06
@willybrauner
Copy link
Contributor Author

@paulpopus nice catch, you're right about the image fallback, I have fixed it in this way.

@denolfe. Thanks for the test usage explanation; I was able to run and trace it locally. The initial error was due to the preload "if else" statement, depending to the mimeType, on the same way than the render function.

I have finally implemented an alternative than the <video> tag in order to keep a simple <img/> rendering. I capture a video frame by drawing it on a canvas. This seems like a better option since many video tags will cause performance issues if a large list of thumbnails needs to be rendered at once.

Capture d’écran 2024-10-15 à 10 40 36

@willybrauner
Copy link
Contributor Author

willybrauner commented Oct 16, 2024

Seems to be pretty quick with this method :)

screen.mov

@willybrauner
Copy link
Contributor Author

@paulpopus @denolfe is this approach could be a right one for you?

@denolfe denolfe assigned paulpopus and unassigned denolfe Oct 23, 2024
@paulpopus
Copy link
Contributor

@willybrauner interesting pattern, I don't think we're opposed to it here, though this logic would need to be moved behind an observer since it would likely harm performance when viewing 50-100 thumbnails at once, which some projects using payload do.

We have this intersect hook if you manage to use it https://github.com/payloadcms/payload/blob/beta/packages/ui/src/hooks/useIntersect.ts#L13

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch 2 times, most recently from 38474aa to 9dc8a5f Compare October 30, 2024 09:06
@willybrauner
Copy link
Contributor Author

@paulpopus I have rebase this branch on the last beta and implemented the observer. One new test failed but strangely, it continue to failed locally when I checkout on the previous commit.

@paulpopus
Copy link
Contributor

I think that's a flaky test so you can ignore it, now sorry to yoyo you back in this PR but we've had some performance issues with thumbnails in the bulk editor (trying to upload 50+ items at once) and I wonder if we may see the same problem here.

See this PR: #8944

So we're sticking to a similar pattern, rendering a thumbnail onto an offscreen canvas but it's done higher up so that it can be handled sequentially so it doesn't block the main UI thread.

Anyway that's to say, we could probably move the thumbnail logic into that new createThumbnail utility and move it higher up in the form manager. Thoughts?

@willybrauner
Copy link
Contributor Author

@paulpopus yes sure. Now we have this ˋcreateThumnail` function, the video thumbnail should be generated into it as for images I guess. Let me try to re implement it in the next days.

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 9dc8a5f to c9c3559 Compare November 3, 2024 14:39

// Convert the OffscreenCanvas to a Blob and free up memory
canvas
.convertToBlob({ type: 'image/jpeg', quality: 0.25 })
Copy link
Contributor Author

@willybrauner willybrauner Nov 3, 2024

Choose a reason for hiding this comment

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

type image/jpeg instead of image/png could display a full back thumbnail in case the image has a transparent background like this

before:
Screenshot 2024-11-03 at 14 55 58
after:
Screenshot 2024-11-03 at 14 56 08

@willybrauner
Copy link
Contributor Author

willybrauner commented Nov 3, 2024

@paulpopus In last commit, my logic migration inside the createThumbnail function. I refactored the base 64 url ​​generation so that it is common to all types of media.

Some notes:

  • createThumbnail now takes file and fileSrc as params. We use either one, it depends on where it's called. Inside Thumbnail component, we do not have access to file (isn't it?)
  • we should replace base64 url image type image/jpg by image/png to cover more upload case I guess. link above
  • need to fix tests

@paulpopus
Copy link
Contributor

paulpopus commented Nov 5, 2024

@willybrauner Thanks for the updates

  1. it takes both but File is whats important and used. You could make it a new prop type so file isnt required if fileSrc is provided
  2. Yeah I'm fine with that, and increase maxDimension to 420 by default so its less pixelated in some places
  3. Yep!

I tested this PR as it is so I think we're nearly ready to go, if you make the above changes and fix tests we can merge it!

Edit:

To add 4. when initially uploading a video, it's not showing the preview and just shows the document icon, there we might be able to pass File as well to create a thumbnail immediately for the user

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 2b5cd55 to ff3f6a9 Compare November 7, 2024 20:51
Comment on lines +30 to +31
fileSrc={src}
key={src}
Copy link
Contributor Author

@willybrauner willybrauner Nov 7, 2024

Choose a reason for hiding this comment

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

Due to a side effect of the new hasPreloaded state in Thumbnail

before:

Screen.Recording.2024-11-07.at.18.41.47.mov

after add src as key to force rerender:

Screen.Recording.2024-11-07.at.18.42.34.mov

@@ -157,7 +156,8 @@ export function FileSidebar() {
>
<Thumbnail
className={`${baseClass}__thumbnail`}
fileSrc={isImage(currentFile.type) ? thumbnailUrls[index] : undefined}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@paulpopus That was the reason why video thumbnail wasn't display before we saved the media.

@willybrauner
Copy link
Contributor Author

willybrauner commented Nov 7, 2024

Hi @paulpopus,

  1. I continue to use fileSrc as createThumbnail second params in some case, because File is not always provided by the parent component. fileSrc is sufficient for generate a new thumbnail according to my tests. Tell me if you find a limitation there.
  2. maxDimension has been set to 420 & mimeType to image/png
  3. I fixed the thumbnail displayed in FileSidebar and File component in order to show the preview before save the media commented here.
  4. need some time to manage new tests, because some of them test a regular src media, not a base64. It will be more complicated to test image upload outputs in DOM.

@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch 2 times, most recently from 07355d6 to d2ce3fb Compare November 7, 2024 21:33
@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from 769c397 to d2e4ebd Compare November 18, 2024 21:45
@willybrauner willybrauner force-pushed the feat/display-video-thumbnail branch from d2e4ebd to c3703b9 Compare November 18, 2024 21:47
Copy link
Contributor

This PR is stale due to lack of activity.

To keep the PR open, please indicate that it is still relevant in a comment below.

@github-actions github-actions bot added the stale label Dec 12, 2024
@willybrauner
Copy link
Contributor Author

Sorry, I couldn't adapt the e2e tests properly. But the feature has been developed and is working.

@github-actions github-actions bot removed the stale label Dec 13, 2024
@denolfe denolfe added the keep Prevents from being marked stale or auto-closed. label Dec 24, 2024
@denolfe
Copy link
Member

denolfe commented Dec 24, 2024

Thank you for your patience on this one @willybrauner . I still think this would be a good one to get in. We'll come up with a way forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keep Prevents from being marked stale or auto-closed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants