PiP

预计阅读时间: 5 分钟

PiP (Picture-in-Picture) 功能提供对 Video.js 播放器画中画模式的完整管理,包括状态访问和模式切换操作。

概述

PiP 功能是 Video.js React 中用于管理播放器画中画状态的模块。它支持画中画模式的请求、退出和切换,让用户能够在小窗口中继续观看视频。

状态

属性类型描述
pipboolean当前是否处于画中画模式
pipAvailabilityboolean画中画功能是否可用

状态说明

  • pip:当播放器处于画中画模式时为 true,否则为 false
  • pipAvailability:浏览器是否支持画中画功能

操作

操作类型描述
requestPictureInPictureAction请求进入画中画模式
exitPictureInPictureAction退出画中画模式
togglePictureInPictureAction切换画中画模式

requestPictureInPicture

请求进入画中画模式。如果当前已在画中画模式,则无效。

import { usePlayerActions, usePlayer } from '@videojs/react';
import { selectPiP } from '@videojs/react';

function PiPButton() {
  const pip = usePlayer(selectPiP);
  const { requestPictureInPicture } = usePlayerActions();
  
  return (
    <button 
      onClick={requestPictureInPicture}
      disabled={!pip.pipAvailability}
    >
      画中画
    </button>
  );
}

exitPictureInPicture

退出当前画中画模式。如果当前不在画中画模式,则无效。

import { usePlayerActions, usePlayer } from '@videojs/react';
import { selectPiP } from '@videojs/react';

function ExitPiPButton() {
  const pip = usePlayer(selectPiP);
  const { exitPictureInPicture } = usePlayerActions();
  
  return (
    <button 
      onClick={exitPictureInPicture}
      disabled={!pip.pip}
    >
      退出画中画
    </button>
  );
}

togglePictureInPicture

切换画中画模式。根据当前状态进入或退出画中画。

import { usePlayerActions, usePlayer } from '@videojs/react';
import { selectPiP } from '@videojs/react';

function TogglePiPButton() {
  const pip = usePlayer(selectPiP);
  const { togglePictureInPicture } = usePlayerActions();
  
  return (
    <button onClick={togglePictureInPicture}>
      {pip.pip ? '退出画中画' : '画中画'}
    </button>
  );
}

选择器

传递 selectPiPusePlayer 钩子以订阅画中画状态。

import { selectPiP, usePlayer } from '@videojs/react';

function PiPStatus() {
  const pip = usePlayer(selectPiP);
  
  return (
    <div>
      <p>画中画状态: {pip.pip ? '激活' : '未激活'}</p>
      <p>画中画可用: {pip.pipAvailability ? '是' : '否'}</p>
    </div>
  );
}

示例

完整的画中画控制组件

import { selectPiP, usePlayer, usePlayerActions } from '@videojs/react';

function PiPControls() {
  const pip = usePlayer(selectPiP);
  const { requestPictureInPicture, exitPictureInPicture, togglePictureInPicture } = usePlayerActions();
  
  if (!pip.pipAvailability) {
    return <div>您的浏览器不支持画中画功能</div>;
  }
  
  return (
    <div className="pip-controls">
      {!pip.pip ? (
        <button onClick={requestPictureInPicture}>开启画中画</button>
      ) : (
        <button onClick={exitPictureInPicture}>关闭画中画</button>
      )}
    </div>
  );
}

PiP 模式切换动画

import { selectPiP, usePlayer } from '@videojs/react';
import { useState, useEffect } from 'react';

function PiPTransition() {
  const pip = usePlayer(selectPiP);
  const [showTransition, setShowTransition] = useState(false);
  
  useEffect(() => {
    setShowTransition(true);
    const timer = setTimeout(() => setShowTransition(false), 500);
    return () => clearTimeout(timer);
  }, [pip.pip]);
  
  return (
    <div className={`pip-transition ${showTransition ? 'active' : ''}`}>
      {pip.pip ? '已进入画中画' : '已退出画中画'}
    </div>
  );
}

画中画时显示迷你控制器

import { selectPiP, selectPlayback, usePlayer, usePlayerActions } from '@videojs/react';

function MiniController() {
  const pip = usePlayer(selectPiP);
  const playback = usePlayer(selectPlayback);
  const { play, pause, togglePictureInPicture } = usePlayerActions();
  
  // 仅在画中画模式显示迷你控制器
  if (!pip.pip) return null;
  
  return (
    <div className="mini-controller">
      <button onClick={playback.paused ? play : pause}>
        {playback.paused ? '播放' : '暂停'}
      </button>
      <button onClick={togglePictureInPicture}>
        关闭
      </button>
    </div>
  );
}

画中画自动切换

import { selectPiP, usePlayer, usePlayerActions } from '@videojs/react';
import { useEffect } from 'react';

function AutoPiP() {
  const pip = usePlayer(selectPiP);
  const { togglePictureInPicture } = usePlayerActions();
  
  // 当页面隐藏时自动进入画中画
  useEffect(() => {
    const handleVisibilityChange = () => {
      if (document.hidden && !pip.pip && pip.pipAvailability) {
        togglePictureInPicture();
      }
    };
    
    document.addEventListener('visibilitychange', handleVisibilityChange);
    return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
  }, [pip.pip, pip.pipAvailability, togglePictureInPicture]);
  
  return null;
}

注意事项

  1. 浏览器支持:画中画功能需要浏览器支持 Picture-in-Picture API
  2. 用户手势:某些浏览器需要用户手势才能触发画中画
  3. 移动设备:移动设备的画中画行为可能有所不同
  4. 权限控制:画中画功能可能被浏览器权限策略限制
  5. 自动退出:页面刷新或导航可能导致画中画自动退出