Shopify video_tag loop: no HLS, so keep the product clip short

Shopify's video_tag skips the HLS source when loop is on, so the MP4 downloads whole. How to cut a short looping clip and conform its size with Sume video trim.

4 min readSume
All posts

When you render a product video with Shopify's video_tag filter and turn loop on, Shopify does not use the HLS source. Its docs say that when you upload an MP4, Shopify also generates an m3u8 file as an extra source, which lets players adapt to the viewer's connection. With loop enabled that source is skipped so the browser can download the MP4 progressively and cache it. So a looping clip is a plain file download, and its size is the cost. Keep it short.

What does video_tag do with each option?

The filter takes autoplay, loop, muted and controls, each true or false, and image_size for the poster. The output carries playsinline and preload="metadata" by default and uses the generated thumbnail as the poster. The example output lists an MP4 <source> with type="video/mp4". If the m3u8 source is not supported, the player falls back to the MP4.

Shopify.dev, Liquid filter video_tag, read 2026-10-03.
SettingWhat the page says
Default outputplaysinline, preload="metadata", aria-label, poster from the generated thumbnail
autoplay, loop, muted, controlsEach accepts true or false
image_sizeSets the poster image dimensions in pixels, for example '400x'
Uploaded MP4Shopify generates an m3u8 as an additional source for HLS
loop onHLS source not used, so the video can download progressively and be cached

Why does the loop setting change the file you should upload?

With HLS, a player can start on a low-bitrate rendition when the connection is slow. Without it, every visitor gets the one MP4 you uploaded. A 45-second brand film that loops is therefore a heavy download on a phone, while a 6-second product turn is not. The Shopify page does not give a size or length limit for the loop case, so this is an inference from how progressive download works, not a rule from Shopify.

The practical split: use the long clip with controls and no loop, where HLS is available, and a separate short silent clip for the looping hero or gallery slot. Test your own theme's output in the browser's network tab before you ship.

How do you cut that short clip with Sume?

Video trim cuts [start, end) out of one Sume-hosted clip into a new MP4. You pass start and exactly one of end or duration (0.2 to 900 seconds). The precision default, exact, is a frame-accurate re-encode with libx264 and yuv420p. audio: "drop" removes the sound, and an output object conforms width, height (each 256 to 2160) and fps (24, 25, 30 or 60). output works only with exact.

The result is a new artifact with video_url, duration_seconds and actual_start_seconds. The public rate is $0.02 per job, with no model inference, only worker ffmpeg. The source must already be on media.sume.com, so import it first with POST /v1/media-imports.

curl -X POST https://api.sume.com/v1/video-trim \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: shopify-loop-hero-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
    "start": 2,
    "duration": 6,
    "audio": "drop",
    "output": { "width": 1080, "height": 1080, "fps": 30 }
  }'

Upload it, then check the rendered tag

Upload the trimmed MP4 to the product's media, then render it with {{ media | video_tag: autoplay: true, loop: true, muted: true }}. Open the page, look at the <video> element and confirm there is no m3u8 source in a looping tag. Add image_size if the default poster is too small for your layout.

Poll the trim job through GET /v1/jobs/:id/status and GET /v1/jobs/:id/result; the default mode is async, and mode: "sync" waits up to 30 seconds. The existing walk-through covers the upload step in the admin.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume