How can I autoplay a product video and hide controls on Dawn 2.0?

Solved

How can I autoplay a product video and hide controls on Dawn 2.0?

OllieTP
Tourist
7 1 8

Hi There, 

 

I'm using Dawn and have a video as the featured media for a key product. 

 

I'm struggling to autoplay this video & hide controls. I've tried updating product-media.liquid as shown below to add muted & autoplay tags, but no luck. The link in question is https://velvetiser.myshopify.com/products/velvetiser-starter-kit password VUSA23

 

Can anyone help me with this (for both desktop & mobile!)

 

Thanks in advance, 

 

Ollie

<template>
      {%- case media.media_type -%}
      {%- when 'external_video' -%}
        {%- assign video_class = 'js-' | append: media.host -%}
        {%- if media.host == 'youtube' -%}
          {{ media | external_video_url:  muted: true, autoplay: true, loop: loop, playlist: media.external_id | external_video_tag: class: video_class, loading: "lazy" }}
        {%- else -%}
          {{ media | external_video_url: muted: true, autoplay: true, loop: loop | external_video_tag: class: video_class, loading: "lazy" }}
        {%- endif -%}
      {%- when 'video' -%}
        {{ media | media_tag: image_size: "2048x", muted: true, autoplay: true, loop: loop, preload: "auto" }}
      {%- when 'model' -%}
        {{ media | media_tag: image_size: "2048x", muted: true, autoplay: true, loop: loop, preload: "auto" }}
      {%- endcase -%}
    </template>
Accepted Solution (1)

OllieTP
Tourist
7 1 8

This is an accepted solution.

For anyone who is stumbling across this and looking for a solution, I ended up using an online converter to convert the video file to webp. This has the effect of making the video load as if it was an image and autoplaying in all browsers I've tested. You can add as many of these files to your products as you want. Works perfectly!

 

Search for mp4 to webp converter to convert your files 🙂

View solution in original post

Replies 21 (21)

PageFly-Victor
Shopify Partner
7865 1785 3101

Hi @OllieTP,

 

You can try this code by following these steps: 

Step 1: Go to Online Store->Theme->Edit code.

Step 2: Search file theme.liquid

Step 3: Paste the below code at bottom of the file -> Save

{% if template contains "product" %}
<script>
window.addEventListener('DOMContentLoaded',(event)=>{
document.querySelectorAll('.deferred-media__poster-button.motion-reduce')[0].click()
});
</script>
{% endif %}



Hope my solution works perfectly for you!

Best regards,

Victor | PageFly

OllieTP
Tourist
7 1 8

Hey Victor, 

 

Thanks very much for helping. 

 

I like the solution, and it works on Desktop, but unfortunately the behaviour on mobile is different. The first click seems to 'select' the video, a further click is required to start playback but content remains hidden behind controls until a third click (not on the play button) to hide the controls. 

 

Here's a pic, as behaviour on mobile device is different to responsive mode on desktop

 

Image.jpeg

 

 

PageFly-Victor
Shopify Partner
7865 1785 3101

Hi@OllieTP ,
I just checked your site on the mobile but I see the video is autoplay. let's confirm your feedback . Thanks

OllieTP
Tourist
7 1 8
Hey Victor,

Yes I added a second click function in which means it auto plays now (🥳) but you’ll see that it auto plays behind the controls and with a strange border like the whole video is selected? Shown in the image too.

A manual click on the video (away from the centre where the play/pause is) fixes both, but I’ve not been able to achieve this. Any ideas??

Ollie
PageFly-Victor
Shopify Partner
7865 1785 3101

I think If I can have access store I will check it carefully. let me know your feedback. Thanks

masahirosoccerg
Visitor
2 0 0

Hey would you mind helping me out with the same issue? I'm trying to make the video autoplay on this product page and it works on desktop but does not seem to autoplay on mobile:

OBYO | Mohair Crewneck Sweater – O BY O STORE (5c46e7.myshopify.com)

muskinandbeauty
Visitor
1 0 0

Hey @PageFly-Victor i am having the same issue, in the product gallery my product video is unable to auto play i tried everything but nothing's working. Can you help me? I want the video to auto play in both desktop and mobile.

OllieTP
Tourist
7 1 8

This is an accepted solution.

