1e41f4b71Sopenharmony_ci# Holding a Video Conference with WebRTC 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciThe **\<Web>** component can start a camera and microphone by calling **navigator.mediaDevices.getUserMedia()**, a standard W3C API, in JavaScript. To call this API, you need to declare the **ohos.permission.CAMERA** and **ohos.permission.MICROPHONE** permissions. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci The **constraints** parameter in the API is a **MediaStreamConstraints** object that specifies the types of media to request. It contains two members: **video** and **audio**. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciIn the following example, when a user clicks the button for enabling the camera on the frontend page (**index.html**), the **\<Web>** component starts the camera and microphone. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci- Application code: 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci ```ts 12e41f4b71Sopenharmony_ci // xxx.ets 13e41f4b71Sopenharmony_ci import { webview } from '@kit.ArkWeb'; 14e41f4b71Sopenharmony_ci import { abilityAccessCtrl } from '@kit.AbilityKit'; 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci @Entry 17e41f4b71Sopenharmony_ci @Component 18e41f4b71Sopenharmony_ci struct WebComponent { 19e41f4b71Sopenharmony_ci controller: webview.WebviewController = new webview.WebviewController() 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci aboutToAppear() { 22e41f4b71Sopenharmony_ci // Enable web frontend page debugging. 23e41f4b71Sopenharmony_ci webview.WebviewController.setWebDebuggingAccess(true); 24e41f4b71Sopenharmony_ci let atManager = abilityAccessCtrl.createAtManager(); 25e41f4b71Sopenharmony_ci atManager.requestPermissionsFromUser(getContext(this), ['ohos.permission.CAMERA', 'ohos.permission.MICROPHONE']) 26e41f4b71Sopenharmony_ci .then(data => { 27e41f4b71Sopenharmony_ci let result: Array<number> = data.authResults; 28e41f4b71Sopenharmony_ci let hasPermissions1 = true; 29e41f4b71Sopenharmony_ci result.forEach(item => { 30e41f4b71Sopenharmony_ci if (item === -1) { 31e41f4b71Sopenharmony_ci hasPermissions1 = false; 32e41f4b71Sopenharmony_ci } 33e41f4b71Sopenharmony_ci }) 34e41f4b71Sopenharmony_ci if (hasPermissions1) { 35e41f4b71Sopenharmony_ci console.info("hasPermissions1"); 36e41f4b71Sopenharmony_ci } else { 37e41f4b71Sopenharmony_ci console.info(" not hasPermissions1"); 38e41f4b71Sopenharmony_ci } 39e41f4b71Sopenharmony_ci }).catch(() => { 40e41f4b71Sopenharmony_ci return; 41e41f4b71Sopenharmony_ci }); 42e41f4b71Sopenharmony_ci } 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci build() { 45e41f4b71Sopenharmony_ci Column() { 46e41f4b71Sopenharmony_ci Web({ src: $rawfile('index.html'), controller: this.controller }) 47e41f4b71Sopenharmony_ci .onPermissionRequest((event) => { 48e41f4b71Sopenharmony_ci if (event) { 49e41f4b71Sopenharmony_ci AlertDialog.show({ 50e41f4b71Sopenharmony_ci title: 'title', 51e41f4b71Sopenharmony_ci message: 'text', 52e41f4b71Sopenharmony_ci primaryButton: { 53e41f4b71Sopenharmony_ci value: 'deny', 54e41f4b71Sopenharmony_ci action: () => { 55e41f4b71Sopenharmony_ci event.request.deny(); 56e41f4b71Sopenharmony_ci } 57e41f4b71Sopenharmony_ci }, 58e41f4b71Sopenharmony_ci secondaryButton: { 59e41f4b71Sopenharmony_ci value: 'onConfirm', 60e41f4b71Sopenharmony_ci action: () => { 61e41f4b71Sopenharmony_ci event.request.grant(event.request.getAccessibleResource()); 62e41f4b71Sopenharmony_ci } 63e41f4b71Sopenharmony_ci }, 64e41f4b71Sopenharmony_ci cancel: () => { 65e41f4b71Sopenharmony_ci event.request.deny(); 66e41f4b71Sopenharmony_ci } 67e41f4b71Sopenharmony_ci }) 68e41f4b71Sopenharmony_ci } 69e41f4b71Sopenharmony_ci }) 70e41f4b71Sopenharmony_ci } 71e41f4b71Sopenharmony_ci } 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci ``` 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci- Code of the **index.html** page: 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci ```html 78e41f4b71Sopenharmony_ci <!-- index.html --> 79e41f4b71Sopenharmony_ci <!DOCTYPE html> 80e41f4b71Sopenharmony_ci <html> 81e41f4b71Sopenharmony_ci <head> 82e41f4b71Sopenharmony_ci <meta charset="UTF-8"> 83e41f4b71Sopenharmony_ci </head> 84e41f4b71Sopenharmony_ci <body> 85e41f4b71Sopenharmony_ci <video id="video" width="500px" height="500px" autoplay="autoplay"></video> 86e41f4b71Sopenharmony_ci <canvas id="canvas" width="500px" height="500px"></canvas> 87e41f4b71Sopenharmony_ci <br> 88e41f4b71Sopenharmony_ci <input type="button" title="HTML5 Camera" value="Enable Camera" onclick="getMedia()"/> 89e41f4b71Sopenharmony_ci <script> 90e41f4b71Sopenharmony_ci function getMedia() 91e41f4b71Sopenharmony_ci { 92e41f4b71Sopenharmony_ci let constraints = { 93e41f4b71Sopenharmony_ci video: {width: 500, height: 500}, 94e41f4b71Sopenharmony_ci audio: true 95e41f4b71Sopenharmony_ci }; 96e41f4b71Sopenharmony_ci // Obtain the video camera area. 97e41f4b71Sopenharmony_ci let video = document.getElementById("video"); 98e41f4b71Sopenharmony_ci // Returned Promise object 99e41f4b71Sopenharmony_ci let promise = navigator.mediaDevices.getUserMedia(constraints); 100e41f4b71Sopenharmony_ci // then() is asynchronous. Invoke the MediaStream object as a parameter. 101e41f4b71Sopenharmony_ci promise.then(function (MediaStream) { 102e41f4b71Sopenharmony_ci video.srcObject = MediaStream; 103e41f4b71Sopenharmony_ci video.play(); 104e41f4b71Sopenharmony_ci }); 105e41f4b71Sopenharmony_ci } 106e41f4b71Sopenharmony_ci </script> 107e41f4b71Sopenharmony_ci </body> 108e41f4b71Sopenharmony_ci </html> 109e41f4b71Sopenharmony_ci ``` 110