Refactor ChannelPlayer component: remove play/pause functionality and related state management, update comments for clarity, and streamline audio control features for a live streaming experience.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import Hls from 'hls.js'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Maximize, Pause, Play, Volume2, VolumeX } from 'lucide-react'
|
||||
import { Maximize, Volume2, VolumeX } from 'lucide-react'
|
||||
|
||||
const STORAGE_KEY = 'tw:player'
|
||||
|
||||
@@ -23,8 +23,8 @@ function readStoredAudio(): { volume: number; muted: boolean } {
|
||||
}
|
||||
|
||||
/**
|
||||
* HLS-плеер линейного канала. Перемотка невозможна: своя минимальная панель без таймлайна, а на
|
||||
* play/после ошибки плеер прыгает к живому краю. Cookie tw_stream уже выдана к монтированию.
|
||||
* HLS-плеер линейного канала. Это живой эфир: ни перемотки, ни паузы — только звук, громкость и
|
||||
* полноэкранный режим. Cookie tw_stream уже выдана к монтированию.
|
||||
*/
|
||||
export function ChannelPlayer({
|
||||
slug,
|
||||
@@ -37,7 +37,6 @@ export function ChannelPlayer({
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const videoRef = useRef<HTMLVideoElement>(null)
|
||||
const hlsRef = useRef<Hls | null>(null)
|
||||
const [playing, setPlaying] = useState(false)
|
||||
const [muted, setMuted] = useState(() => readStoredAudio().muted)
|
||||
const [volume, setVolume] = useState(() => readStoredAudio().volume)
|
||||
|
||||
@@ -79,17 +78,6 @@ export function ChannelPlayer({
|
||||
|
||||
useEffect(() => clearHideTimer, [clearHideTimer])
|
||||
|
||||
const seekToLiveEdge = useCallback(() => {
|
||||
const video = videoRef.current
|
||||
if (!video) return
|
||||
const live = hlsRef.current?.liveSyncPosition
|
||||
if (typeof live === 'number' && Number.isFinite(live)) {
|
||||
video.currentTime = live
|
||||
} else if (video.seekable.length > 0) {
|
||||
video.currentTime = video.seekable.end(video.seekable.length - 1)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current
|
||||
if (!video) return
|
||||
@@ -137,17 +125,6 @@ export function ChannelPlayer({
|
||||
}
|
||||
}, [slug, onUnavailable])
|
||||
|
||||
const togglePlay = () => {
|
||||
const video = videoRef.current
|
||||
if (!video) return
|
||||
if (video.paused) {
|
||||
seekToLiveEdge()
|
||||
void video.play().catch(() => undefined)
|
||||
} else {
|
||||
video.pause()
|
||||
}
|
||||
}
|
||||
|
||||
// Установить громкость (0..1); 0 = mute, >0 запоминаем как последний уровень для «размьютить».
|
||||
const applyVolume = (value: number) => {
|
||||
const video = videoRef.current
|
||||
@@ -194,14 +171,9 @@ export function ChannelPlayer({
|
||||
playsInline
|
||||
muted
|
||||
className="h-full w-full"
|
||||
onClick={togglePlay}
|
||||
onDoubleClick={toggleFullscreen}
|
||||
onPlay={() => {
|
||||
setPlaying(true)
|
||||
scheduleHide()
|
||||
}}
|
||||
onPlay={scheduleHide}
|
||||
onPause={() => {
|
||||
setPlaying(false)
|
||||
clearHideTimer()
|
||||
setControlsVisible(true)
|
||||
}}
|
||||
@@ -221,9 +193,6 @@ export function ChannelPlayer({
|
||||
controlsVisible ? 'opacity-100' : 'pointer-events-none opacity-0'
|
||||
}`}
|
||||
>
|
||||
<button type="button" onClick={togglePlay} aria-label="play/pause">
|
||||
{playing ? <Pause className="h-5 w-5" /> : <Play className="h-5 w-5" />}
|
||||
</button>
|
||||
<div className="flex items-center gap-2">
|
||||
<button type="button" onClick={toggleMute} aria-label="mute">
|
||||
{muted ? <VolumeX className="h-5 w-5" /> : <Volume2 className="h-5 w-5" />}
|
||||
|
||||
Reference in New Issue
Block a user