This commit is contained in:
@@ -3,22 +3,32 @@ package config
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DatabasePath string
|
||||
CachePath string
|
||||
}
|
||||
|
||||
// LoadConfig loads configuration from environment variables
|
||||
func LoadConfig() *Config {
|
||||
cfg := &Config{
|
||||
DatabasePath: getEnv("DATABASE_PATH", "./butterfliu.db"),
|
||||
CachePath: getEnv("CACHE_PATH", "./cache"),
|
||||
}
|
||||
os.MkdirAll(cfg.CachePath, os.ModeAppend)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (self *Config) GetCachePath(cacheType string) string {
|
||||
path := path.Join(self.CachePath, cacheType)
|
||||
os.MkdirAll(path, os.ModeAppend)
|
||||
return path
|
||||
}
|
||||
|
||||
// getEnv gets an environment variable with a default value
|
||||
func getEnv(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
|
||||
@@ -41,3 +41,18 @@ func (c *SongController) Stream(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.ServeFile(w, r, mediaFile.Path)
|
||||
}
|
||||
|
||||
func (c *SongController) Cover(w http.ResponseWriter, r *http.Request) {
|
||||
paramID := chi.URLParam(r, "id")
|
||||
id, err := strconv.Atoi(paramID)
|
||||
if err != nil {
|
||||
http.Error(w, "无效的歌曲 ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
coverPath, err := c.service.GetCover(id)
|
||||
if err != nil {
|
||||
http.Error(w, "获取封面异常", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, r, coverPath)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"butterfliu/config"
|
||||
"butterfliu/internal/model"
|
||||
"butterfliu/internal/repository"
|
||||
"butterfliu/internal/util"
|
||||
"path"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type SongService struct {
|
||||
@@ -29,3 +33,13 @@ func (s *SongService) GetMediaFile(id int) (model.MediaFile, error) {
|
||||
}
|
||||
return s.mediaRepo.Get(song.MediaFileID)
|
||||
}
|
||||
|
||||
func (s *SongService) GetCover(id int) (string, error) {
|
||||
file, err := s.GetMediaFile(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
util.ExtractCover(file.Path, id)
|
||||
conf := config.LoadConfig()
|
||||
return path.Join(conf.GetCachePath("cover"), strconv.Itoa(id)+".jpg"), nil
|
||||
}
|
||||
|
||||
20
internal/util/ffmpeg.go
Normal file
20
internal/util/ffmpeg.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ExtractCover(filePath string, id int) bool {
|
||||
if _, err := exec.LookPath("ffmpeg"); err != nil {
|
||||
return false
|
||||
}
|
||||
coverPath := "cache/cover/" + strconv.Itoa(id) + ".jpg"
|
||||
cmd := exec.Command("ffmpeg", "-i", filePath, "-an", "-vcodec", "mjpeg", "-q:v", "5", "-f", "image2", "-y", coverPath)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
5
main.go
5
main.go
@@ -4,6 +4,7 @@ import (
|
||||
"butterfliu/internal/controller"
|
||||
"butterfliu/internal/repository"
|
||||
"butterfliu/internal/service"
|
||||
"butterfliu/config"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
@@ -12,7 +13,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := InitDB("./butterfliu.db")
|
||||
config := config.LoadConfig()
|
||||
err := InitDB(config.DatabasePath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -46,6 +48,7 @@ func main() {
|
||||
r.Route("/api/songs", func(r chi.Router) {
|
||||
r.Get("/", songController.GetAllWithDetails)
|
||||
r.Get("/{id}/stream", songController.Stream)
|
||||
r.Get("/{id}/cover", songController.Cover)
|
||||
})
|
||||
|
||||
r.Route("/api", func(r chi.Router) {
|
||||
|
||||
Reference in New Issue
Block a user