fix: audio bars and upload process

This commit is contained in:
talksik
2026-02-21 13:05:02 -08:00
parent 8546260493
commit cbb3f50a25
9 changed files with 226 additions and 108 deletions
@@ -3,12 +3,21 @@ import type { MediaParticleData, StreamParticle } from "@/api/types";
import { apiClient } from "@/api/client";
import { usePlaybackStore } from "@/stores/playback-store";
import { Skeleton } from "@/components/ui/skeleton";
import { AudioLevelBars } from "@/components/audio/audio-level-bars";
import { useAudioSource } from "@/components/audio/use-audio-source";
interface MediaParticleViewProps {
particle: StreamParticle;
onEnded: () => void;
}
function formatTime(ms: number): string {
const totalSeconds = Math.floor(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}
export function MediaParticleView({
particle,
onEnded,
@@ -23,6 +32,10 @@ export function MediaParticleView({
const videoRef = useRef<HTMLVideoElement>(null);
const audioRef = useRef<HTMLAudioElement>(null);
const [audioEl, setAudioEl] = useState<HTMLAudioElement | null>(null);
const [currentTimeMs, setCurrentTimeMs] = useState(0);
const audioSource = useAudioSource(audioEl);
useEffect(() => {
if (cachedUrl) {
@@ -75,8 +88,29 @@ export function MediaParticleView({
if (isAudio) {
return (
<div className="flex h-full w-full items-center justify-center">
<audio ref={audioRef} src={url} autoPlay onEnded={onEnded} controls />
<div className="relative flex h-full w-full items-center justify-center bg-black/90">
<audio
ref={(el) => {
audioRef.current = el;
setAudioEl(el);
}}
src={url}
autoPlay
onEnded={onEnded}
onTimeUpdate={(e) => {
setCurrentTimeMs(e.currentTarget.currentTime * 1000);
}}
/>
{audioSource && (
<AudioLevelBars sourceNode={audioSource.sourceNode} />
)}
<div className="absolute top-3 right-3 rounded-full bg-black/30 px-2.5 py-1 backdrop-blur-sm">
<span className="font-mono text-xs text-white/80">
{formatTime(currentTimeMs)} / {formatTime(data.duration_ms)}
</span>
</div>
</div>
);
}