可配置 tmpfs

This commit is contained in:
2021-05-26 15:47:25 +08:00
parent 3a2db11b06
commit d93da6aa09
7 changed files with 66 additions and 35 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
msw-open-music msw-open-music
msw-open-music.exe msw-open-music.exe
dist dist
music.sqlite3

View File

@@ -26,16 +26,19 @@ Fork from `msw-file`,目前是一个音乐播放器。
### 后端使用 ### 后端使用
初次使用请配置 `api_config.json` **最重要的是配置 `token`** 初次使用请配置 `config.json` **最重要的是配置 `token`**
默认 ffmpeg 线程 `ffmpeg_threads` 为 1 ,大于 1 以上的值似乎对编码音频没有效果。 默认 ffmpeg 线程 `ffmpeg_threads` 为 1 ,大于 1 以上的值似乎对编码音频没有效果。
#### api_config.json 说明 #### config.json 说明
- `database_name` 字符串类型,指定 sqlite3 单文件数据库的位置,如果不存在则会自动创建。 - `database_name` 字符串类型,指定 sqlite3 单文件数据库的位置,如果不存在则会自动创建。
- `addr` api 服务监听端口,该参数会被传入 `http.Serve.Addr` - `addr` api 服务监听端口,该参数会被传入 `http.Serve.Addr`
- `token` 字符串,作为管理密码 - `token` 字符串,作为管理密码
- `ffmpeg_configs`,字典,其键是 ffmpeg 配置的名称,其值是放入 `ffmpeg -i input.mp3 -vn [此处] -f matroska -` 的参数,类型是字符串。 **注意:** 前端会按键名来排序配置列表,并以列表中的第一项作为默认配置。 - `ffmpeg_configs`,字典,其键是 ffmpeg 配置的名称,其值是放入 `ffmpeg -i input.mp3 -vn [此处] -f matroska -` 的参数,类型是字符串。 **注意:** 前端会按键名来排序配置列表,并以列表中的第一项作为默认配置。
- `file_life_time` 临时文件生存时间超过该时间没有访问该临时文件tmpfs 将删除此文件。
- `cleaner_internal` 清理器的检查间隔。
- `root` 存放该临时文件目录, **Windows 用户请替换成合适的目录。**
### 前端使用 ### 前端使用
@@ -359,4 +362,4 @@ Fork from `msw-file`,目前是一个音乐播放器。
- `/web/#/search_folders?folder_id=2614` - `/web/#/search_folders?folder_id=2614`
显示该文件夹中的文件, folder_id 是文件夹的唯一标识。 显示该文件夹中的文件, folder_id 是文件夹的唯一标识。

View File

@@ -1,13 +0,0 @@
{
"database_name": "/tmp/music.sqlite3",
"addr": ":8080",
"token": "!! config your very strong token here !!",
"ffmpeg_threads": 1,
"ffmpeg_configs": {
"0. OPUS 128k": {"args": "-c:a libopus -ab 128k"},
"OPUS 96k": {"args": "-c:a libopus -ab 96k"},
"OPUS 256k": {"args": "-c:a libopus -ab 256k"},
"AAC 128k": {"args": "-c:a aac -ab 128k"},
"AAC 256k": {"args": "-c:a aac -ab 256k"}
}
}

23
config.json Normal file
View File

@@ -0,0 +1,23 @@
{
"api": {
"database_name": "music.sqlite3",
"addr": ":8080",
"token": "!! config your very strong token here !!",
"ffmpeg_threads": 1,
"ffmpeg_configs": {
"0. OPUS 128k": {"args": "-c:a libopus -ab 128k"},
"1. OPUS 96k": {"args": "-c:a libopus -ab 96k"},
"2. OPUS 256k": {"args": "-c:a libopus -ab 256k"},
"3. OPUS 320k": {"args": "-c:a libopus -ab 320k"},
"4. OPUS 512k": {"args": "-c:a libopus -ab 512k"},
"5. AAC 128k": {"args": "-c:a aac -ab 128k"},
"6. AAC 256k": {"args": "-c:a aac -ab 256k"},
"7. 全损音质 32k": {"args": "-c:a libopus -ab 32k"}
}
},
"tmpfs": {
"file_life_time": 600,
"cleaner_internal": 1,
"root": "/tmp/"
}
}

View File

