143
package main
import (
"fmt"
"github.com/faiface/beep"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"
"math/rand"
"os"
"strings"
"time"
)
var (
curdir string
done = make(chan bool)
)
func getallfiles() []string {
var files []string
f, err := os.Open(curdir)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
files, err = f.Readdirnames(0)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
f.Close()
var songs []string
for _, file := range files {
if file[len(file)-4:] == ".mp3" {
songs = append(songs, file)
}
}
return songs
}
func getargsongs() []string {
var songs []string
for _, song := range os.Args[1:] {
info, err := os.Stat(song)
if err == nil && len(song) > 4 && song[len(song)-4:] == ".mp3" && !info.IsDir() && info.Mode().IsRegular() {
songs = append(songs, song)
} else {
fmt.Println(song, "is not a valid mp3 file.")
}
}
return songs
}
func showqueue(songs []string) {
if len(songs) == 0 {
fmt.Println("\nEmpty queue.")
os.Exit(0)
}
var tmpstr string
tmpstr = strings.Split(songs[0], "/")[len(strings.Split(songs[0], "/"))-1]
tmpstr = tmpstr[:len(tmpstr)-4]
fmt.Printf("\nNow Playing:\n%s\n\n", tmpstr)
if len(songs) == 1 {
return
}
fmt.Println("Up Next:")
var loopmax int = 5
if len(songs) < loopmax {
loopmax = len(songs)
}
for i := 1; i < loopmax; i++ {
tmpstr = strings.Split(songs[i], "/")[len(strings.Split(songs[i], "/"))-1]
tmpstr = tmpstr[:len(tmpstr)-4]
fmt.Printf("%d: %s\n", i, tmpstr)
}
fmt.Println("")
}
func shuffle(songs *[]string) {
var tmpstr string
var tmpint int
for i := 0; i < len(*songs); i++ {
tmpint = rand.Intn(len(*songs))
tmpstr = (*songs)[i]
(*songs)[i] = (*songs)[tmpint]
(*songs)[tmpint] = tmpstr
}
}
func playlist(songs []string) {
for i := range songs {
showqueue(songs[i:])
play(songs[i])
}
}
func play(song string) {
file, _ := os.Open(song)
streamer, format, _ := mp3.Decode(file)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done = make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
streamer.Close()
file.Close()
}
func skipsong() {
var input string
for {
time.Sleep(200 * time.Millisecond)
fmt.Print("Enter 'skip' to skip the current song: ")
fmt.Scanln(&input)
if input == "skip" {
speaker.Clear()
done <- true
}
}
}
func main() {
tmpstr, err := os.Getwd()
if err != nil {
fmt.Println("An error occured while getting the directory.")
os.Exit(1)
}
curdir = tmpstr
var songs []string
if len(os.Args) <= 1 {
songs = getallfiles()
shuffle(&songs)
} else {
songs = getargsongs()
}
if len(songs) == 0 {
fmt.Println("No songs found.")
os.Exit(0)
}
go playlist(songs)
skipsong()
}