read_files.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package read
  2. import (
  3. "os"
  4. "fmt"
  5. "io/ioutil"
  6. "path/filepath"
  7. tag "github.com/dhowden/tag"
  8. duration "github.com/felamaslen/go-music-player/pkg/read/duration"
  9. )
  10. type Song struct {
  11. title, artist, album string
  12. length int
  13. }
  14. func ReadFile(fileName string) (song *Song, err error) {
  15. file, errFile := os.Open(fileName)
  16. if errFile != nil {
  17. return &Song{}, errFile
  18. }
  19. defer file.Close()
  20. tags, errTags := tag.ReadFrom(file)
  21. if errTags != nil {
  22. return &Song{}, errTags
  23. }
  24. result := Song{
  25. title: tags.Title(),
  26. artist: tags.Artist(),
  27. album: tags.Album(),
  28. length: duration.GetSongDuration(file, tags),
  29. }
  30. return &result, nil
  31. }
  32. func ReadMultipleFiles(files chan string) chan *Song {
  33. songs := make(chan *Song)
  34. go func() {
  35. defer close(songs)
  36. for {
  37. select {
  38. case file, more := <- files:
  39. if more {
  40. song, err := ReadFile(file)
  41. if err == nil {
  42. songs <- song
  43. } else {
  44. fmt.Printf("Error reading file (%s): %s\n", file, err)
  45. }
  46. } else {
  47. return
  48. }
  49. }
  50. }
  51. }()
  52. return songs
  53. }
  54. func isValidFile(file string) bool {
  55. // TODO: support FLAC/MP3
  56. return filepath.Ext(file) == ".ogg"
  57. }
  58. func recursiveDirScan(directory string, output chan string, root bool) {
  59. files, err := ioutil.ReadDir(directory)
  60. if err != nil {
  61. fmt.Printf("Error scanning directory (%s): %s", directory, err)
  62. return
  63. }
  64. for _, file := range(files) {
  65. relativePath := filepath.Join(directory, file.Name())
  66. if file.IsDir() {
  67. recursiveDirScan(relativePath, output, false)
  68. } else if isValidFile(file.Name()) {
  69. output <- relativePath
  70. }
  71. }
  72. if (root) {
  73. close(output)
  74. }
  75. }
  76. func ScanDirectory(directory string) chan string {
  77. files := make(chan string)
  78. go func() {
  79. recursiveDirScan(directory, files, true)
  80. }()
  81. return files
  82. }