xref: /docs/en/application-dev/web/web-rtc.md (revision e41f4b71)
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