added PIP button in order to skip full screen & launch picture-in-picture
This commit is contained in:
parent
65c3c4ca4e
commit
86b1f8abad
@ -33,6 +33,7 @@
|
||||
"react-intl": "^6.4.4",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"react-tag-input-component": "^2.0.2",
|
||||
"react-use-pip": "^1.5.0",
|
||||
"recharts": "^2.9.3",
|
||||
"semantic-sdp": "^3.26.3",
|
||||
"usehooks-ts": "^2.9.1",
|
||||
|
@ -1,12 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import Hls from "hls.js";
|
||||
import { HTMLProps, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { HTMLProps, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { Icon } from "./icon";
|
||||
import { ProgressBar } from "./progress-bar";
|
||||
import { Menu, MenuItem } from "@szhsin/react-menu";
|
||||
import { StreamState } from "@/const";
|
||||
import classNames from "classnames";
|
||||
import usePictureInPicture, { VideoRefType } from "react-use-pip";
|
||||
|
||||
export enum VideoStatus {
|
||||
Online = "online",
|
||||
@ -133,6 +134,17 @@ export default function LiveVideoPlayer({
|
||||
}
|
||||
}, [video, volume, muted]);
|
||||
|
||||
const {
|
||||
isPictureInPictureActive,
|
||||
isPictureInPictureAvailable,
|
||||
togglePictureInPicture
|
||||
} = usePictureInPicture(video as VideoRefType);
|
||||
|
||||
const handlePIPClick = useCallback(async () => {
|
||||
togglePictureInPicture(!isPictureInPictureActive);
|
||||
}, [
|
||||
isPictureInPictureActive, togglePictureInPicture]);
|
||||
|
||||
function playStateToIcon() {
|
||||
switch (playState) {
|
||||
case "playing":
|
||||
@ -179,15 +191,17 @@ export default function LiveVideoPlayer({
|
||||
<h2>{title}</h2>
|
||||
</div>
|
||||
{/* CENTER PLAY ICON */}
|
||||
<div className="absolute w-full h-full flex items-center justify-center pointer">
|
||||
<Icon name={playStateToIcon()} size={80} className={playState === "loading" ? "animate-spin" : ""} />
|
||||
<div className="absolute w-full h-full flex items-center justify-center cursor-pointer">
|
||||
{!isPictureInPictureActive && (
|
||||
<Icon name={playStateToIcon()} size={80} className={playState === "loading" ? "animate-spin" : ""} />
|
||||
)}
|
||||
</div>
|
||||
{/* PLAYER CONTROLS OVERLAY */}
|
||||
<div
|
||||
className="absolute flex items-center gap-1 bottom-0 w-full bg-primary h-[40px]"
|
||||
onClick={e => e.stopPropagation()}>
|
||||
<div className="flex grow gap-1 items-center">
|
||||
<div className="px-5 py-2 pointer" onClick={() => togglePlay()}>
|
||||
<div className="px-5 py-2 cursor-pointer" onClick={() => togglePlay()}>
|
||||
<Icon name={playStateToIcon()} className={playState === "loading" ? "animate-spin" : ""} />
|
||||
</div>
|
||||
<div className="px-3 py-2 uppercase font-bold tracking-wide hover:bg-primary-hover">{pStatus}</div>
|
||||
@ -214,7 +228,7 @@ export default function LiveVideoPlayer({
|
||||
<Menu
|
||||
direction="top"
|
||||
align="center"
|
||||
menuButton={<div className="px-3 py-2 tracking-wide pointer">{levelName(level)}</div>}
|
||||
menuButton={<div className="px-3 py-2 tracking-wide cursor-pointer">{levelName(level)}</div>}
|
||||
menuClassName="bg-primary w-fit">
|
||||
{levels?.map(v => (
|
||||
<MenuItem
|
||||
@ -227,8 +241,12 @@ export default function LiveVideoPlayer({
|
||||
))}
|
||||
</Menu>
|
||||
</div>
|
||||
{isPictureInPictureAvailable && (
|
||||
<div className="pl-3 py-2 cursor-pointer tracking-wide font-bold text-sm"
|
||||
onClick={handlePIPClick}>PIP</div>
|
||||
)}
|
||||
<div
|
||||
className="px-3 py-2 pointer"
|
||||
className="px-2 py-2 cursor-pointer"
|
||||
onClick={() => {
|
||||
if (video.current) {
|
||||
video.current.requestFullscreen();
|
||||
@ -239,6 +257,13 @@ export default function LiveVideoPlayer({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isPictureInPictureActive && (
|
||||
<div
|
||||
className="absolute z-20 bg-[#00000055] select-none w-full h-full flex items-center justify-center cursor-pointer">
|
||||
<h2 onClick={async () => togglePictureInPicture(!isPictureInPictureActive)}>Video is playing in PIP
|
||||
window</h2>
|
||||
</div>
|
||||
)}
|
||||
{status === VideoStatus.Offline && (
|
||||
<div className="absolute w-full h-full z-20 bg-[#000000aa] flex items-center justify-center text-3xl font-bold uppercase">
|
||||
<FormattedMessage defaultMessage="Offline" id="7UOvbT" />
|
||||
|
10
yarn.lock
10
yarn.lock
@ -6838,6 +6838,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-use-pip@npm:^1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "react-use-pip@npm:1.5.0"
|
||||
peerDependencies:
|
||||
react: ^16.9.0 || ^17 || ^18
|
||||
checksum: 10c0/448a6d176eada90cafdcc2465dd9c974ba46e80c033168b3ecef87a064dd5f2976a8758f039e8b5c3f4abf15f844ad4096a2db6b1b0465f8a76988bee28aefdc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react@npm:^18.2.0":
|
||||
version: 18.2.0
|
||||
resolution: "react@npm:18.2.0"
|
||||
@ -7516,6 +7525,7 @@ __metadata:
|
||||
react-intl: "npm:^6.4.4"
|
||||
react-router-dom: "npm:^6.13.0"
|
||||
react-tag-input-component: "npm:^2.0.2"
|
||||
react-use-pip: "npm:^1.5.0"
|
||||
recharts: "npm:^2.9.3"
|
||||
rollup-plugin-visualizer: "npm:^5.10.0"
|
||||
semantic-sdp: "npm:^3.26.3"
|
||||
|
Loading…
x
Reference in New Issue
Block a user