Music Player
componentry/music-playerFreeComponent
Component for music-player
Live preview
live · rendered by the registry
Rendered by componentry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://componentry.dev/r/music-player.jsonSource
1"use client";23import React, { useRef, useState, useEffect } from "react";4import { cn } from "@/lib/utils";5import { motion } from "framer-motion";67export interface MusicPlayerProps extends React.HTMLAttributes<HTMLDivElement> {8 /** The source URL of the audio file or YouTube video */9 src: string;10 /** The URL of the album cover image */11 coverArt: string;12 /** Whether to auto-play the audio when loaded */13 autoPlay?: boolean;14}1516export function MusicPlayer({17 className,18 src,19 coverArt,20 autoPlay = false,21 ...props22}: MusicPlayerProps) {23 const [isPlaying, setIsPlaying] = useState(autoPlay);24 const audioRef = useRef<HTMLAudioElement | null>(null);25 const iframeRef = useRef<HTMLIFrameElement | null>(null);2627 // Extract YouTube ID if it's a YouTube URL28 const getYoutubeId = (url: string) => {29 const match = url.match(30 /(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))([^&?]+)/31 );32 return match ? match[1] : null;33 };3435 const youtubeId = src ? getYoutubeId(src) : null;3637 useEffect(() => {38 if (isPlaying) {39 if (youtubeId && iframeRef.current?.contentWindow) {40 iframeRef.current.contentWindow.postMessage(41 JSON.stringify({ event: "command", func: "playVideo", args: [] }),42 "*"43 );44 } else {45 audioRef.current?.play().catch(() => setIsPlaying(false));46 }47 } else {48 if (youtubeId && iframeRef.current?.contentWindow) {49 iframeRef.current.contentWindow.postMessage(50 JSON.stringify({ event: "command", func: "pauseVideo", args: [] }),51 "*"52 );53 } else {54 audioRef.current?.pause();55 }56 }57 }, [isPlaying, youtubeId]);5859 const togglePlay = () => {60 setIsPlaying(!isPlaying);61 };6263 return (64 <div65 className={cn("relative inline-flex flex-col items-center", className)}66 {...props}67 >68 {youtubeId ? (69 <iframe70 ref={iframeRef}71 className="hidden"72 src={`https://www.youtube.com/embed/${youtubeId}?enablejsapi=1&autoplay=${73 autoPlay ? 1 : 074 }&controls=0`}75 allow="autoplay"76 />77 ) : (78 <audio79 ref={audioRef}80 src={src}81 onEnded={() => setIsPlaying(false)}82 className="hidden"83 />84 )}8586 <div87 className="relative cursor-pointer select-none h-64 w-64 md:h-80 md:w-80"88 onClick={togglePlay}89 title={isPlaying ? "Pause" : "Play"}90// … truncated
More from componentry
All 59 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradientanimated-gradient | componentry | Components | Free | no deps | |
| ASCII Effectascii-effect | componentry | Components | Free | no deps | |
| Aurora Flowaurora-flow | componentry | Components | Free | no deps | |
| auth-modalauth-modal | componentry | Components | Free | no deps | |
| border-beamborder-beam | componentry | Components | Free | no deps | |
| circuit-boardcircuit-board | componentry | Components | Free | no deps | |
| closing-plasmaclosing-plasma | componentry | Components | Free | no deps | |
| collection-surfercollection-surfer | componentry | Components | Free | no deps |
