voice_chat

package
v0.0.0-...-41ed81f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package voice_chat plays audio in Discord voice channels via Lavalink. Lavalink owns the voice WebSocket (DAVE/E2EE); the bot just forwards voice state events from discordgo and tells Lavalink what to play.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotInVoice   = errors.New("user is not in a voice channel")
	ErrNoTrackFound = errors.New("no playable track at that URL")
	// ErrAlreadyPlaying is returned by ResumeQueue when a track is already playing.
	ErrAlreadyPlaying = errors.New("already playing in this guild")
	// ErrVoiceTimeout means Discord didn't deliver VOICE_STATE / VOICE_SERVER —
	// retrying the join usually fixes it.
	ErrVoiceTimeout   = errors.New("voice connection didn't establish")
	ErrQueueFull      = errors.New("queue is full")
	ErrNothingPlaying = errors.New("nothing is playing")
	// ErrTrackFailed is distinct from ErrVoiceTimeout because retrying is
	// pointless — the track itself is the problem.
	ErrTrackFailed = errors.New("track failed to play")
)

Functions

func FormatPlayResult

func FormatPlayResult(r PlayResult, resumeCmd string) string

FormatPlayResult renders a PlayResult as a user-facing message. resumeCmd is the suggested resume command when r.WhileStopped is set.

func FriendlyPlayError

func FriendlyPlayError(err error) string

FriendlyPlayError maps a Player error to a short user-facing message. ErrTrackFailed stays brief because OnTrackException already announced the detail.

func IsUserFacingError

func IsUserFacingError(err error) bool

IsUserFacingError gates error-channel logging — true for routine user mistakes, false for genuine bugs.

Types

type PlayResult

type PlayResult struct {
	Title    string
	Queued   bool
	Position int // 1-indexed queue position when Queued; 0 otherwise
	// WhileStopped: bot was disconnected with a saved track; the queued URL won't
	// play until the user resumes.
	WhileStopped bool
	Playlist     *PlaylistInfo
}

PlayResult describes what Play did with the URL. Title/Queued/Position describe the first track; Playlist (non-nil for playlist URLs) carries batch totals.

type Player

type Player struct {
	// contains filtered or unexported fields
}

Player owns the disgolink client and per-guild queue / announce-channel state.

func New

func New(link disgolink.Client, session *discordgo.Session) *Player

New constructs a Player. Register OnTrackEnd and OnTrackException as disgolink listeners to wire up auto-advance and failure announcements.

func (*Player) ClearQueue

func (p *Player) ClearQueue(guildID string) (int, error)

ClearQueue wipes the upcoming queue and any saved/stopped track — a full session reset. Does NOT stop a currently-playing track. Returns the total number of tracks removed.

func (*Player) OnTrackEnd

func (p *Player) OnTrackEnd(player disgolink.Player, e lavalink.TrackEndEvent)

OnTrackEnd (disgolink listener) advances the queue and posts "Now playing". On an empty queue it disconnects and forgets the announce channel.

func (*Player) OnTrackException

func (p *Player) OnTrackException(player disgolink.Player, e lavalink.TrackExceptionEvent)

OnTrackException (disgolink listener) signals any in-flight Play so it can bail out of the voice-connect wait, and posts a failure message to the announce channel.

func (*Player) Play

func (p *Player) Play(ctx context.Context, guildID, channelID, userID, url string) (PlayResult, error)

Play loads url and either starts playback or appends to the queue. channelID is remembered as the destination for auto-advance "Now playing" messages; pass empty to leave it untouched. Voice-connect timeouts retry transparently via cycleVoice.

func (*Player) Queue

func (p *Player) Queue(guildID string) (QueueSnapshot, error)

func (*Player) ResumeQueue

func (p *Player) ResumeQueue(ctx context.Context, guildID, channelID, userID string) (lavalink.Track, error)

ResumeQueue rejoins userID's voice channel and restarts the Stop-saved track from position 0; OnTrackEnd then walks the upcoming queue normally. channelID becomes the new announce destination. Errors: ErrAlreadyPlaying, ErrNothingPlaying, ErrNotInVoice.

func (*Player) Skip

func (p *Player) Skip(ctx context.Context, guildID string) (skipped, next *lavalink.Track, err error)

Skip advances to the next queued track. If the queue is empty, playback stops and the bot leaves voice (caller detects via next == nil).

func (*Player) Stop

func (p *Player) Stop(ctx context.Context, guildID string) (changed bool, err error)

Stop snapshots the current track into pausedTracks and disconnects. The upcoming queue is left intact — ResumeQueue replays the saved track from position 0. Use ClearQueue for a full reset. changed=false means the bot was already stopped (idempotent). Returns ErrNothingPlaying when nothing is active AND no stopped session exists.

type PlaylistInfo

type PlaylistInfo struct {
	Name        string // may be empty if Lavalink didn't supply one
	TotalTracks int
	// QueuedTracks excludes the first track in the fresh-start path (it's playing,
	// not queued); less than TotalTracks if the queue cap was hit mid-batch.
	QueuedTracks int
}

PlaylistInfo describes a playlist that Play loaded and enqueued.

type QueueSnapshot

type QueueSnapshot struct {
	Current  *lavalink.Track
	Paused   *lavalink.Track
	Upcoming []lavalink.Track
}

QueueSnapshot is a read-only view of a guild's playback state. Current and Paused are mutually exclusive; Upcoming is copied, safe to read without a lock.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL