svelte icon indicating copy to clipboard operation
svelte copied to clipboard

The muted attribute does not render in the video tag

Open rafaucau opened this issue 3 years ago • 9 comments

Describe the bug

The muted attribute does not render in the video tag which prevents autoplay on Safari when using client side routing.

Info from @GrygrFlzr

svelte properly sets video.muted = true, and that does mute the video, the JS property that controls the muted attribute is confusingly video.defaultMuted instead https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/defaultMuted tl;dr this attribute needs special case handling in svelte core also notable is that SSR svelte properly renders the muted attribute because it uses string concat, but DOM svelte does not

Reproduction

  • Create a video tag with muted and autoplay attributes. E.g.: https://svelte.dev/repl/9fb1ac3f9a314bd3947fb1c62cdb1dcf
  • Check in dev tools what is rendered image
  • The muted attribute is missing

When using client side routing in SvelteKit, when navigating through pages, the video will not automatically play on Safari.

Logs

No response

System Info

System:
    OS: Windows 10 10.0.19043
    CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
    Memory: 17.33 GB / 31.92 GB
  Binaries:
    Node: 14.17.3 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 7.19.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1023.0), Chromium (91.0.864.67)
    Internet Explorer: 11.0.19041.1
  npmPackages:
    svelte: ^3.38.3 => 3.38.3

Severity

annoyance

rafaucau avatar Jul 16 '21 02:07 rafaucau

This is a serious issue, because autoplay will not work on ios without the muted attribute.

jer-0 avatar Sep 14 '21 00:09 jer-0

Workaround like this:

	let ref!: HTMLVideoElement

	onMount(() => {
		ref.setAttribute("muted", `true`)
	})

But still, a fix on this will be appreciated

winston0410 avatar Jul 27 '22 22:07 winston0410

That workaround fixed the issue for me, but would also appreciate this for iOS safari autoplay

alizauf avatar Oct 13 '22 22:10 alizauf

Weirdly I have the same problem. On one page it just removes the muted from all videos... 😅 The workaround doesn't help either.

eriksachse avatar Jun 22 '23 18:06 eriksachse

@eriksachse Try this sample workaround:

<div>
  {@html '<video muted autoplay loop defaultmuted playsinline src="/animation.mp4" />'}
</div>

So you put the <video> as an HTML string.

rafaucau avatar Jun 22 '23 18:06 rafaucau

Another workaround (?), I don't have the issue if I've imported the file using Vite static imports: https://vitejs.dev/guide/assets.html#importing-asset-as-url

<script>
	import hero_mp4 from '$lib/assets/marketing/landing/hero-gif.mp4';
	const kedyou_mp4 = '/comparisons/kedyou.mp4';
</script>

<video autoplay playsinline loop muted>
	<source src={hero_mp4} type="video/mp4" />
</video>
<video autoplay playsinline loop muted>
	<source src={kedyou_mp4} type="video/mp4" />
</video>

Produces the output:

<video autoplay playsinline loop muted>
  <source src="/_app/immutable/assets/hero-gif.631030a2.mp4" type="video/mp4">
</video>
<video autoplay playsinline loop>  <!-- muted missing??? -->
  <source src="/comparisons/kedyou.mp4" type="video/mp4">
</video>

oscarhermoso avatar Jul 24 '23 14:07 oscarhermoso

Does it have something to do with this:

let videoElement = document.createElement('video')

//this will work
videoElement['controls'] = true;
videoElement['loop'] = true;

//this will NOT work
videoElement['muted'] = true;

document.body.appendChild(videoElement);

If so, than issue with browsers, when attributes are set as properties

https://jsbin.com/radarevoku/edit?html,css,js,output

andriytyurnikov avatar Nov 24 '23 00:11 andriytyurnikov