可配置 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.exe
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 以上的值似乎对编码音频没有效果。
#### api_config.json 说明
#### config.json 说明
- `database_name` 字符串类型,指定 sqlite3 单文件数据库的位置,如果不存在则会自动创建。
- `addr` api 服务监听端口,该参数会被传入 `http.Serve.Addr`
- `token` 字符串,作为管理密码
- `ffmpeg_configs`,字典,其键是 ffmpeg 配置的名称,其值是放入 `ffmpeg -i input.mp3 -vn [此处] -f matroska -` 的参数,类型是字符串。 **注意:** 前端会按键名来排序配置列表,并以列表中的第一项作为默认配置。
- `file_life_time` 临时文件生存时间超过该时间没有访问该临时文件tmpfs 将删除此文件。
- `cleaner_internal` 清理器的检查间隔。
- `root` 存放该临时文件目录, **Windows 用户请替换成合适的目录。**
### 前端使用

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"`
}
func NewAPI(apiConfig APIConfig) (*API, error) {
func NewAPI(apiConfig APIConfig, tmpfsConfig tmpfs.TmpfsConfig) (*API, error) {
var err error
db, err := database.NewDatabase(apiConfig.DatabaseName)
@@ -696,7 +696,7 @@ func NewAPI(apiConfig APIConfig) (*API, error) {
},
APIConfig: apiConfig,
}
api.Tmpfs = tmpfs.NewTmpfs()
api.Tmpfs = tmpfs.NewTmpfs(tmpfsConfig)
// mount api
apiMux.HandleFunc("/hello", api.HandleOK)

View File

@@ -11,22 +11,29 @@ import (
type Tmpfs struct {
record map[string]int64
Root string
FileLifeTime int64
CleanerInternal int64
Config TmpfsConfig
wg sync.WaitGroup
}
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{
record: make(map[string]int64),
FileLifeTime: 10*60, // ! important
CleanerInternal: 1,
Root: "/tmp/",
Config: config,
}
tmpfs.wg.Add(1)
go tmpfs.Cleaner()
@@ -47,7 +54,7 @@ func (tmpfs *Tmpfs) Cleaner() {
for {
now := time.Now().Unix()
for key, value := range tmpfs.record {
if now - value > tmpfs.FileLifeTime {
if now - value > tmpfs.Config.FileLifeTime {
err = os.Remove(key)
if err != nil {
log.Println("[tmpfs] Failed to remove file", err)

26
main.go
View File

@@ -5,34 +5,44 @@ import (
"flag"
"log"
"msw-open-music/internal/pkg/api"
"msw-open-music/internal/pkg/tmpfs"
"os"
)
var APIConfigFilePath string
var ConfigFilePath string
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() {
var err error
flag.Parse()
apiConfig := api.NewAPIConfig()
apiConfigFile, err := os.Open(APIConfigFilePath)
config := Config{}
configFile, err := os.Open(ConfigFilePath)
if err != nil {
log.Fatal(err)
}
err = json.NewDecoder(apiConfigFile).Decode(&apiConfig)
err = json.NewDecoder(configFile).Decode(&config)
if err != nil {
log.Fatal(err)
}
apiConfigFile.Close()
configFile.Close()
api, err := api.NewAPI(apiConfig)
api, err := api.NewAPI(config.APIConfig, config.TmpfsConfig)
if err != nil {
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())
}