audio-producer

from daffy0208/ai-dev-standards

As Described in the name

7 stars6 forksUpdated Dec 25, 2025
npx skills add https://github.com/daffy0208/ai-dev-standards --skill audio-producer

SKILL.md

Audio Producer Skill

I help you build audio players, process audio, and create interactive sound experiences for the web.

What I Do

Audio Playback:

  • Custom audio players
  • Playlist management
  • Playback controls (play, pause, seek, volume)
  • Waveform visualization

Audio Processing:

  • Audio effects (reverb, delay, filters)
  • Equalization and mixing
  • Audio recording
  • Real-time audio manipulation

Interactive Audio:

  • Background music and sound effects
  • User interaction sounds
  • Spatial audio
  • Audio notifications

Custom Audio Player

// components/AudioPlayer.tsx
'use client'
import { useState, useRef, useEffect } from 'react'

interface AudioPlayerProps {
  src: string
  title?: string
  artist?: string
}

export function AudioPlayer({ src, title, artist }: AudioPlayerProps) {
  const audioRef = useRef<HTMLAudioElement>(null)
  const [playing, setPlaying] = useState(false)
  const [currentTime, setCurrentTime] = useState(0)
  const [duration, setDuration] = useState(0)
  const [volume, setVolume] = useState(1)

  useEffect(() => {
    const audio = audioRef.current
    if (!audio) return

    const updateTime = () => setCurrentTime(audio.currentTime)
    const updateDuration = () => setDuration(audio.duration)

    audio.addEventListener('timeupdate', updateTime)
    audio.addEventListener('loadedmetadata', updateDuration)
    audio.addEventListener('ended', () => setPlaying(false))

    return () => {
      audio.removeEventListener('timeupdate', updateTime)
      audio.removeEventListener('loadedmetadata', updateDuration)
      audio.removeEventListener('ended', () => setPlaying(false))
    }
  }, [])

  const togglePlay = () => {
    if (!audioRef.current) return

    if (playing) {
      audioRef.current.pause()
    } else {
      audioRef.current.play()
    }
    setPlaying(!playing)
  }

  const handleSeek = (e: React.ChangeEvent<HTMLInputElement>) => {
    const time = parseFloat(e.target.value)
    setCurrentTime(time)
    if (audioRef.current) {
      audioRef.current.currentTime = time
    }
  }

  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const vol = parseFloat(e.target.value)
    setVolume(vol)
    if (audioRef.current) {
      audioRef.current.volume = vol
    }
  }

  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    return `${mins}:${secs.toString().padStart(2, '0')}`
  }

  return (
    <div className="bg-white rounded-lg shadow-lg p-6 max-w-md">
      <audio ref={audioRef} src={src} />

      {/* Track Info */}
      {(title || artist) && (
        <div className="mb-4">
          {title && <h3 className="font-semibold text-lg">{title}</h3>}
          {artist && <p className="text-gray-600 text-sm">{artist}</p>}
        </div>
      )}

      {/* Progress Bar */}
      <div className="mb-4">
        <input
          type="range"
          min="0"
          max={duration || 0}
          value={currentTime}
          onChange={handleSeek}
          className="w-full"
        />
        <div className="flex justify-between text-sm text-gray-600 mt-1">
          <span>{formatTime(currentTime)}</span>
          <span>{formatTime(duration)}</span>
        </div>
      </div>

      {/* Controls */}
      <div className="flex items-center gap-4">
        <button
          onClick={togglePlay}
          className="w-12 h-12 bg-blue-600 text-white rounded-full flex items-center justify-center hover:bg-blue-700"
        >
          {playing ? '⏸️' : '▶️'}
        </button>

        <div className="flex items-center gap-2 flex-1">
          <span className="text-sm">🔊</span>
          <input
            type="range"
            min="0"
            max="1"
            step="0.1"
            value={volume}
            onChange={handleVolumeChange}
            className="flex-1"
          />
        </div>
      </div>
    </div>
  )
}

Podcast Player

// components/PodcastPlayer.tsx
'use client'
import { useState } from 'react'
import { AudioPlayer } from './AudioPlayer'

interface Episode {
  id: string
  title: string
  description: string
  audioUrl: string
  duration: number
  publishedAt: string
}

export function PodcastPlayer({ episodes }: { episodes: Episode[] }) {
  const [currentEpisode, setCurrentEpisode] = useState<Episode>(episodes[0])

  return (
    <div>
      <AudioPlayer
        src={currentEpisode.audioUrl}
        title={currentEpisode.title}
      />

      <div className="mt-6">
        <h3 className="font-semibold mb-4">Episodes</h3>
        <div className="space-y-2">
          {episodes.map((episode) => (
            <button
              key={episode.id}
              onClick={() => setCurrentEpisode(episode)}
              className={`w-full text-left p-4 rounded-lg ${
                currentEpisode.id === episode.id
                  ? 'bg-blue-100 border-2 border-blue-600'
                  

...
Read full content

Repository Stats

Stars7
Forks6
LicenseMIT License