1# Enabling Picture-in-Picture 2The web component supports the picture-in-picture (PiP) feature. An application can use the Picture-in-Picture API of the W3C standard to create a floating window on a web page to play videos. In this way, users can continue to watch videos in the PiP window when browsing other web pages or interacting with other applications. 3 4To use online video resources, you need to set the network permission in the configuration file. For details about how to add permissions, see [Declaring Permissions in the Configuration File](../security/AccessToken/declare-permissions.md). 5 6```json 7// src/main/module.json5 8"requestPermissions": [ 9 { 10 "name": "ohos.permission.INTERNET" 11 }, 12] 13``` 14 15## Constraints 161. H.264/H.265/HLS videos can be played in the PiP window. 172. The size of the PiP window is adjusted based on the system capability. For details, see the system features and capabilities in the design guide. 18 19## Entering Picture-in-Picture 20 21In the following example, a video element that includes only a media source and a button element for user interaction are used to describe how to create a PiP window, through which a user can continuously watch a video when browsing another web page or interacting with another application. 22 23```html 24<!-- Replace the URL with the actual URL of the video source --> 25<video id="video" src="https://example.com/file.mp4" controls></video> 26<button id="togglePipButton">Enable PiP</button> 27``` 28 29Use the **requestPictureInPicture()** method provided by the **HTMLVideoElement** API to enable the PiP feature. If the system supports the PiP feature, the video is displayed in PiP mode. 30 31```js 32togglePipButton.addEventListener("click", async () => { 33 try { 34 // Request to enter the picture-in-picture mode. 35 await video.requestPictureInPicture(); 36 } catch (err) { 37 // If the PiP mode fails to be switched, an error message is displayed. 38 console.error("Picture-in-Picture mode failed:", err); 39 } 40}); 41``` 42 43## Exiting Picture-in-Picture 44 45To exit the PiP mode, use the **exitPictureInPicture()** method of the **Document** API to display the video on the original tab page. 46 47```js 48// ... 49try { 50 if (videoElement !== document.pictureInPictureElement) { 51 await videoElement.requestPictureInPicture(); 52 } else { 53 await document.exitPictureInPicture(); 54 } 55} 56// ... 57``` 58 59## Listening for Picture-in-Picture Events 60 61When a user enables the picture-in-picture mode, a floating window is displayed for playing the video. The system specifies that only one picture-in-picture video can be played at a time. 62When **HTMLVideoElement** successfully enters the PiP mode, the **enterpictureinpicture** event is triggered. When **HTMLVideoElement** successfully exits the PiP mode, the **leavepictureinpicture** event is triggered. 63You can handle these events by listening for them. 64 65 66```js 67videoElement.addEventListener('enterpictureinpicture', function (event) { 68// The video enters the PiP mode. 69}); 70 71videoElement.addEventListener('leavepictureinpicture', function (event) { 72// The video exits the PiP mode. 73}); 74``` 75 76## Interacting with the Picture-in-Picture Window 77 78* PiP window control: 79 Allows users to double-click a PiP window to zoom in or zoom out the window. 80 Allows users to drag the PiP window to any position on the screen. 81 Allows users to click the PiP window to display or hide UI components at the PiP control layer. 82 83* UI components at the PiP control layer: 84 The PiP window control layer includes the close (close the PiP window) and restore (restore from the PiP window to the original application UI) components. 85 The playback control includes the pause, play, and forward/rewind components. (By default, the forward/rewind UI component is displayed. If the original video does not support forward/rewind, there is no response for click events.) 86 87  88 89 90## Example 91 92The following is an example of entering and exiting the PiP mode: 93 94* ETS code on the application side: 95 96 ```ts 97 // xxx.ets 98 import {webview} from '@kit.ArkWeb'; 99 100 @Entry 101 @Component 102 struct Index { 103 @State videoSrc: Resource = $rawfile('PictureInPicture.html') 104 105 106 controller: webview.WebviewController = new webview.WebviewController() 107 108 build() { 109 Column() { 110 Web({src: this.videoSrc, controller: this.controller}) 111 } 112 } 113 } 114 ``` 115 116* Code of the HTML page: 117 118 ```html 119 <!-- picture-in-picture.html --> 120 <!DOCTYPE html> 121 <html lang="en"> 122 <head> 123 <meta charset="UTF-8" /> 124 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 125 <title>Picture-in-Picture Demo</title> 126 <style> 127 body { 128 font-family: Arial, sans-serif; 129 display: flex; 130 flex-direction: column; 131 align-items: center; 132 justify-content: center; 133 height: 100vh; 134 margin: 0; 135 } 136 video { 137 width: 60%; 138 border: 1px solid #ccc; 139 border-radius: 8px; 140 margin-bottom: 20px; 141 } 142 button { 143 padding: 10px 20px; 144 font-size: 16px; 145 cursor: pointer; 146 } 147 </style> 148 </head> 149 <body> 150 <!-- Replace the URL with the actual URL of the video source --> 151 <video id="video" src="https://example.com/file.mp4" controls></video> 152 <button id="togglePipButton">Enable PiP</button> 153 154 <script> 155 const video = document.getElementById("video"); 156 const togglePipButton = document.getElementById("togglePipButton"); 157 158 // If the browser does not support the PiP feature or the feature is disabled, the button is hidden. 159 togglePipButton.hidden = 160 !document.pictureInPictureEnabled || video.disablePictureInPicture; 161 162 // Listen for the click events to enter or exit the PiP mode. 163 togglePipButton.addEventListener("click", async () => { 164 try { 165 if (document.pictureInPictureElement) { 166 // If the PiP mode is used, exit the PiP mode. 167 await document.exitPictureInPicture(); 168 } else { 169 // Otherwise, enter the PiP mode. 170 await video.requestPictureInPicture(); 171 } 172 } catch (err) { 173 // If the PiP mode fails to be switched, an error message is displayed. 174 console.error("Picture-in-Picture mode failed:", err); 175 } 176 }); 177 178 // Listen for the PiP enter event. 179 video.addEventListener("enterpictureinpicture", () => { 180 // Update the button text to "Exit PiP" 181 togglePipButton.textContent = "Exit PiP" 182 }); 183 184 // Listen for the PiP exit event. 185 video.addEventListener("leavepictureinpicture", () => { 186 // Update the button text to "Enable PiP" 187 togglePipButton.textContent = "Enable PiP" 188 }); 189 </script> 190 </body> 191 </html> 192 ``` 193