svelte
svelte copied to clipboard
The muted attribute does not render in the video tag
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
andautoplay
attributes. E.g.: https://svelte.dev/repl/9fb1ac3f9a314bd3947fb1c62cdb1dcf - Check in dev tools what is rendered
- 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
This is a serious issue, because autoplay will not work on ios without the muted attribute.
Workaround like this:
let ref!: HTMLVideoElement
onMount(() => {
ref.setAttribute("muted", `true`)
})
But still, a fix on this will be appreciated
That workaround fixed the issue for me, but would also appreciate this for iOS safari autoplay
Weirdly I have the same problem. On one page it just removes the muted from all videos... 😅 The workaround doesn't help either.
@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.
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>
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