198 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package gavalink
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 	"os"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	// TrackLoaded is a Tracks Type for a succesful single track load
 | |
| 	TrackLoaded = "TRACK_LOADED"
 | |
| 	// PlaylistLoaded is a Tracks Type for a succseful playlist load
 | |
| 	PlaylistLoaded = "PLAYLIST_LOADED"
 | |
| 	// SearchResult is a Tracks Type for a search containing many tracks
 | |
| 	SearchResult = "SEARCH_RESULT"
 | |
| 	// NoMatches is a Tracks Type for a query yielding no matches
 | |
| 	NoMatches = "NO_MATCHES"
 | |
| 	// LoadFailed is a Tracks Type for an internal Lavalink error
 | |
| 	LoadFailed = "LOAD_FAILED"
 | |
| )
 | |
| 
 | |
| // Tracks contains data for a Lavalink Tracks response
 | |
| type Tracks struct {
 | |
| 	// Type contains the type of response
 | |
| 	//
 | |
| 	// This will be one of TrackLoaded, PlaylistLoaded, SearchResult,
 | |
| 	// NoMatches, or LoadFailed
 | |
| 	Type         string        `json:"loadType"`
 | |
| 	PlaylistInfo *PlaylistInfo `json:"playlistInfo"`
 | |
| 	Tracks       []*Track      `json:"tracks"`
 | |
| }
 | |
| 
 | |
| // PlaylistInfo contains information about a loaded playlist
 | |
| type PlaylistInfo struct {
 | |
| 	// Name is the friendly of the playlist
 | |
| 	Name string `json:"name"`
 | |
| 	// SelectedTrack is the index of the track that loaded the playlist,
 | |
| 	// if one is present.
 | |
| 	SelectedTrack int `json:"selectedTrack"`
 | |
| }
 | |
| 
 | |
| // Track contains information about a loaded track
 | |
| type Track struct {
 | |
| 	// Data contains the base64 encoded Lavaplayer track
 | |
| 	Data string     `json:"track"`
 | |
| 	Info *TrackInfo `json:"info"`
 | |
| }
 | |
| 
 | |
| // TrackInfo contains more data about a loaded track
 | |
| type TrackInfo struct {
 | |
| 	Identifier string        `json:"identifier"`
 | |
| 	Title      string        `json:"title"`
 | |
| 	Author     string        `json:"author"`
 | |
| 	URI        string        `json:"uri"`
 | |
| 	Seekable   bool          `json:"isSeekable"`
 | |
| 	Stream     bool          `json:"isStream"`
 | |
| 	Length     time.Duration `json:"length"`
 | |
| 	Position   int           `json:"position"`
 | |
| }
 | |
| 
 | |
| func (t *TrackInfo) MarshalJSON() ([]byte, error) {
 | |
| 	type Alias TrackInfo
 | |
| 	return json.Marshal(&struct {
 | |
| 		Length int64 `json:"length"`
 | |
| 		*Alias
 | |
| 	}{
 | |
| 		Length: int64(t.Length / time.Millisecond),
 | |
| 		Alias:  (*Alias)(t),
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func (t *TrackInfo) UnmarshalJSON(data []byte) error {
 | |
| 	type Alias TrackInfo
 | |
| 	aux := &struct {
 | |
| 		Length int64 `json:"length"`
 | |
| 		*Alias
 | |
| 	}{
 | |
| 		Alias: (*Alias)(t),
 | |
| 	}
 | |
| 	if err := json.Unmarshal(data, &aux); err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	t.Length = time.Duration(aux.Length) * time.Millisecond
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	opVoiceUpdate       = "voiceUpdate"
 | |
| 	opUserJoin          = "userJoin"
 | |
| 	opUserLeave         = "userLeave"
 | |
| 	opUserListen        = "userListen"
 | |
| 	opPlay              = "play"
 | |
| 	opStop              = "stop"
 | |
| 	opPause             = "pause"
 | |
| 	opSeek              = "seek"
 | |
| 	opVolume            = "volume"
 | |
| 	opDestroy           = "destroy"
 | |
| 	opPlayerUpdate      = "playerUpdate"
 | |
| 	opEvent             = "event"
 | |
| 	opStats             = "stats"
 | |
| 	eventTrackStart     = "TrackStartEvent"
 | |
| 	eventTrackEnd       = "TrackEndEvent"
 | |
| 	eventTrackException = "TrackExceptionEvent"
 | |
| 	eventTrackStuck     = "TrackStuckEvent"
 | |
| 	eventVoiceProcessed = "VoiceProcessedEvent"
 | |
| )
 | |
| 
 | |
| // Exception is a message from the Lavalink server
 | |
| type Exception struct {
 | |
| 	Message  string
 | |
| 	Severity string
 | |
| 	Cause    string
 | |
| }
 | |
| 
 | |
| // VoiceServerUpdate is a raw Discord VOICE_SERVER_UPDATE event
 | |
| type VoiceServerUpdate struct {
 | |
| 	GuildID  string `json:"guild_id"`
 | |
| 	Endpoint string `json:"endpoint"`
 | |
| 	Token    string `json:"token"`
 | |
| }
 | |
| 
 | |
| // VoiceProcessingData is an event containing methods to easily download captured voice data
 | |
| type VoiceProcessingData struct {
 | |
| 	io.ReadCloser
 | |
| 
 | |
| 	node *Node
 | |
| 
 | |
| 	UserID string
 | |
| 	URL    string
 | |
| 	File   string
 | |
| 
 | |
| 	res *http.Response
 | |
| }
 | |
| 
 | |
| func (v *VoiceProcessingData) open() error {
 | |
| 	req, err := http.NewRequest(http.MethodGet, v.URL, nil)
 | |
| 
 | |
| 	req.Header.Set("Authorization", v.node.config.Password)
 | |
| 
 | |
| 	res, err := v.node.client.Do(req)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	v.res = res
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (v *VoiceProcessingData) Close() error {
 | |
| 	if v.res != nil {
 | |
| 		return v.res.Body.Close()
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (v *VoiceProcessingData) Read(buf []byte) (n int, err error) {
 | |
| 	if v.res == nil {
 | |
| 		err = v.open()
 | |
| 
 | |
| 		if err != nil {
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	n, err = v.res.Body.Read(buf)
 | |
| 
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (v *VoiceProcessingData) SaveTo(file string) error {
 | |
| 	f, err := os.Create(file)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	defer f.Close()
 | |
| 
 | |
| 	if v.res == nil {
 | |
| 		err = v.open()
 | |
| 
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	defer v.res.Body.Close()
 | |
| 
 | |
| 	_, err = io.Copy(f, v.res.Body)
 | |
| 
 | |
| 	return err
 | |
| }
 |