Better player

This commit is contained in:
2024-01-23 00:46:18 +08:00
parent bb10ff9cac
commit 6897bfe018
5 changed files with 112 additions and 14 deletions

View File

@@ -1,10 +1,63 @@
import { useState, Fragment } from "react";
// @ts-ignore
import APlayer from "aplayer";
import Artplayer from "artplayer";
import { useState, Fragment, useRef, useEffect } from "react";
export default function Media({ sources }: { sources: { caption: string; url: string; type: string }[] }) {
import "aplayer/dist/APlayer.min.css";
function Video({ url, ...rest }: { url: string, className?: string }) {
const container = useRef<HTMLDivElement>(null);
useEffect(() => {
new Artplayer({
container: container.current as HTMLDivElement,
url: url,
setting: true,
flip: true,
playbackRate: true,
aspectRatio: true,
subtitleOffset: true
});
});
return (
<div ref={container} {...rest}></div>
);
}
function Audio({ url, artist, caption, ...rest }: {
url: string,
artist: string,
caption: string,
className?: string
}) {
const container = useRef(null);
useEffect(() => {
new APlayer({
container: container.current,
audio: [{
name: caption,
artist: artist,
url: url,
theme: "#49509e"
}]
});
});
return (
<div ref={container} {...rest}></div>
);
}
export default function Media({ sources, author }: {
sources: { caption: string; url: string; type: string }[],
author?: { name: string }
}) {
const [focus, setFocus] = useState<boolean[]>(sources.map((_, idx) => idx === 0));
function changeFocus(idx: number) {
setFocus(focus.map((_, idx) => idx === idx));
setFocus(focus.map((_, i) => i === idx));
}
return (
@@ -20,16 +73,16 @@ export default function Media({ sources }: { sources: { caption: string; url: st
checked={focus[idx]}
onChange={() => changeFocus(idx)}
/>
<div role="tabpanel" className="tab-content bg-base-100 border-base-300 rounded-box">
<div role="tabpanel" className="tab-content bg-base-100 border-base-300 rounded-box w-full">
{item.type === "video" && (
<video className="mb-0 block w-full h-[360px]" controls>
<source src={item.url} />
</video>
<div className="w-full h-[460px]">
<Video className="w-full h-full" url={item.url} />
</div>
)}
{item.type === "audio" && (
<audio className="mb-0 block w-full h-[20px]" controls>
<source src={item.url} />
</audio>
<div className="w-full">
<Audio url={item.url} artist={author?.name ?? "佚名"} caption={item.caption} />
</div>
)}
</div>
</Fragment>

View File

@@ -19,6 +19,9 @@ const { post } = (
type
title
description
author {
name
}
assets {
caption
url
@@ -67,8 +70,8 @@ const { post } = (
{
post.assets?.length > 0 && (
<div class="mb-5">
<Media sources={post.assets} />
<div class="mb-5 w-full">
<Media client:only sources={post.assets} author={post.author} />
</div>
)
}