mirror of
https://github.com/nianzhibai/91.git
synced 2026-06-15 00:44:30 +08:00
Enhance video detail player experience
Add ArtPlayer/HLS playback, resume prompts, mobile gestures, orientation toggle, and theme-aware controls. Hide author metadata from video detail headers.
This commit is contained in:
Generated
+35
@@ -9,6 +9,8 @@
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"artplayer": "^5.4.0",
|
||||
"hls.js": "^1.6.16",
|
||||
"lucide-react": "0.453.0",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
@@ -475,6 +477,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/artplayer": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/artplayer/-/artplayer-5.4.0.tgz",
|
||||
"integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"option-validator": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
@@ -525,12 +536,27 @@
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hls.js": {
|
||||
"version": "1.6.16",
|
||||
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.16.tgz",
|
||||
"integrity": "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||
@@ -832,6 +858,15 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/option-validator": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/option-validator/-/option-validator-2.0.6.tgz",
|
||||
"integrity": "sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"kind-of": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"test": "node --import tsx --test tests/*.test.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"artplayer": "^5.4.0",
|
||||
"hls.js": "^1.6.16",
|
||||
"lucide-react": "0.453.0",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
|
||||
@@ -10,11 +10,10 @@ type Props = {
|
||||
*
|
||||
* 视觉:
|
||||
* - 标题:大、粗、最高两行
|
||||
* - meta:作者首字头像 + 名字 + 一组小胶囊(来源、画质、时长、观看数、发布时间)
|
||||
* - meta:一组小胶囊(来源、画质、时长、观看数、发布时间)
|
||||
* 每个胶囊有自己的语义色彩,避免传统 "·" 分隔列表的列表感。
|
||||
*/
|
||||
export function VideoMetaHeader({ video }: Props) {
|
||||
const author = (video.author ?? "").trim();
|
||||
const source = (video.sourceLabel ?? "").trim();
|
||||
const quality = (video.quality ?? "").trim();
|
||||
const duration = (video.duration ?? "").trim();
|
||||
@@ -28,15 +27,6 @@ export function VideoMetaHeader({ video }: Props) {
|
||||
</h1>
|
||||
|
||||
<div className="vd-header__row">
|
||||
{author && (
|
||||
<div className="vd-author" aria-label={`作者 ${author}`}>
|
||||
<span className="vd-author__avatar" aria-hidden="true">
|
||||
{author.slice(0, 1)}
|
||||
</span>
|
||||
<span className="vd-author__name">{author}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ul className="vd-meta" aria-label="视频信息">
|
||||
{source && (
|
||||
<li className="vd-meta__chip" data-tone={sourceKind || "neutral"}>
|
||||
|
||||
+1104
-133
File diff suppressed because it is too large
Load Diff
@@ -131,8 +131,10 @@ export default function VideoDetailPage() {
|
||||
<div className="vd-player-wrap">
|
||||
<div className="vd-player">
|
||||
<VideoPlayer
|
||||
id={detail.id}
|
||||
src={detail.videoSrc}
|
||||
poster={detail.poster}
|
||||
previewSrc={detail.previewSrc}
|
||||
title={detail.title}
|
||||
onFirstPlay={handleFirstPlay}
|
||||
/>
|
||||
|
||||
+286
-61
@@ -15,7 +15,6 @@
|
||||
* .vd-player-wrap 播放器外层光晕
|
||||
* .vd-player 播放器框
|
||||
* .vd-header 标题 + 一行作者/meta
|
||||
* .vd-author 作者头像 + 名字
|
||||
* .vd-meta meta 胶囊列表
|
||||
* .vd-actions 操作工具条
|
||||
* .vd-info 简介 + 标签合并卡
|
||||
@@ -145,9 +144,107 @@
|
||||
aspect-ratio: 16 / 9;
|
||||
background: #000;
|
||||
width: 100%;
|
||||
--video-player-progress: #ff5634;
|
||||
--video-player-progress-loaded: rgba(255, 86, 52, 0.34);
|
||||
--video-player-progress-track: rgba(255, 255, 255, 0.24);
|
||||
--video-player-progress-hover: rgba(255, 210, 198, 0.36);
|
||||
}
|
||||
|
||||
.video-player video {
|
||||
:root[data-theme="pink"] .video-player {
|
||||
--video-player-progress: #ec4f86;
|
||||
--video-player-progress-loaded: rgba(236, 79, 134, 0.34);
|
||||
--video-player-progress-track: rgba(255, 255, 255, 0.28);
|
||||
--video-player-progress-hover: rgba(255, 197, 216, 0.42);
|
||||
}
|
||||
|
||||
.video-player__mount {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.video-player__poster-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
filter: blur(22px) saturate(1.08);
|
||||
opacity: 0.26;
|
||||
transform: scale(1.04);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.video-player .art-video-player {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
--art-theme: var(--video-player-progress);
|
||||
--art-loaded-color: var(--video-player-progress-loaded);
|
||||
--art-progress-color: var(--video-player-progress-track);
|
||||
--art-hover-color: var(--video-player-progress-hover);
|
||||
--art-progress-height: 5px;
|
||||
--art-control-height: 44px;
|
||||
--art-control-icon-size: 32px;
|
||||
--art-bottom-height: 112px;
|
||||
--art-widget-background: rgba(8, 9, 13, 0.86);
|
||||
--art-tip-background: rgba(8, 9, 13, 0.78);
|
||||
}
|
||||
|
||||
.art-video-player.art-manual-orientation {
|
||||
background: #000;
|
||||
transition:
|
||||
width 180ms var(--ease-out),
|
||||
height 180ms var(--ease-out),
|
||||
transform 180ms var(--ease-out);
|
||||
}
|
||||
|
||||
.art-video-player .art-control-orientationToggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.art-video-player .art-control-orientationToggle .video-player__orientation-control-icon {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
}
|
||||
|
||||
.art-video-player
|
||||
.art-control-orientationToggle[data-next-orientation="landscape"]
|
||||
.video-player__orientation-control-icon--to-landscape,
|
||||
.art-video-player
|
||||
.art-control-orientationToggle[data-next-orientation="portrait"]
|
||||
.video-player__orientation-control-icon--to-portrait {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.art-video-player .art-control-orientationToggle svg {
|
||||
display: block;
|
||||
fill: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.art-video-player .art-control-orientationToggle svg * {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.art-video-player.art-manual-orientation .art-control-orientationToggle svg {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
@media (hover: none) and (pointer: coarse), (max-width: 768px) {
|
||||
.art-video-player .art-control-orientationToggle {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.video-player video,
|
||||
.video-player .art-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
@@ -175,6 +272,162 @@
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.video-player__resume,
|
||||
.video-player__error,
|
||||
.video-player__gesture-hud,
|
||||
.video-player__seek-preview {
|
||||
position: absolute;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.video-player__resume {
|
||||
left: 50%;
|
||||
top: 16px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
max-width: calc(100% - 32px);
|
||||
padding: 8px 10px 8px 14px;
|
||||
border-radius: var(--radius-pill);
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
background: rgba(8, 9, 13, 0.78);
|
||||
color: #fff;
|
||||
font-size: var(--font-sm);
|
||||
font-weight: var(--weight-semibold);
|
||||
transform: translateX(-50%);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.video-player__resume span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.video-player__resume button,
|
||||
.video-player__error button {
|
||||
min-height: 30px;
|
||||
border: 0;
|
||||
border-radius: var(--radius-pill);
|
||||
padding: 0 12px;
|
||||
background: var(--video-player-progress);
|
||||
color: #fff;
|
||||
font-size: var(--font-sm);
|
||||
font-weight: var(--weight-bold);
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.video-player__resume button + button,
|
||||
.video-player__error button + button {
|
||||
background: rgba(255, 255, 255, 0.13);
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
}
|
||||
|
||||
.video-player__resume button:hover,
|
||||
.video-player__error button:hover {
|
||||
filter: brightness(1.08);
|
||||
}
|
||||
|
||||
.video-player__error {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: min(420px, calc(100% - 32px));
|
||||
padding: 18px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
background: rgba(8, 9, 13, 0.86);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
transform: translate(-50%, -50%);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
|
||||
}
|
||||
|
||||
.video-player__error-title {
|
||||
margin-bottom: 6px;
|
||||
font-size: var(--font-lg);
|
||||
font-weight: var(--weight-bold);
|
||||
}
|
||||
|
||||
.video-player__error-message {
|
||||
color: rgba(255, 255, 255, 0.76);
|
||||
font-size: var(--font-md);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.video-player__error-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.video-player__gesture-hud {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
min-width: 92px;
|
||||
padding: 12px 18px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: rgba(8, 9, 13, 0.78);
|
||||
color: #fff;
|
||||
font-size: var(--font-lg);
|
||||
font-weight: var(--weight-bold);
|
||||
text-align: center;
|
||||
transform: translate(-50%, -50%);
|
||||
pointer-events: none;
|
||||
animation: video-player-hud-pop 650ms var(--ease-out) forwards;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
@keyframes video-player-hud-pop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(0.92);
|
||||
}
|
||||
18% {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.video-player__seek-preview {
|
||||
bottom: 66px;
|
||||
width: 168px;
|
||||
overflow: hidden;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
background: rgba(8, 9, 13, 0.88);
|
||||
transform: translateX(-50%);
|
||||
pointer-events: none;
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.42);
|
||||
}
|
||||
|
||||
.video-player__seek-preview video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
height: auto;
|
||||
object-fit: cover;
|
||||
filter: none;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.video-player__seek-preview span {
|
||||
display: block;
|
||||
padding: 5px 8px 6px;
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
font-size: var(--font-xs);
|
||||
font-weight: var(--weight-bold);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 长按 2 倍速时的角标提示 */
|
||||
.video-player__rate-hint {
|
||||
position: absolute;
|
||||
@@ -195,6 +448,37 @@
|
||||
animation: video-player-rate-hint-in 120ms ease-out;
|
||||
}
|
||||
|
||||
:root[data-theme="pink"] .video-player__resume,
|
||||
:root[data-theme="pink"] .video-player__error,
|
||||
:root[data-theme="pink"] .video-player__seek-preview,
|
||||
:root[data-theme="pink"] .video-player__gesture-hud {
|
||||
border-color: rgba(255, 197, 216, 0.28);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.video-player__resume {
|
||||
top: 10px;
|
||||
width: calc(100% - 20px);
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.video-player__resume span {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.video-player__error {
|
||||
width: calc(100% - 24px);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.video-player__seek-preview {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes video-player-rate-hint-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -234,46 +518,6 @@
|
||||
gap: var(--space-3) var(--space-4);
|
||||
}
|
||||
|
||||
/* Author chip */
|
||||
.vd-author {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: 4px 12px 4px 4px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid var(--border-subtle);
|
||||
transition: border-color var(--transition-fast),
|
||||
background var(--transition-fast);
|
||||
}
|
||||
|
||||
.vd-author:hover {
|
||||
border-color: var(--border-accent);
|
||||
background: var(--accent-softer);
|
||||
}
|
||||
|
||||
.vd-author__avatar {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent-gradient);
|
||||
color: var(--text-on-accent);
|
||||
font-size: var(--font-sm);
|
||||
font-weight: var(--weight-bold);
|
||||
text-transform: uppercase;
|
||||
flex: 0 0 auto;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.vd-author__name {
|
||||
color: var(--text-strong);
|
||||
font-size: var(--font-md);
|
||||
font-weight: var(--weight-semibold);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Meta chips */
|
||||
.vd-meta {
|
||||
display: flex;
|
||||
@@ -1116,11 +1360,6 @@
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.vd-author__avatar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.vd-meta {
|
||||
gap: 6px;
|
||||
}
|
||||
@@ -1206,20 +1445,6 @@
|
||||
gap: var(--space-2) var(--space-3);
|
||||
}
|
||||
|
||||
.vd-author {
|
||||
padding: 3px 10px 3px 3px;
|
||||
}
|
||||
|
||||
.vd-author__avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: var(--font-xs);
|
||||
}
|
||||
|
||||
.vd-author__name {
|
||||
font-size: var(--font-sm);
|
||||
}
|
||||
|
||||
/* 操作栏:点赞点踩组合占满主行,"不再显示"折到右侧或单独一行 */
|
||||
.vd-actions {
|
||||
padding: var(--space-2);
|
||||
|
||||
Reference in New Issue
Block a user