npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ziplayer

v0.2.4

Published

A modular Discord voice player with plugin system

Downloads

541

Readme

ziplayer

A modular Discord voice player with plugin system for @discordjs/voice.

Features

  • 🎵 Plugin-based architecture - Easy to extend with new sources
  • 🎶 Multiple source support - YouTube, SoundCloud, Spotify (with fallback)
  • 🔊 Queue management - Add, remove, shuffle, clear
  • 🎚️ Volume control - 0-200% volume range
  • ⏯️ Playback control - Play, pause, resume, stop, skip
  • 🔁 Auto play - Automatically replay the queue when it ends
  • 🔂 Loop control - Repeat a single track or the entire queue
  • 📊 Progress bar - Display playback progress with customizable icons
  • 🔔 Event-driven - Rich event system for all player actions
  • 🎭 Multi-guild support - Manage players across multiple Discord servers
  • 🗃️ User data - Attach custom data to each player for later use
  • 🔌 Lavalink - Support manage an external Lavalink JVM node
  • 🎛️ Audio Filters - Apply real-time audio effects using FFmpeg (bassboost, nightcore, etc.)

Installation

npm install ziplayer @ziplayer/plugin @ziplayer/extension @discordjs/voice discord.js

Quick Start

import { PlayerManager } from "ziplayer";
import { SoundCloudPlugin, YouTubePlugin, SpotifyPlugin } from "@ziplayer/plugin";
import { voiceExt } from "@ziplayer/extension";

const manager = new PlayerManager({
	plugins: [new SoundCloudPlugin(), new YouTubePlugin(), new SpotifyPlugin()],
	extensions: [
		new voiceExt(null, {
			lang: "vi-VN",
			minimalVoiceMessageDuration: 1,
			postSilenceDelayMs: 2000,
		}),
	],
});

// Create player
const player = await manager.create(guildId, {
	leaveOnEnd: true,
	leaveTimeout: 30000,
	userdata: { channel: textChannel }, // store channel for events
	// Choose extensions for this player (by name or instances)
	extensions: ["voiceExt"],
	// Apply audio filters
	filters: ["bassboost", "normalize"],
});

// Connect and play
await player.connect(voiceChannel);
await player.play("Never Gonna Give You Up", userId);

// Play a full YouTube playlist
await player.play("https://www.youtube.com/playlist?list=PL123", userId);

// Enable autoplay
player.queue.autoPlay(true);

// Play a full SoundCloud playlist
await player.play("https://soundcloud.com/artist/sets/playlist", userId);

// Events
player.on("willPlay", (player, track) => {
	console.log(`Up next: ${track.title}`);
});
player.on("trackStart", (player, track) => {
	console.log(`Now playing: ${track.title}`);
	player.userdata?.channel?.send(`Now playing: ${track.title}`);
});

// Audio Filters
player.filter.applyFilter("bassboost"); // Apply bass boost
player.filter.applyFilter("nightcore"); // Apply nightcore effect
player.filter.removeFilter("bassboost"); // Remove specific filter
player.filter.clearFilters(); // Clear all filters

// Apply custom filter
player.filter.applyFilter({
	name: "custom",
	ffmpegFilter: "volume=1.5,treble=g=5",
	description: "Volume boost + treble boost",
});

// Receive transcripts
manager.on("voiceCreate", (player, evt) => {
	console.log(`User ${evt.userId} said: ${evt.content}`);
});

TTS (Interrupt Mode)

Play short text-to-speech messages without losing music progress. The player pauses music, plays TTS on a dedicated AudioPlayer, then resumes.

  • Requirements: @ziplayer/plugin with TTSPlugin installed and registered in PlayerManager.
import { PlayerManager } from "ziplayer";
import { TTSPlugin, YouTubePlugin, SoundCloudPlugin, SpotifyPlugin } from "@ziplayer/plugin";

const manager = new PlayerManager({
	plugins: [new TTSPlugin({ defaultLang: "vi" }), new YouTubePlugin(), new SoundCloudPlugin(), new SpotifyPlugin()],
});

// Create a player with TTS interrupt enabled
const player = await manager.create(guildId, {
	tts: {
		createPlayer: true, // pre-create the internal TTS AudioPlayer
		interrupt: true, // pause music, swap to TTS, then resume
		volume: 1, // 1 => 100%
	},
});

await player.connect(voiceChannel);

// Trigger TTS by playing a TTS query (depends on your TTS plugin)
await player.play("tts: xin chào mọi người", userId);

// Listen to TTS lifecycle events
manager.on("ttsStart", (plr, { track }) => console.log("TTS start", track?.title));
manager.on("ttsEnd", (plr) => console.log("TTS end"));

Notes

  • The detection uses track.source that includes "tts" or query starting with tts:.
  • If you need more control, call player.interruptWithTTSTrack(track) after building a TTS track via your plugin.
  • For CPU-heavy TTS generation, consider offloading to worker_threads or a separate process and pass a stream/buffer to the plugin.

Player Lifecycle Overview

PlayerManager.create(guild, opts)
        │
        ▼
[Player constructor]
 - setup event listeners
 - freeze ExtensionContext { player, manager }
 - register plugins
        │
        ▼
attachExtension(ext)
 - set ext.player
 - ext.onRegister?(context)
 - ext.active?(...) → false ⇒ detach
        │
        ▼
player.play(query, by)
 - runBeforePlayHooks → extensions may mutate query/tracks/start Lavalink
 - resolve track list / queue updates / TTS interrupt check
 - extensionsProvideStream → extension stream overrides plugin pipeline
 - plugin.getStream / getFallback
        │
        ▼
Audio playback
 - trackStart / queue events emitted
 - runAfterPlayHooks with final outcome
        │
        ▼
player.destroy()
 - stop audio/voice / clear queue & plugins
 - ext.onDestroy?(context) for each attached extension
 - emit playerDestroy & cleanup references

This diagram shows how custom extensions (voice, lyrics, Lavalink, etc.) integrate across the full player lifecycle and where their hooks are invoked.

Lavalink Process

Use lavalinkExt when you need ZiPlayer to manage an external Lavalink JVM node. The extension starts, stops, and optionally restarts the Lavalink jar and forwards lifecycle events through the manager/player.

import { PlayerManager } from "ziplayer";
import { lavalinkExt } from "@ziplayer/extension";

const lavalink = new lavalinkExt(null, {
	nodes: [
		{
			identifier: "locallavalink",
			password: "youshallnotpass",
			host: "localhost",
			port: 2333,
			secure: false,
		},
	],
	client: client,
	searchPrefix: "scsearch",
});

const manager = new PlayerManager({
	extensions: ["lavalinkExt"],
});

Events

All player events are forwarded through the PlayerManager:

  • trackStart - When a track starts playing
  • willPlay - Before a track begins playing
  • trackEnd - When a track finishes
  • queueEnd - When the queue is empty
  • playerError - When an error occurs
  • queueAdd - When a track is added
  • volumeChange - When volume changes
  • And more...

Useful Links

Example | Repo | Package | Plugin | Extension

License

MIT License