-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Hosted video support in video section #2248
Conversation
04b93dc
to
1fd71bb
Compare
0355cdb
to
1fd71bb
Compare
Hello @kmeleta, we add some little updates on the settings. They are listed here.
Also this might be tricky so if this is too complicated, don't hesitate to flag. But it feels like the preview from the default youtube URL gives a lot of focus on this option vs the shopify hosted video option. is it possible to remove the default url in the URL field, and the preview under? We would still need to keep the placeholder image in the page. |
Hello, some notes and a few changes (sorry about that Ken)
@ludo I think settings right above Shopify Hosted Video should stay functional, like Enable video looping. Ken is exploring a setting to play the video automatically when loading the page, if we add it it would be also there. Full-width and color options are most likely layout settings, we would likely keep them together below the content. Once we have the new semantic settings, we will have a layout heading to make them more obvious! Also the new color setting is gonna be a lot more prominent, we don’t want it to high once we have it. After discussion with Kim and Dan, we don’t want to add tons of settings. If video is autoplayed, sound is off by default. Or else, sound is on since you decided to start it! For the autoplay setting / positon / naming, I am still checking with Katy. |
👋 We're exploring additional functionality here. No need for further reviewing until updated. cc @ludoboludo |
b7901ee
to
d6b66a0
Compare
f066c84
to
b8f121a
Compare
Reviews can resume. Recent changes have mostly been to settings content, so please give attention to those before I request translations. |
position: relative; | ||
padding-bottom: 56.25%; | ||
padding-bottom: calc(var(--ratio-percent) - var(--media-border-width)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I remember playing with that. I do think it's a partial pixel issue so not sure what we can do. I'll revisit quickly though and see if a trivial fix presents itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I found out it's because of very slight differences in aspect ratio between the cover and video. Which apparently can happen even with the default cover images generated in the admin. I decided to compare the two ratios and if the difference between them is insignificant I set apply an object-fit: cover to hide any difference. We wouldn't want to apply the cover for larger differences as we don't want significant portions of the video cropped. Curious what you think about this approach (see video.liquid) 3141a40
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎩 on MacOS Chrome, Firefox and Safari + iOS Safari
sections/video.liquid
Outdated
></iframe> | ||
{{ section.settings.video | ||
| video_tag: | ||
image_size: "2048x", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a big image (by file size) potentially. Is there any way to serve the poster responsively? Do we even need this poster if we're using the deferred-media
component?
One idea might be if the image size could be page width if the full_width
setting is false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.. honestly I was hoping that wouldn't have to be loaded.. I see now that it is, even if I remove image_size and pass poster: ""
.
It renders this dom but that fallback image still loads even when not displayable..
<video>
<source>
<img /> <!-- fallback content when no html video support -->
</video>
So I guess the 2 options I see
A) Keep our current responsive cover image implementation and pass a very small, inconsequential image_size to the video_tag for now.
B) Refactor the hosted video cover image to use the same fixed size that the video_tag and poster attribute will. Though this will probably require I not use image_tag or else we'll probably end up loading both /myimage.png&width=2000
and /myimage_2000x.png
It's unfortunate there doesn't appear to be a way to support dynamic image sizes, but option B may be the way to go as it might have the benefit of preventing the flashing you mentioned in another comment. I'll probably go ahead and experiment with that, but let me know what you think or if it seems like I'm missing something.
Edit: not actually sure how/if I can ensure the image sources always match..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @ludoboludo ^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ended up just reducing the image size passed to the video_tag (value is debatable). I'm ok with this (for now) because that image won't impact initial load with deferred rendering. That said, I don't have too much of a problem not using the video_tag if would allow us to better control and repurpose the images used. So if anyone else agrees with that I can look at making that change. Though it's probably worth noting that the poster attr on video I believe requires one fixed image src afaik.
Also happy to open a follow up issue to further consider other options regardless of the outcome here.
{{ section.settings.video | ||
| video_tag: | ||
image_size: "2048x", | ||
autoplay: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be related to above comment, but do you notice a little flicker when you click the play button? It happens very quickly but seems like the screen goes white for a frame. Comments above are more nits/style stuff but this seems noticeable for buyers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you had identified this already, but during tophatting I found that on Safari I had to click play twice: once on the deferred media and again on the player. True on MacOS and iOS safari.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flicker appears to be from a small delay between when the player is rendered and when the player can show the first frame or poster image. I mention a possible fix in your comment about the poster image.
Otherwise we'd probably need to make an exception for this type of video and not defer rendering the fragment so that it can load that first frame before the cover is clicked. Or possibly delay the removal of the cover image until the player fires the loadeddata
event. But then you get into a scenario where there could be a perceived lag upon action.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then you get into a scenario where there could be a perceived lag upon action.
I'd like to catch up on this if I can help to test if we could use some of our perceived performance UI (loader) in this use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the deferred media behaviour get us in terms of performance for hosted video?
The deferred media pattern is great for youtube and vimeo since their video players are very large (lots of JS). For hosted video though I believe we are using the default browser controls. Do we need it for hosted video? It might solve some problems with the flicker and double-clicking play on Safari.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deferred media pattern is great for youtube and vimeo since their video players are very large
Correct. Using deferred media was mostly to take advantage of existing functionality and styling. If I were to not defer the rendering, I'd also use preload="metadata"
on the video to avoid any flicker. This will load that poster/fallback image I can't exclude from the video_tag and it will preload a certain amount of the video itself so it can at least show the first frame (usually ~1kb but sometimes it just starts buffering for some reason). So inherently there will be a slight performance hit that deferred media aims to avoid. If I don't preload anything, the flicker will occur regardless.
@melissaperreault it could be worth us pairing on this and considering the severity and our options. We could also just mitigate the flicker as much as I can for now and follow up with an enhancement if we feel we need to. Youtube and vimeo also flash a blank background before the first frame loads. Here's a throttled/slow-mo comparison https://screenshot.click/hosted-yt-comparison.mp4 of the best case scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Paired with @melissaperreault on this. We decided the flicker isn't blocking, but we did set background of the video player to pure black. We find this slightly less jarring and should be a familiar experience to the youtube video loading sequence.
I experimented with non-deferred loading but didn't feel the benefit was worth the performance impact or the code exceptions.
I also tried changing the z-index of the cover image instead of hiding it. This actually worked well, but only if the aspect ratio of the video and cover image were the same.
I will likely be opening an issue for follow up investigations/improvements as a result of this PR and will make mention all this.
91b3232
to
588d4cd
Compare
588d4cd
to
3141a40
Compare
></iframe> | ||
{{ section.settings.video | ||
| video_tag: | ||
image_size: "1100x", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what makes sense for this fixed value. In the video section, you'd most likely only see this image displayed if your browser or device prevents the autoplay from happening, or if your browser doesn't support html video or the provided formats. So I'm not sure how much it's worth increasing the file size.
The only other use of native video in the theme we pass 2048x
as I originally had. Not actually sure what was used to determine that value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it was tied to the max-width we could get to 🤔 But since the max is 1600
that would be 32000
😬
We defaulted to 1024 x 2 for most common resolutions maybe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I could see that. That could probably be smarter logic now, but I also wouldn't think we should go higher than what it is anyway..
Hi ! I did not read everything, but we have implemented that on our themes as well. here, I decided to use preload="metadata" everywhere. This indeed improves the user experience by making the video faster to load as first few frames are already loaded. However we have, as alwyas, received complains from merchants using ton shit of video and having their performance scores "apparently" impacted. What I am thinking to do is switching to preload none, and using an InteresectionObserver to switch to metadata like 500 or 600px before the video appears. Have you considered this approach? |
Thanks for that insight @bakura10. I could certainly see an approach like that being useful. I briefly thought about preloading the video metadata upon hovering on the section, to get even a small jump on the loading. We'll just want to fully consider the options and decide on something that will apply well to product media and potential future uses of video. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🎩 Let's make that follow-up ticket to look into skipping the deferred-media
component for hosted videos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good 👍
Just some small comments/nitpicks but ready to approve after that
controls: true, | ||
muted: false | ||
}} | ||
{%- endif -%} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty cool that without JS the native video still works 👍
sections/video.liquid
Outdated
{{ section.settings.video | ||
| video_tag: | ||
image_size: "1100x", | ||
autoplay: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The video does autoplay though. It doesn't seem like it happen all the time but it will. I wonder if we should default not to autoplay here.
I know we don't want to overthink the no js behaviour, but I think it's a safer bet to not autoplay since it's also not muted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh for just the no-js, yeah you're right, good call. Removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Ken!! 🎉
Sharing some observations that are not blockers. Mainly notes for us to acknowledge and one that I'll create an issue for to follow up on.
-
I am sad to remember that Youtube URL videos require users to tap twice on touch devices. 😢
-
When the "cover image" don't have the same aspect ratio of the video, only the Vimeo video will wear the light grey background. I think it's okay due to how the player and control will align.
-
I'd love to have the ability to replace back my cover image from my Shopify-hosted video instead of being required to re-upload it again, if I tested a new cover. We offer no way to dismiss that change. 😢
-
We need to fix how an image will preview at the section UI thumbnail level. Right now, it doesn't display the "cover image" for the Shopify-hosted video when it does for the embed one. And if you add a cover image under the embed cover image setting, the preview won't match the right video displayed. Video reference 1, video reference 2
@melissaperreault I think it is doable, right here: |
@ludoboludo yeah, thanks for the video. That process works great, but I meant giving the ability to pick back that first cover image that is automatically pulled from the Shopify-hosted video. We can't revert back if you replace that original cover image. The only workaround I found with Ken's help is downloading the video from the Files and re-uploading it to get back that original cover image. It's known and shared with the team. We'll keep waiting to see how merchants will use. 🙏 |
For info, I have experimented with a preload none + intersection observer to change to preload meta when the video is nearing the viewport. It works like a charm. Best of both worlds ;). This really added only 3 lines of code to our own video component, so it is worthwhile. |
eac31bf
Thanks @melissaperreault
Unfortunately that appears the case. I believe I found it could be possible to avoid this, just not with our current embed approach. Which we chose for its lightweight. Youtube is fairly opinionated about mobile autoplay. On the bright side, I was able to improve this behavior for both vimeo and youtube which previously required a second click even on desktop.
Yeah vimeo handles that case a little differently. That light grey background on the iframe is from the vimeo styles, just as the youtube player uses black, but vimeo keeps the player ui tied to the actual playable area so it creates the appearance that maybe that grey background isn't a part of the embedded video. Not ideal, but hopefully an edge case that won't be noticed too often.
I agree, but it's also possible we have more of a use case for that flow as testers than most users would in real world use. Would be interested in what that team thinks about that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small nitpick but otherwise 👍
{% endif %} | ||
> | ||
<button | ||
id="Deferred-Poster-Modal-{{ section.settings.video_url.id }}" | ||
id="Deferred-Poster-Modal-{{ video_id }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick:
id="Deferred-Poster-Modal-{{ video_id }}" | |
id="Deferred-Poster-{{ video_id }}" |
No need to make this change, I was just noticing that in our JS the selector is this.querySelector('[id^="Deferred-Poster-"]')
and since it's not a modal we could adjust it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not going to change it now, but I added this to the video section improvements ticket so it can get updated in follow ups.
Hosted video support in video section (Shopify#2248)
* shopify/main: update version and release notes (Shopify#2327) add zoom on hover and show spinner when image loading (Shopify#2314) Try more universal rich text controls (Shopify#2085) Hosted video support in video section (Shopify#2248)
* New hosted video setting and liquid improvements * Setting and content updates * Settings updates * More setting/content changes * Another one * Fix mute and border radius * Aspect ratio fixes and general improvements * Safari autoplay fix * Update no-js experience * Update 20 translation files * Whitespace * Prevent no-js autoplay --------- Co-authored-by: translation-platform[bot] <34770790+translation-platform[bot]@users.noreply.github.com>
PR Summary:
Added support for Shopify-hosted video to the existing Dawn video section. Also added a video looping setting and other video section improvements.
Why are these changes introduced?
Fixes #2247
Previously our video section has only supported
video_url
, effectively allowing embedded youtube or vimeo videos. Now video files can be uploaded directly to the admin and surfaced in editor using the newvideo
setting type.We've also added a video looping setting that will apply to both video types and updated some setting content.
With these changes we've also fixed the issue where youtube and vimeo videos would require 2 clicks to play. Now they should correctly autoplay (on desktop at least) after clicking the cover image to load the video.
What approach did you take?
Implemented
video
type setting in the video section alongside the existingvideo_url
setting. Because the new and existing settings need to exist at the same time, the hosted video values will override anything from the existing settings, including the video source, description (alt text), and poster image. From a UX perspective this is not ideal, but is technically necessary for the time being. The hosted video is rendered in the liquid via thevideo_tag
.To minimize complexity and redundant code in the section I captured some values in variables that are shared between the hosted video and video url cases, like poster image, alt text, id, etc. I also cleaned up the poster image aspect ratio code to ensure consistent display between video types.
Decision log
- Allow cover image to explicitly override cover from admin
- Allowing the video url settings to have an effect on a hosted video could add confusion and break the single source of truth from the admin
- Allowing the video url desc setting serve as a fallback could make it more likely that alt text is added even if from the wrong place, but this could enforce a bad pattern
Visual impact on existing themes
New settings will appear in the editor, but there should be no visual impact on existing themes.
Testing steps/scenarios
Demo links
Checklist