Video Calls in Android and iOS WebViews
A Meet call runs in the web view of a native or Capacitor app, if the app lets the web view use the camera and microphone.
A web view is a browser inside your app. Meet is a normal web page, so it runs there when the web view allows the same things a browser asks for. Two ways to do it:
- Open the room link directly in the web view, with the token in the address:
https://meet.respiresoft.com/r/<name>?token=.... No embed origin is needed because nothing is framed. - Put your own page in the web view and embed Meet in an iframe from there. Add your page's origin to Embed origins in the dashboard. For a page loaded from a file or an app scheme, host the page on https instead, because a frame needs a real origin.
Android WebView#
Ask for the permissions in AndroidManifest.xml and at run time:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
// Only grant it to your own meeting host.
if (request.origin.host == "meet.respiresoft.com") request.grant(request.resources)
else request.deny()
}
}If your page frames Meet, the request comes from your page's origin. Grant it for the origin you trust.
iOS WKWebView#
Add the usage texts to Info.plist (NSCameraUsageDescription, NSMicrophoneUsageDescription) and allow inline media:
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
let webView = WKWebView(frame: .zero, configuration: config)Camera and microphone in a WKWebView need iOS 14.3 or newer. On iOS 15 and newer you can answer the permission prompt in
webView(_:requestMediaCapturePermissionFor:initiatedByFrame:type:decisionHandler:) with .grant for your own host, so people are not
asked on every call.
Capacitor and Cordova#
Add the camera and microphone permissions to the native project as above, then load the room or your embedding page. In Capacitor the
page is on https://localhost or your own server address, so add that origin to Embed origins if you frame Meet.
Limits to plan for#
- Screen sharing starting from a web view is not supported by the system. Hide the button with
?hide=screen. - Background and calls. A web view that goes to the background may stop sending video. Keep the screen awake during a call.
- Old web views. An old Android System WebView or an iOS older than 14.3 may not run calls. Offer to open the room in the system browser instead.
- Address options that help in apps:
?theme=dark|light,?lang=en,?hide=chat,people,screen,pip,leave,header.
If the call must look exactly like your app, use the headless client (preview) in your web view.