Skip to main content

Banuba SDK Web AR Known issues

MediaStreamCapture stream freezes when browser tab becomes inactive on Safari

Starting from the 15.3 release Safari began to pause MediaStreams obtained from canvas.captureStream(), which used internally by WebAR's MediaStreamCapture, when the browser's tab is not visible. This leads to the video freeze of the WebRTC call app participant using WebAR SDK when the participant minimizes or hides the browser or the browser's tab running the app. Unfortunately, currently there is no known workaround for the issue.

Page running WebAR SDK consumes too much memory

The most likely reason is a memory leak caused by a dangling Player instance which is can not be automatically collected by the browser's GC. Consider the code:

let webcam

document.querySelector("#start").onclick = async () => {
const player = await Player.create({ clientToken: "xxx-xxx-xxx" })

await player.use((webcam = new Webcam()))
player.play()

Dom.render(player, "#webar")
}

document.querySelector("#stop").onclick = () => {
webcam.stop()

Dom.unmount("#webar")
}

Sequence of clicks on the #start followed by a click on the #stop leads to a memory leak, since the player object is still held in the browser memory. To fix it, you should call Player.destroy() once the player object is not needed anymore. The following fixed code will not cause the memory leak:

let webcam, player

document.querySelector("#start").onclick = async () => {
player = await Player.create({ clientToken: "xxx-xxx-xxx" })

await player.use((webcam = new Webcam()))
player.play()

Dom.render(player, "#webar")
}

document.querySelector("#stop").onclick = () => {
webcam.stop()

Dom.unmount("#webar")

// destroy the player object to prevent accidental memory leaks
player.destroy()
}
note

If the app has such a "start - stop - repeat" logic, you may also consider to cache the player object instead of constantly re-creating it:

let player, webcam 

document.querySelector("#start").onclick = async () => {
// reuse the player instance instead of re-creation
if (!player) player = await Player.create({ clientToken: "xxx-xxx-xxx" })

await player.use((webcam = new Webcam()))
player.play()

Dom.render(player, "#webar")
}

document.querySelector("#stop").onclick = () => {
webcam.stop()

Dom.unmount("#webar")

// no need to destroy the player since it will be reused on the next "#start" click
}

Page running WebAR SDK crashes

One of the most popular reasons is a memory leak which drains all the device RAM. Please check out the Page running WebAR SDK consumes too much memory section.

If that's not your case, please contact support and submit the issue.

Poor FPS on Safari

Starting from the WebAR SDK 1.5.0 release the Face Tracking technology has improved it's accuracy in exchange for average processing time. This change has not affected browsers with SIMD support, but reduced FPS on Safari. If Safari support is crucial for your application, use the previous, lightweight version of the Face Tracking technology on Safari:

const player = await Player.create({ clientToken: "xxx-xxx-xxx" })

// use `face_tracker_lite` instead of `face_tracker` on Safari
await player.addModule(new Module("https://cdn.jsdelivr.net/npm/@banuba/webar/dist/modules/face_tracker_lite.zip"))

Effect animations are delayed on Safari

This is a known Safari bug and for your convenience we provide you with the ready-to-go fix.

Assume you have an html page from the Getting Started section. Download the range-requests.sw.js file and put it next to the WebAR running page. To fix the Safari playback issue prepend the navigator.serviceWorker.register("./range-requests.sw.js") to the page's script and point Player to proxy video requests to the service worker:

index.html
<!DOCTYPE html>
<html>
<head>
<title>Banuba SDK Web AR</title>
</head>
<body>
<div id="webar"></div>
<script type="module">
import {
Webcam,
Effect,
Module,
Player,
Dom,
} from "https://cdn.jsdelivr.net/npm/@banuba/webar/dist/BanubaSDK.browser.esm.js"

// Fixes video range requests in Safari that cause AR effects animation delay
navigator.serviceWorker.register("./range-requests.sw.js")

const run = async () => {
const player = await Player.create({
clientToken: "PUT YOUR CLIENT TOKEN HERE",
// point the player to proxy video requests to the service worker
proxyVideoRequestsTo: "___range-requests___/",
})
await player.addModule(new Module("https://cdn.jsdelivr.net/npm/@banuba/webar/dist/modules/face_tracker.zip"))

await player.use(new Webcam())
player.applyEffect(new Effect("Rorschach.zip"))
Dom.render(player, "#webar")
}

run()
</script>
</body>
</html>

You can verify the fix with help of the Rorschach animated effect.

note

You may want to conditionally include the fix for Safari but not for the other browsers.. Check the quickstart-web demo app for a possible implementation.

note

If your app already has a ServiceWorker in your app simply import the range-requests.sw.js into it:

my-app.sw.js
importScripts("range-requests.sw.js")