@@ -677,7 +677,7 @@ type APIConfig struct {
FfmpegConfigs map[string]*FfmpegConfig `json:"ffmpeg_configs"` FfmpegConfigs map[string]*FfmpegConfig `json:"ffmpeg_configs"`
} }
func NewAPI(apiConfig APIConfig) (*API, error) { func NewAPI(apiConfig APIConfig, tmpfsConfig tmpfs.TmpfsConfig) (*API, error) {
var err error var err error
db, err := database.NewDatabase(apiConfig.DatabaseName) db, err := database.NewDatabase(apiConfig.DatabaseName)
@@ -696,7 +696,7 @@ func NewAPI(apiConfig APIConfig) (*API, error) {
}, },
APIConfig: apiConfig, APIConfig: apiConfig,
} }
api.Tmpfs = tmpfs.NewTmpfs() api.Tmpfs = tmpfs.NewTmpfs(tmpfsConfig)
// mount api // mount api
apiMux.HandleFunc("/hello", api.HandleOK) apiMux.HandleFunc("/hello", api.HandleOK)

View File

@@ -11,22 +11,29 @@ import (
type Tmpfs struct { type Tmpfs struct {
record map[string]int64 record map[string]int64
Root string Config TmpfsConfig
FileLifeTime int64
CleanerInternal int64
wg sync.WaitGroup wg sync.WaitGroup
} }
func (tmpfs *Tmpfs) GetObjFilePath(id int64, configName string) (string) { func (tmpfs *Tmpfs) GetObjFilePath(id int64, configName string) (string) {
return filepath.Join(tmpfs.Root, strconv.FormatInt(id, 10) + "." + configName + ".ogg") return filepath.Join(tmpfs.Config.Root, strconv.FormatInt(id, 10) + "." + configName + ".ogg")
} }
func NewTmpfs() *Tmpfs { type TmpfsConfig struct {
FileLifeTime int64 `json:"file_life_time"`
CleanerInternal int64 `json:"cleaner_internal"`
Root string `json:"root"`
}
func NewTmpfsConfig() (*TmpfsConfig) {
config := &TmpfsConfig{}
return config
}
func NewTmpfs(config TmpfsConfig) *Tmpfs {
tmpfs := &Tmpfs{ tmpfs := &Tmpfs{
record: make(map[string]int64), record: make(map[string]int64),
FileLifeTime: 10*60, // ! important Config: config,
CleanerInternal: 1,
Root: "/tmp/",
} }
tmpfs.wg.Add(1) tmpfs.wg.Add(1)
go tmpfs.Cleaner() go tmpfs.Cleaner()
@@ -47,7 +54,7 @@ func (tmpfs *Tmpfs) Cleaner() {
for { for {
now := time.Now().Unix() now := time.Now().Unix()
for key, value := range tmpfs.record { for key, value := range tmpfs.record {
if now - value > tmpfs.FileLifeTime { if now - value > tmpfs.Config.FileLifeTime {
err = os.Remove(key) err = os.Remove(key)
if err != nil { if err != nil {
log.Println("[tmpfs] Failed to remove file", err) log.Println("[tmpfs] Failed to remove file", err)

26
main.go
View File

@@ -5,34 +5,44 @@ import (
"flag" "flag"
"log" "log"
"msw-open-music/internal/pkg/api" "msw-open-music/internal/pkg/api"
"msw-open-music/internal/pkg/tmpfs"
"os" "os"
) )
var APIConfigFilePath string var ConfigFilePath string
func init() { func init() {
flag.StringVar(&APIConfigFilePath, "apiconfig", "api_config.json", "API Config Json file") flag.StringVar(&ConfigFilePath, "config", "config.json", "backend config file path")
}
type Config struct {
APIConfig api.APIConfig `json:"api"`
TmpfsConfig tmpfs.TmpfsConfig `json:"tmpfs"`
} }
func main() { func main() {
var err error var err error
flag.Parse() flag.Parse()
apiConfig := api.NewAPIConfig()
apiConfigFile, err := os.Open(APIConfigFilePath) config := Config{}
configFile, err := os.Open(ConfigFilePath)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
err = json.NewDecoder(apiConfigFile).Decode(&apiConfig) err = json.NewDecoder(configFile).Decode(&config)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
apiConfigFile.Close() configFile.Close()
api, err := api.NewAPI(apiConfig) api, err := api.NewAPI(config.APIConfig, config.TmpfsConfig)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Println("Starting", apiConfig.DatabaseName, apiConfig.Addr, apiConfig.Token) log.Println("Starting",
config.APIConfig.DatabaseName,
config.APIConfig.Addr,
config.APIConfig.Token,
)
log.Fatal(api.Server.ListenAndServe()) log.Fatal(api.Server.ListenAndServe())
} }