PIP 모드를 사용하면 사용자가 플로팅 창에서 동영상을 시청할 수 있습니다. (항상 다른 창 위에 놓임) 다른 사이트 또는 응용 프로그램과 상호 작용하면서 보는 것을 볼 수 있습니다.
Picture-in-Picture Web API로 웹사이트의 동영상 요소에 사용되는 PIP 모드입니다. 다음 링크에서 사용해 보세요. 공식 PIP 모드 샘플을 참고하세요.
배경
Safari는 2016년 9월에 WebKit API를 통해 PIP 모드 지원을 추가했습니다. macOS Sierra에서. 6개월 후 Chrome은 Android O가 출시되고 Android O가 설치된 모바일 기기에서 네이티브 Android API를 사용합니다. 6개월 후 Google은 프로젝트를 개발하고 Safari와 호환되는 기능인 웹 API를 표준화하여 개발자가 PIP 모드의 전체 환경을 만들고 제어할 수 있습니다. 여기 있습니다.
코드 들어가기
PIP 모드 시작
먼저 동영상 요소와 사용자가 콘텐츠와 직접 상호작용할 수 있는 사용할 수 있습니다.
<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>
사용자 동작에 대한 응답으로만 PIP 모드를 요청하고
프라미스를 반환했습니다.videoElement.play()
이는 프라미스가
아직 사용자 동작을 전파하지 않습니다. 그 대신 requestPictureInPicture()
pipButtonElement
의 클릭 핸들러를 추가합니다. 사용자의 책임
사용자가 두 번 클릭하는 경우의 상황을
처리할 수 있습니다
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
await videoElement.requestPictureInPicture();
pipButtonElement.disabled = false;
});
프라미스가 해결되면 Chrome은 동영상을 작은 창으로 축소하여 사용자는 이리저리 이동하고 다른 창 위에 배치할 수 있습니다.
완료되었습니다. 훌륭합니다. 이제 독서를 멈추고 휴식을 취하세요 있습니다. 안타깝게도 항상 그런 것은 아닙니다. 프라미스는 어떤 경우라도 거부될 수 있습니다. 다음의 이유 중 하나:
- 시스템에서 PIP 모드를 지원하지 않습니다.
- 제한적인 제한사항으로 인해 문서에서 PIP 모드를 사용할 수 없습니다. 권한 정책.
- 동영상 메타데이터가 아직 로드되지 않았습니다 (
videoElement.readyState === 0
). - 동영상 파일이 오디오 전용입니다.
- 새
disablePictureInPicture
속성이 동영상 요소에 표시됩니다. - 사용자 동작 이벤트 핸들러에서 호출이 되지 않았습니다 (예: 버튼 클릭). Chrome 74부터 적용할 수 있습니다. 이미 PIP 모드가 사용 설정되어 있습니다.
아래의 기능 지원 섹션에서는 현재 상태에 따라 버튼을 사용 설정/사용 중지하는 방법을 이러한 제한사항을 준수해야 합니다
이러한 잠재적인 오류를 캡처하기 위해 try...catch
블록을 추가하고
상황을 알 수 있습니다.
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
try {
await videoElement.requestPictureInPicture();
} catch (error) {
// TODO: Show error message to user.
} finally {
pipButtonElement.disabled = false;
}
});
동영상 요소는 PIP 모드이든 not: 이벤트가 실행되고 호출 메서드가 작동합니다. 포드의 상태 변경을 PIP 모드 창 (재생, 일시중지, 탐색 등)으로 이동하며 JavaScript에서 프로그래매틱 방식으로 상태를 변경할 수 있습니다.
PIP 모드 종료
이제 버튼에서 PIP 모드를 시작하고 종료하도록 전환해 보겠습니다.
먼저 읽기 전용 객체 document.pictureInPictureElement
가
동영상 요소입니다. 그렇지 않은 경우
PIP 모드를 사용합니다. 그렇지 않으면
document.exitPictureInPicture()
: 동영상이
새 탭으로 이동하겠습니다 이 메서드는 프로미스를 반환합니다.
...
try {
if (videoElement !== document.pictureInPictureElement) {
await videoElement.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
}
...
PIP 모드 이벤트 수신
운영체제에서는 일반적으로 PIP 모드를 하나의 창으로 제한하므로 Chrome의 구현은 이 패턴을 따릅니다. 즉, 사용자는 동영상 감상 중에 업로드할 수 있습니다. 사용자가 이탈하여 사용자가 요청하지 않아도 PIP 모드를 사용할 수 있습니다.
새로운 enterpictureinpicture
및 leavepictureinpicture
이벤트 핸들러를 사용하면
맞춤설정할 수 있습니다. 그것은 인터넷을 탐색하는 것에서부터 무엇이든 될 수 있습니다.
실시간 스트림 채팅 표시에 이르기까지 다양합니다.
videoElement.addEventListener('enterpictureinpicture', function (event) {
// Video entered Picture-in-Picture.
});
videoElement.addEventListener('leavepictureinpicture', function (event) {
// Video left Picture-in-Picture.
// User may have played a Picture-in-Picture video from a different page.
});
PIP 모드 창 맞춤설정
Chrome 74는 다음 화면에서 재생/일시중지, 이전 트랙, 다음 트랙 버튼을 지원합니다. Media Session API를 사용하여 제어할 수 있는 PIP 모드 창입니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.기본적으로 재생/일시중지 버튼은 PIP 모드에서 항상 표시됩니다.
동영상이 MediaStream 객체 (예: getUserMedia()
,
getDisplayMedia()
, canvas.captureStream()
) 또는 동영상에 MediaSource가 있는 경우
길이를 +Infinity
(예: 실시간 피드)로 설정합니다. 재생/일시중지 버튼을 사용하려면 다음 단계를 따르세요.
항상 표시됨, 두 '재생' 모두에 대해 일부 미디어 세션 작업 핸들러를 설정합니다. 및
"일시중지" 미디어 이벤트를 생성합니다.
// Show a play/pause button in the Picture-in-Picture window
navigator.mediaSession.setActionHandler('play', function () {
// User clicked "Play" button.
});
navigator.mediaSession.setActionHandler('pause', function () {
// User clicked "Pause" button.
});
'이전 트랙' 표시 중 및 '다음 트랙' 창 컨트롤도 비슷합니다. 설정 이에 대한 미디어 세션 작업 핸들러가 PIP 모드에 표시합니다. 이러한 작업을 처리할 수 있습니다.
navigator.mediaSession.setActionHandler('previoustrack', function () {
// User clicked "Previous Track" button.
});
navigator.mediaSession.setActionHandler('nexttrack', function () {
// User clicked "Next Track" button.
});
실제 사례를 확인하려면 공식 미디어 세션 샘플을 사용해 보세요.
PIP 모드 창 크기 가져오기
동영상 시작 및 종료 시 동영상 화질을 조정하려는 경우 PIP 모드를 사용하려면 PIP 모드 창 크기를 알아야 하며 사용자가 수동으로 창 크기를 조절하면 알림을 받습니다.
아래 예는 PIP 모드 창은 생성 또는 크기가 조절될 때 표시됩니다.
let pipWindow;
videoElement.addEventListener('enterpictureinpicture', function (event) {
pipWindow = event.pictureInPictureWindow;
console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
pipWindow.addEventListener('resize', onPipWindowResize);
});
videoElement.addEventListener('leavepictureinpicture', function (event) {
pipWindow.removeEventListener('resize', onPipWindowResize);
});
function onPipWindowResize(event) {
console.log(
`> Window size changed to ${pipWindow.width}x${pipWindow.height}`
);
// TODO: Change video quality based on Picture-in-Picture window size.
}
각 사소한 변경이 있을 때마다 크기 조절 이벤트에 직접 연결하지 않는 것이 좋습니다. 를 추가하면 별도의 이벤트가 실행되어 성능 문제가 발생할 수 있습니다. 포함 즉, 크기 조절 작업이 계속해서 이벤트를 발생시킵니다. 있습니다. 제한 및 성능 조정과 같은 디바운싱하여 이 문제를 해결할 수 있습니다.
기능 지원
PIP 모드 웹 API가 지원되지 않을 수 있으므로 이를 감지하고
점진적인 개선을 제공합니다. 지원되는 경우에도
사용자가 사용 중지 또는 권한 정책에 따라 사용 중지할 수 있습니다. 다행히
새 불리언 document.pictureInPictureEnabled
를 사용하여 이를 결정합니다.
if (!('pictureInPictureEnabled' in document)) {
console.log('The Picture-in-Picture Web API is not available.');
} else if (!document.pictureInPictureEnabled) {
console.log('The Picture-in-Picture Web API is disabled.');
}
동영상의 특정 버튼 요소에 적용되는 방식으로, PIP 모드 버튼의 표시 여부를 처리합니다.
if ('pictureInPictureEnabled' in document) {
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
videoElement.addEventListener('loadedmetadata', setPipButton);
videoElement.addEventListener('emptied', setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
pipButtonElement.hidden = true;
}
function setPipButton() {
pipButtonElement.disabled =
videoElement.readyState === 0 ||
!document.pictureInPictureEnabled ||
videoElement.disablePictureInPicture;
}
MediaStream 동영상 지원
MediaStream 객체를 재생하는 동영상 (예: getUserMedia()
, getDisplayMedia()
,
canvas.captureStream()
)는 Chrome 71에서 PIP 모드도 지원합니다. 이
사용자의 웹캠이 포함된 PIP 모드 창을 표시할 수 있습니다.
디스플레이 동영상 스트림,
캔버스 요소로도 설정할 수 있습니다 Note that the
DOM에 연결하지 않아도 동영상 요소를
PIP 모드를 사용합니다.
PIP 모드 창에 사용자의 웹캠 표시
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
PIP 모드 창에 디스플레이 표시
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
PIP 모드 창에 캔버스 요소 표시
const canvas = document.createElement('canvas');
// Draw something to canvas.
canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
const video = document.createElement('video');
video.muted = true;
video.srcObject = canvas.captureStream();
video.play();
// Later on, video.requestPictureInPicture();
canvas.captureStream()
와 Media Session API를 함께 사용하면 다음과 같은 작업을 할 수 있습니다.
Chrome 74에서 오디오 재생목록 창 만들기 공식
오디오 재생목록 샘플
샘플, 데모, Codelab
공식 PIP 모드 샘플을 확인하여 PIP 모드를 사용해 보세요. 웹 API
데모와 Codelab이 이어서 나옵니다.
다음 단계
먼저 구현 상태 페이지에서 API는 현재 Chrome과 다른 브라우저에서 구현되어 있습니다.
조만간 제공될 내용은 다음과 같습니다.
- 웹 개발자는 맞춤 PIP 모드 컨트롤을 추가할 수 있습니다.
- 임의의
HTMLElement
객체를 플로팅 창에 표시하기 위한 새로운 웹 API가 제공됩니다.
브라우저 지원
PIP 모드 웹 API는 Chrome, Edge, Opera, Safari에서 지원됩니다. 자세한 내용은 MDN을 참고하세요.
리소스
- Chrome 기능 상태: https://www.chromestatus.com/feature/5729206566649856
- Chrome 구현 버그: https://crbug.com/?q=component:Blink>Media>PictureInPicture
- PIP 모드 웹 API 사양: https://wicg.github.io/picture-in-picture
- 사양 문제: https://github.com/WICG/picture-in-picture/issues
- 샘플: https://googlechrome.github.io/samples/picture-in-picture/
- 비공식 PIP 모드 폴리필: https://github.com/gbentaieb/pip-polyfill/
이 과정에서 공헌해 주신 Mounir Lamouri와 Jennifer Apacible에 진심으로 감사드립니다. 이 도움말과 관련하여 도움이 될 것입니다. 진심으로 감사드립니다. 표준화 노력에 관여합니다.