Autoplay Video on Product Page with unmute button

Autoplay Video on Product Page with unmute button

artwithlauren
Visitor
2 0 0

Hello Shopify Community,

 

I'm running an ad campaign where people land on this page: https://www.artwithlauren.com/products/weekly-art-club-for-kids

 

I'd like for the product video to autoplay with a button to "unmute". The autoplay + unmute button works on a traditional Vimeo embed, but I haven't been able to get it to work as a product media video. 

 

I'm on the Studio 14 theme. 

 

Has anyone found a way to get this to work?

Replies 2 (2)

ThePrimeWeb
Shopify Partner
2139 616 523

Hey @artwithlauren,

 

After a few tries and some coffee later, I managed to get this. The only part I can't fix (Vimeo Limitation) is that when you click unmute, the video will restart. The only way I could control it is to write a code where the autoplay is muted, and then when you click unmute, the video reloads unmuted. 

 

 

Go to your theme's "Edit Code" Option, then in the search bar type "theme.liquid"
Above the tag "</body>" tag paste the following. Screenshot attached for reference.

<style>
deferred-media {
    position: relative !important;
}

deferred-media:has(iframe.js-vimeo:not(.unmuted)):before {
    position: absolute !important;
    content: "Unmute" !important;
    top: 10px !important;
    left: 50% !important;
    transform: translateX(-50%) !important;
    color: white !important;
    z-index: 99 !important;
    background-color: rgba(var(--color-button),var(--alpha-button-background)) !important;
    padding: 5px 10px !important;
    border-radius: 5px !important;
    cursor: pointer !important;
}
</style>

<script>
document.addEventListener('DOMContentLoaded', () => {
    document.getElementById('Deferred-Poster-Modal-38651478278441').click()
    let originalSrc;
    
    setTimeout(() => {
        originalsrc=document.querySelector('iframe.js-vimeo').src;
        document.querySelector('iframe.js-vimeo').src=originalSrc + '&background=1';
    }, 300)
    
    document.querySelector('deferred-media').addEventListener('click', function() {
        if(!document.querySelector('iframe.js-vimeo').classList.contains('unmuted')) {
            document.querySelector('iframe.js-vimeo').classList.add('unmuted');
            document.querySelector('iframe.js-vimeo').src=originalSrc;
        }  
    });
});
</script>

 

Screenshot is for reference only, the correct code to paste is the one shown above.

 

ThePrimeWeb_0-1716994422591.png

 

 

 

Note: In any case it doesn't work (or is not always working) just increase this value in increments of 300 (300,600,900, ....) until you find the sweet spot!

ThePrimeWeb_1-1716994455147.png

 

 

Was I helpful?

Buy me a coffee

🙂

Need help with your store? contact@theprimeweb.com or check out the website
Check out our interview with Shopify!
artwithlauren
Visitor
2 0 0

Hi Prime Web, thank you so much for taking a stab at this! I'm sorry that I am just now seeing your response. It did not work on my end, but maybe that is because I've edited some pages since then? 

 

Vimeo videos autoplay great when embedded directly, as you can see on this home page: https://www.artwithlauren.com/. I have it set to show a thumbnail until the video is loaded, then switch to the video. When you click the unmute botton, the video keeps playing.

 

On the product page, it's another story! It would be amazing to be able to autoplay videos when rendered via product-media.liquid. Here is an example page: https://www.artwithlauren.com/products/the-great-wave-hokusai

 

According to Vimeo, Vimeo videos need "&autoplay=1&muted=1" at the end of their embed URL to autoplay. When I upload a video to a Shopify product with those parameters added, they're removed when Shopify renders the videos. My best guess is that we need to add code to product-media.liquid to add those autoplay parameters to the end of an external video, but I'm not a shopify dev! What do you think?

 

Here's my product-media.liquid file:

{% comment %}
    Renders product media

    Accepts:
    - media: {Object} Product Media object
    - loop: {Boolean} Enable video looping (optional)
    - variant_image: {Boolean} Whether or not media is associated with a variant

    Usage:
    {% render 'product-media',
      media: media,
      loop: section.settings.enable_video_looping,
      variant_image: true
    %}
{% endcomment %}

