element-hq / element-hq/element-call

Not connecting to live kit (Webview)

Open
#3,379 7 comments 0 reactions 0 assignees View on GitHub
T-Defect
Dominant language
TypeScript
Stars
996
Forks
213
Avg merge
1d 8h
Merged PRs (30d)
55

Description

### Steps to reproduce

**1. Where are you starting? What can you see?**
I've prepared a simple html for rendering a widget inside a webview.
It works normally for lobby, but as soon as I try to join the call the live kit connection doesn't seem to properly initialize

```html









var widgetApi;
const iframeSrc = "__IFRAME_SRC__";
const roomId = "__ROOM_ID__";
const userId = "__USER_ID__";
const deviceId = "__DEVICE_ID__";
const widgetId = "__WIDGET_ID__";
const homeServerUrl = "__BASE_URL__";
const parentUrl = "__PARENT_URL__";
const memberPayload = `__MEMBER_PAYLOAD__`;
const callPayload = `__CALL_PAYLOAD__`;
const callMemberPayload = `__CALL_MEMBER_PAYLOAD__`;
const createRoomPayload = `__CREATE_ROOM_PAYLOAD__`;
const widgetToken = "__WIDGET_TOKEN__";

const GROUP_CALL_EVENT = "org.matrix.msc3401.call";
const GROUP_CALL_MEMBER_EVENT = "org.matrix.msc3401.call.member";

class CallWidgetDriver extends (window.mxwidgets?.WidgetDriver || WidgetDriver) {
validateCapabilities(requested) {
return Promise.resolve(requested);
}

async sendEvent(eventType, content, stateKey = null, roomId = null) {
console.log("sendEvent", { eventType, content, stateKey, roomId });
// Use REST API to send Matrix state events
const matrixUrl = homeServerUrl + "/_matrix/client/v3/rooms/" + encodeURIComponent(roomId) + "/state/" + encodeURIComponent(eventType) + "/" + encodeURIComponent(stateKey);
const response = await fetch(matrixUrl, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + widgetToken,
},
body: JSON.stringify(content),
})
const data = await response.json();
console.log('Matrix event sent:', data);
return Promise.resolve({
roomId,
eventId: data.event_id,
});
}

async sendToDevice(eventType, encrypted, contentMap) {
console.log("sendToDevice", { eventType, encrypted, contentMap });
const txnId = "txn" + Math.round(Math.random() * 1000000);
const matrixUrl = homeServerUrl + "/_matrix/client/v3/sendToDevice/" + encodeURIComponent(eventType) + "/" + txnId;
const response = await fetch(matrixUrl, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + widgetToken,
},
body: JSON.stringify(contentMap),
})
const data = await response.json();
console.log('To-device event sent:', data);
return Promise.resolve();
}

readStateEvents(eventType, stateKey, limit, roomIds = null) {
let stateEvents = [];
if (eventType === "m.room.member") {
stateEvents = JSON.parse(memberPayload);
} else if (eventType === GROUP_CALL_EVENT) {
stateEvents = JSON.parse(callPayload);
} else if (eventType === GROUP_CALL_MEMBER_EVENT) {
stateEvents = JSON.parse(callMemberPayload);
} else if (eventType === "m.room.create") {
stateEvents = JSON.parse(createRoomPayload);
}
console.log("readStateEvents", { eventType, stateKey, limit, roomIds }, stateEvents);
return Promise.resolve(stateEvents);
}

readRoomState(roomId, eventType, stateKey) {
return this.readStateEvents(eventType, stateKey, Number.MAX_SAFE_INTEGER, [roomId]);
}

async *getTurnServers() {
yield {
uris: ["stun:turn.matrix.org"],
username: "",
password: "",
};
}

async sendDelayedEvent(delay, parentDelayId, eventType, content, stateKey = null, roomId = null) {
console.log("sendDelayedEvent", { delay, parentDelayId, eventType, content, stateKey, roomId });
const matrixUrl = homeServerUrl + "/_matrix/client/v3/rooms/" + encodeURIComponent(roomId) + "/state/" + encodeURIComponent(eventType) + "/" + encodeURIComponent(stateKey) + "?org.matrix.msc4140.delay=" + encodeURIComponent(delay);
const response = await fetch(matrixUrl, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + widgetToken,
},
body: JSON.stringify(content),
});
const data = await response.json();
console.log('Matrix delayed event sent:', data);
return Promise.resolve({
roomId,
delayId: data.delay_id,
});
}

async updateDelayedEvent(delayId, action) {
console.log("updateDelayedEvent", { delayId, action });
// Use REST API to update/cancel delayed event
const matrixUrl = homeServerUrl + "/_matrix/client/unstable/org.matrix.msc4140/delayed_events/" + encodeURIComponent(delayId);
const response = await fetch(matrixUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer " + widgetToken,
},
body: JSON.stringify({ action }),
});
const data = await response.json();
console.log('Matrix delayed event updated:', data);
return Promise.resolve();
}

readRoomAccountData(eventType, roomIds = null) {
console.log("readRoomAccountData", { eventType, roomIds });
return Promise.resolve([]);
}

readRoomEvents(eventType, msgtype, limit, roomIds = null, since = null) {
console.log("readRoomEvents", { eventType, msgtype, limit, roomIds, since });
return Promise.resolve([]);
}

readEventRelations(eventId, roomId, relationType, eventType, from, to, limit, direction) {
console.log("readEventRelations", { eventId, roomId, relationType, eventType, from, to, limit, direction });
return Promise.resolve({ chunk: [] });
}

askOpenID(observer) {
console.log("askOpenID", { observer });
observer.update({state: "blocked" });
}
}

const onHangup = ev => {
console.log("onHangup");
ev.preventDefault();
widgetApi.transport.reply(ev.detail, {});
widgetApi.off("action:im.vector.hangup", onHangup);
widgetApi.removeAllListeners();
widgetApi.stop();
};
const onReady = async () => {
console.log("onReady");
widgetApi.on("action:im.vector.hangup", onHangup);
};
const onIframeLoad = () => {
const callWidget = {
id: widgetId,
creatorUserId: userId,
type: "m.custom",
url: iframeSrc,
origin: parentUrl,
waitForIframeLoad: false,
};
const widget = new mxwidgets.Widget(callWidget);
const callWidgetIframe = document.getElementById("call-widget-iframe");
callWidgetIframe.src = iframeSrc;
callWidgetIframe.onload = "";
const widgetDriver = new CallWidgetDriver();
widgetApi = new mxwidgets.ClientWidgetApi(widget, callWidgetIframe, widgetDriver);
widgetApi.once("ready", onReady);
};





```

**2. What do you click?**
Click join a call

![Image](https://github.com/user-attachments/assets/2af53f36-2f79-4555-b195-60a0563de6a6)

### Outcome

#### What did you expect?
Can see video/audio stream of current user and other patricipants
#### What happened instead?
Blank screen

### Operating system

Android

### Browser information

Webview sandbox

### URL for webapp

_No response_

### Will you send logs?

Yes

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.