For anyone who is stumbling across this and looking for a solution, I ended up using an online converter to convert the video file to webp. This has the effect of making the video load as if it was an image and autoplaying in all browsers I've tested. You can add as many of these files to your products as you want. Works perfectly!

 

Search for mp4 to webp converter to convert your files 🙂

LVC
Tourist
7 1 6

I found a slightly better solution that uses product video files instead of .webp which is basically the same as .gif - slow loading and not that pretty.

 

In my case, I plan to add a few videos here and there as first product media, with "Show second image on hover" working as well, if needed.

 

Theme is Dawn 9.0.0

1) Open "card-product.liquid" in Theme code editor. Locate line 52 and replace the two "if" statements that end right before <div class="card__content"> with the following:

 

        {%- if card_product.featured_media -%}
          <div class="card__media">
            <div class="media media--transparent media--hover-effect">
              {% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
{% liquid
assign alternateMediaIsVideo = false
if card_product.featured_media.media_type == 'video'
assign alternateMediaIsVideo = true
endif
%}

{% unless alternateMediaIsVideo %}

              <img
                srcset="
                  {%- if card_product.featured_media.width >= 165 -%}{{ card_product.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 360 -%}{{ card_product.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 533 -%}{{ card_product.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 720 -%}{{ card_product.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 940 -%}{{ card_product.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 1066 -%}{{ card_product.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
                  {{ card_product.featured_media | image_url }} {{ card_product.featured_media.width }}w
                "
                src="{{ card_product.featured_media | image_url: width: 533 }}"
                sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                alt="{{ card_product.featured_media.alt | escape }}"
                class="motion-reduce"
                {% unless lazy_load == false %}
                  loading="lazy"
                {% endunless %}
                width="{{ card_product.featured_media.width }}"
                height="{{ card_product.featured_media.height }}"
              >
{% else %}
{{
  card_product.featured_media
  | video_tag:
  controls: false,
  muted: true,
  loop: true,
  autoplay: true,
  image_size: '1066x',
  class: 'motion-reduce'
}}
{% endunless %}
              {% comment %}theme-check-enable ImgLazyLoading{% endcomment %}

              {%- if card_product.media[1] != null and show_secondary_image -%}
{% liquid
assign alternateMediaIsVideo = false
if card_product.media[1].media_type == 'video'
assign alternateMediaIsVideo = true
endif
%}

{% unless alternateMediaIsVideo %}
                <img
                  srcset="
                    {%- if card_product.media[1].width >= 165 -%}{{ card_product.media[1] | image_url: width: 165 }} 165w,{%- endif -%}
                    {%- if card_product.media[1].width >= 360 -%}{{ card_product.media[1] | image_url: width: 360 }} 360w,{%- endif -%}
                    {%- if card_product.media[1].width >= 533 -%}{{ card_product.media[1] | image_url: width: 533 }} 533w,{%- endif -%}
                    {%- if card_product.media[1].width >= 720 -%}{{ card_product.media[1] | image_url: width: 720 }} 720w,{%- endif -%}
                    {%- if card_product.media[1].width >= 940 -%}{{ card_product.media[1] | image_url: width: 940 }} 940w,{%- endif -%}
                    {%- if card_product.media[1].width >= 1066 -%}{{ card_product.media[1] | image_url: width: 1066 }} 1066w,{%- endif -%}
                    {{ card_product.media[1] | image_url }} {{ card_product.media[1].width }}w
                  "
                  src="{{ card_product.media[1] | image_url: width: 533 }}"
                  sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                  alt=""
                  class="motion-reduce"
                  loading="lazy"
                  width="{{ card_product.media[1].width }}"
                  height="{{ card_product.media[1].height }}"
                >
  {% else %}
{{
  card_product.media[1]
  | video_tag:
  controls: false,
  muted: true,
  loop: true,
  autoplay: true,
  image_size: '1066x',
  class: 'motion-reduce'
}}
{% endunless %}
              {%- endif -%}
            </div>
          </div>
        {%- endif -%}

 

The added code pieces are without indentation for better overview.

 

2) In Theme customization, open Default Collection and add a new "Custom Liquid" section. Enter the following at the top code field (not the css field):

 

<style type="text/css">
.media.media--hover-effect > video + video,
.media.media--hover-effect > video + img,
.media.media--hover-effect > img + video {
  opacity: 0;
}
  
.card__media .media video {
  height: 100%;
  object-fit: cover;
  object-position: center center;
  width: 100%;
}

@media screen and (min-width: 990px) {
  .card .media.media--hover-effect > video:only-child,
  .card-wrapper .media.media--hover-effect > video:only-child {
    transition: transform var(--duration-long) ease;
  }

  .card:hover .media.media--hover-effect > video:first-child:only-child,
  .card-wrapper:hover .media.media--hover-effect > video:first-child:only-child {
    transform: scale(1.03);
  }

  .card-wrapper:hover
    .media.media--hover-effect
    > video:first-child:not(:only-child) {
    opacity: 0;
  }

 .card-wrapper:hover .media.media--hover-effect > video + video,
 .card-wrapper:hover .media.media--hover-effect > video + img,
 .card-wrapper:hover .media.media--hover-effect > img + video {
  opacity: 1;
  transition: transform var(--duration-long) ease;
  transform: scale(1.03);
  }
}
</style>

 

 

Remember to set the "section padding" sliders to zero, and you're done.

 

There might be some redundant css that needs testing and transition animations need some tweaking. Other than that, different order variations of product images and videos are loading, autoplaying and looping. 

 

Good luck!

Rob76
Visitor
2 0 0

Works great!  Thank you so much.

daveamor
Tourist
3 1 0

This code works perfect. Actually the first code is enough, we dont have to create a custom liquid. Thank you again

devToasted
Shopify Partner
2 0 0

This is awesome and works good. Thanks for posting this

CBE
Visitor
1 0 0

Thanks for your work!

I made some changes based on your work that will work in the following way:

1. We can put the video in whatever location we want, it also doesn't matter where we put the images

2. What happens is we check if the first media item is an image, if not we search through the list of media items until we see an image and assign that to a local value

3. For the video we do something similair but we search through the media list until we find an item that is a video, we also assign that to a local value

4. We use these values to decide what needs to be displayed as "featured" item and as "hovered" item

5. I added some javascript to make sure the videos only play when you hover over the product and that it will reset every time in order to play from the start on each hover

 

This is the code in the card_product.liquid file

 

under the `assign ratio` section around line 28 we will add some new assigns. This block will look like this:

 

{%- liquid
assign ratio = 1
if featuredImage and media_aspect_ratio == 'portrait'
assign ratio = 0.8
elsif featuredImage and media_aspect_ratio == 'adapt'
assign ratio = featuredImage.aspect_ratio
endif
if ratio == 0 or ratio == null
assign ratio = 1
endif
assign featuredImage = featuredImage
if featuredImage.media_type != 'video'
for item in card_product.media
if item.media_type == 'image'
assign featuredImage = item
break
endif
endfor
endif
assign featuredVideo = nil
for item in card_product.media
if item.media_type == 'video'
assign featuredVideo = item
break
endif
endfor
-%}

 

 

now do a search and replace on the page by using ctrl + f

enter: card_product.featured_media
and for replace: featuredImage

 

then replace the code for the first div below the first {%- if featuredImage -%} you find (should be around line 72 after adding the above code)

so replace the entire div with the code below

 

 

<div class="card__media{% if image_shape and image_shape != 'default' %} shape--{{ image_shape }} color-{{ settings.card_color_scheme }} gradient{% endif %}">
            <div class="media media--transparent media--hover-effect">
              {% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
                <img
                  srcset="
                    {%- if featuredImage.width >= 165 -%}{{ featuredImage | image_url: width: 165 }} 165w,{%- endif -%}
                    {%- if featuredImage.width >= 360 -%}{{ featuredImage | image_url: width: 360 }} 360w,{%- endif -%}
                    {%- if featuredImage.width >= 533 -%}{{ featuredImage | image_url: width: 533 }} 533w,{%- endif -%}
                    {%- if featuredImage.width >= 720 -%}{{ featuredImage | image_url: width: 720 }} 720w,{%- endif -%}
                    {%- if featuredImage.width >= 940 -%}{{ featuredImage | image_url: width: 940 }} 940w,{%- endif -%}
                    {%- if featuredImage.width >= 1066 -%}{{ featuredImage | image_url: width: 1066 }} 1066w,{%- endif -%}
                    {{ featuredImage | image_url }} {{ featuredImage.width }}w
                  "
                  src="{{ featuredImage | image_url: width: 533 }}"
                  sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                  alt="{{ featuredImage.alt | escape }}"
                  class="motion-reduce"
                  {% unless lazy_load == false %}
                    loading="lazy"
                  {% endunless %}
                  width="{{ featuredImage.width }}"
                  height="{{ featuredImage.height }}"
                >
              {% comment %}theme-check-enable ImgLazyLoading{% endcomment %}

              {%- if card_product.media[1] != null or featuredVideo and show_secondary_image -%}
                {%- unless featuredVideo != nil -%}
                  <img
                    srcset="
                      {%- if card_product.media[1].width >= 165 -%}{{ card_product.media[1] | image_url: width: 165 }} 165w,{%- endif -%}
                      {%- if card_product.media[1].width >= 360 -%}{{ card_product.media[1] | image_url: width: 360 }} 360w,{%- endif -%}
                      {%- if card_product.media[1].width >= 533 -%}{{ card_product.media[1] | image_url: width: 533 }} 533w,{%- endif -%}
                      {%- if card_product.media[1].width >= 720 -%}{{ card_product.media[1] | image_url: width: 720 }} 720w,{%- endif -%}
                      {%- if card_product.media[1].width >= 940 -%}{{ card_product.media[1] | image_url: width: 940 }} 940w,{%- endif -%}
                      {%- if card_product.media[1].width >= 1066 -%}{{ card_product.media[1] | image_url: width: 1066 }} 1066w,{%- endif -%}
                      {{ card_product.media[1] | image_url }} {{ card_product.media[1].width }}w
                    "
                    src="{{ card_product.media[1] | image_url: width: 533 }}"
                    sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                    alt=""
                    class="motion-reduce"
                    loading="lazy"
                    width="{{ card_product.media[1].width }}"
                    height="{{ card_product.media[1].height }}"
                  >
                {%- else -%}
                    {{
                      featuredVideo
                      | video_tag:
                        controls: false,
                        muted: true,
                        loop: true,
                        autoplay: false,
                        image_size: '1066x',
                        class: 'motion-reduce'
                    }}
                {%- endunless -%}
              {%- endif -%}
            </div>
          </div>

 

 

In order to make sure the autoplay works in the way as described in point 5 we add the following to the bottom of the page

 

 

  <script>
    document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.card').forEach((video) => {
      video.addEventListener('mouseover', function() {
        var playItem = this.querySelector('video');
        playItem.currentTime = 0;
        playItem.play();
      });

      video.addEventListener('mouseout', function() {
        this.querySelector('video').pause();
      });
    });
    });
  </script>

 

 

The css part is the same as in LVC's answer

AlexCPerky
Excursionist
10 0 3

This is great & just what I was after. Thanks very much & super appreciation : )

cansu3351
Visitor
1 0 0

Hello, I tried this, it works very well, but when I apply the code you gave in the first place, the products cannot be clicked. That is, only the product picture and video are visible on the home page, but I cannot open the product to see other product photos. Additionally, features such as product name, price, etc. were also deleted with this code. What is more accurate about this?

LVC
Tourist
7 1 6

Recent Dawn theme updates have rendered my solution obsolete, and I'm currently trying this one by Pete Soc, that I found on the other post:
https://github.com/peterbrunton/shopify-gists/blob/main/product-card-rollover-video

ryeung316
Shopify Partner
4 0 1

This was such a simple and easy fix! Thanks @OllieTP for the pro tip... I used https://tinywow.com/video/to-webp to achieve the conversion from mp4 to webp but unfortunately, I noticed the file size doubled from 2mb to 4.15mb...

It does auto-play AND it shows the 2nd line image (our video webp) now upon desktop hover all without any code!

dannygarcia
Visitor
1 0 0

Thanks a ton @OllieTP for such incredible and EASY solution!!! I thought that webp is for static only. It took me several days to find so easy solution for this problem. Thank you so much! You are my hero! No need to mess with video and coding now.

ireneeeeee
Visitor
1 0 0

This totally worked! Thanks so much!

Rajat4757
Visitor
1 0 0

Hi, How to upload webp video in the image banner /Video banner for home page?

seedlingstudio
Shopify Partner
2 0 0

This is by far the easiest solution!! Thanks so much, I had no idea WebP preserves motion. I think the video solution with code is valuable for some use cases, but the WebP route worked perfectly for what I needed – higher quality and about half the size of my optimized gifs. 🙂