{%- if media.media_type == 'image' -%}
  <img
    class="global-media-settings global-media-settings--no-shadow{% if variant_image %} product__media-item--variant{% endif %}"
    srcset="{%- if media.preview_image.width >= 550 -%}{{ media.preview_image | image_url: width: 550 }} 550w,{%- endif -%}
            {%- if media.preview_image.width >= 1100 -%}{{ media.preview_image | image_url: width: 1100 }} 1100w,{%- endif -%}
            {%- if media.preview_image.width >= 1445 -%}{{ media.preview_image | image_url: width: 1445 }} 1445w,{%- endif -%}
            {%- if media.preview_image.width >= 1680 -%}{{ media.preview_image | image_url: width: 1680 }} 1680w,{%- endif -%}
            {%- if media.preview_image.width >= 2048 -%}{{ media.preview_image | image_url: width: 2048 }} 2048w,{%- endif -%}
            {%- if media.preview_image.width >= 2200 -%}{{ media.preview_image | image_url: width: 2200 }} 2200w,{%- endif -%}
            {%- if media.preview_image.width >= 2890 -%}{{ media.preview_image | image_url: width: 2890 }} 2890w,{%- endif -%}
            {%- if media.preview_image.width >= 4096 -%}{{ media.preview_image | image_url: width: 4096 }} 4096w,{%- endif -%}
            {{ media.preview_image | image_url }} {{ media.preview_image.width }}w"
    sizes="(min-width: 750px) calc(100vw - 22rem), 1100px"
    src="{{ media.preview_image | image_url: width: 1445 }}"
    alt="{{ media.alt | escape }}"
    loading="lazy"
    width="1100"
    height="{{ 1100 | divided_by: media.preview_image.aspect_ratio | ceil }}"
    data-media-id="{{ media.id }}"
  >
{%- else -%}
  {%- if media.media_type == 'model' -%}
    <div class="product-media-modal__model" data-media-id="{{ media.id }}">
      <product-model class="deferred-media media media--transparent global-media-settings global-media-settings--no-shadow" style="padding-top: min(calc(100vh - 12rem), 100%)">
  {%- else -%}
    <deferred-media class="deferred-media media global-media-settings global-media-settings--no-shadow" style="padding-top: min(calc(100vh - 12rem), {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%)" data-media-id="{{ media.id }}">
  {%- endif -%}

    <button id="Deferred-Poster-Modal-{{ media.id }}" class="deferred-media__poster" type="button">
      <span class="deferred-media__poster-button motion-reduce">
        {%- if media.media_type == 'model' -%}
          {%- render 'icon-3d-model' -%}
        {%- else -%}
          {%- render 'icon-play' -%}
        {%- endif -%}
      </span>
      <img
        srcset="{% if media.preview_image.width >= 288 %}{{ media.preview_image | image_url: width: 288 }} 288w,{% endif %}
                {% if media.preview_image.width >= 576 %}{{ media.preview_image | image_url: width: 576 }} 576w,{% endif %}
                {% if media.preview_image.width >= 550 %}{{ media.preview_image | image_url: width: 550 }} 550w,{% endif %}
                {% if media.preview_image.width >= 1100 %}{{ media.preview_image | image_url: width: 1100 }} 1100w,{% endif %}
                {{ media.preview_image | image_url }} {{ media.preview_image.width }}w"
        src="{{ media | image_url: width: 550, height: 550 }}"
        sizes="(min-width: 1200px) calc((1200px - 10rem) / 2), (min-width: 750px) calc((100vw - 11.5rem) / 2), calc(100vw - 4rem)"
        loading="lazy"
        width="576"
        height="{{ 576 | divided_by: media.preview_image.aspect_ratio }}"
        alt="{{ media.preview_image.alt | escape }}"
      >
    </button>
    <template>
      {%- case media.media_type -%}
      {%- when 'external_video' -%}
        {%- assign video_class = 'js-' | append: media.host -%}
        {%- if media.host == 'youtube' -%}
          {{ media | external_video_url: autoplay: true, loop: loop, playlist: media.external_id | external_video_tag: class: video_class, loading: "lazy" }}
        {%- else -%}
          {{ media | external_video_url: autoplay: true, loop: loop | external_video_tag: class: video_class, loading: "lazy" }}
        {%- endif -%}
      {%- when 'video' -%}
        {{ media | media_tag: image_size: "2048x", autoplay: true, loop: loop, controls: true, preload: "none" }}
      {%- when 'model' -%}
        {{ media | media_tag: image_size: "2048x", toggleable: true }}
      {%- endcase -%}
    </template>

  {%- if media.media_type == 'model' -%}
      </product-model>
      <button
        class="button button--full-width product__xr-button"
        type="button"
        aria-label="{{ 'products.product.xr_button_label' | t }}"
        data-shopify-xr
        data-shopify-model3d-id="{{ media.id }}"
        data-shopify-title="title"
        data-shopify-xr-hidden
        >
        {% render 'icon-3d-model' %}
        {{ 'products.product.xr_button' | t }}
      </button>
    </div>
  {%- else -%}
    </deferred-media>
  {%- endif -%}
{%- endif -%}