-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Open
Labels
browser issueA bug or limitation of the browserA bug or limitation of the browser
Description
Description
I am building a vertical short-video feed (TikTok-style) using Svelte 5 and Video.js.
The app follows this logic:
- All videos start muted.
- The user interacts with the first video by clicking an "Unmute" button.
- This sets a global state (isMuted = false).
- Subsequent videos in the feed use this state to initialize and call .play() unmuted.
This works perfectly on Desktop. However, on Mobile Browsers (eg: iOS Safari), the unmuted autoplay works for approximately 5–10 videos, and then fails. The video stops playing with the following error: Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context.
My simplified code
<script lang="ts">
import { VolumeX, Play } from "@lucide/svelte";
import videojs from "video.js";
import "video.js/dist/video-js.css";
import { playerState } from "$lib/state/player.svelte";
let {
video,
isActive = false,
index,
}: {
video
isActive?: boolean;
index?: number;
} = $props();
let playerContainer: HTMLDivElement;
let player: any = $state(null);
let playing = $state(isActive);
function onPlaybackToggle() {
if (playing) {
player?.pause();
} else {
player?.play();
}
playing = !playing;
}
$effect(() => {
if (!document.getElementById(video.id)) {
const videoElement = document.createElement("video-js");
videoElement.style.width = "100%";
videoElement.style.height = "100%";
videoElement.style.objectFit = "cover";
videoElement.id = video.id;
playerContainer.appendChild(videoElement);
player = videojs(videoElement, {
muted: true,
controls: false,
loop: true,
playsinline: true,
preload: "none",
sources: [{ src: video.hls_url }]
});
}
});
$effect(() => {
// When the user unmutes the first video, unmute all videos
if (!playerState.mute) {
player?.muted(false);
}
});
$effect(() => {
if (isActive) {
playing = true;
player?.play();
} else {
playing = false;
player?.pause();
}
});
</script>
<div
data-index={index}
bind:this={playerContainer}
>
<button class="absolute inset-0 z-10" onclick={onPlaybackToggle}>
{#if !playing}
<Play class="h-12 w-12 text-white" />
{/if}
</button>
{#if playerState.mute}
<button onclick={() => (playerState.mute = false)}>
Unmute
</button>
{/if}
</div>
Reduced test case
Steps to reproduce
- Open the website on mobile Safari/Chrome
- Unmute the first video
- Swipe for a while
- The videos will stop playing and the error appears in Console tab
Errors
Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission
What version of Video.js are you using?
8.12.0
Video.js plugins used.
No response
What browser(s) including version(s) does this occur with?
iOS Safari, Android Chrome
What OS(es) and version(s) does this occur with?
iOS, Android
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
browser issueA bug or limitation of the browserA bug or limitation of the browser