stream 播放支持选择 ffmpeg 配置

组件化 manage-database
This commit is contained in:
2021-05-24 01:06:40 +08:00
parent 85513ece62
commit ccf1566cc9
4 changed files with 165 additions and 23 deletions

View File

@@ -10,6 +10,7 @@ import (
"os"
"os/exec"
"strconv"
"strings"
)
type API struct {
@@ -19,6 +20,20 @@ type API struct {
APIConfig APIConfig
}
type FfmpegConfigs struct {
FfmpegConfigs map[string]*FfmpegConfig `json:"ffmpeg_configs"`
}
type AddFfmpegConfigRequest struct {
Token string `json:"token"`
FfmpegConfig FfmpegConfig `json:"ffmpeg_config"`
}
type FfmpegConfig struct {
Name string `json:"name"`
Args string `json:"args"`
}
type Status struct {
Status string `json:"status,omitempty"`
}
@@ -310,6 +325,12 @@ func (api *API) HandleGetFileStream(w http.ResponseWriter, r *http.Request) {
api.HandleErrorString(w, r, `parameter "id" should be an integer`)
return
}
configs := q["config"]
if len(configs) == 0 {
api.HandleErrorString(w, r, `parameter "config" can't be empty`)
return
}
configName := configs[0]
file, err := api.Db.GetFile(int64(id))
if err != nil {
api.HandleError(w, r, err)
@@ -322,16 +343,19 @@ func (api *API) HandleGetFileStream(w http.ResponseWriter, r *http.Request) {
return
}
log.Println("[api] Stream file", path)
log.Println("[api] Stream file", path, configName)
cmd := exec.Command("ffmpeg",
"-i", path,
"-c:a", "libopus",
"-ab", "128k",
"-vn",
"-f", "matroska",
"-",
)
ffmpegConfig, ok := api.APIConfig.FfmpegConfigs[configName]
if !ok {
api.HandleErrorStringCode(w, r, `ffmpeg config not found`, 404)
return
}
args := strings.Split(ffmpegConfig.Args, " ")
startArgs := []string {"-i", path}
endArgs := []string {"-vn", "-f", "matroska", "-"}
ffmpegArgs := append(startArgs, args...)
ffmpegArgs = append(ffmpegArgs, endArgs...)
cmd := exec.Command("ffmpeg", ffmpegArgs...)
cmd.Stdout = w
err = cmd.Run()
if err != nil {
@@ -409,10 +433,56 @@ func (api *API) HandleGetFile(w http.ResponseWriter, r *http.Request) {
io.Copy(w, src)
}
func (api *API) HandleGetFfmpegConfigs(w http.ResponseWriter, r *http.Request) {
log.Println("[api] Get ffmpeg config list")
ffmpegConfigs:= &FfmpegConfigs{
FfmpegConfigs: api.APIConfig.FfmpegConfigs,
}
json.NewEncoder(w).Encode(&ffmpegConfigs)
}
func (api *API) HandleAddFfmpegConfig(w http.ResponseWriter, r *http.Request) {
addFfmpegConfigRequest := AddFfmpegConfigRequest{}
err := json.NewDecoder(r.Body).Decode(&addFfmpegConfigRequest)
if err != nil {
api.HandleError(w, r, err)
return
}
// check token
err = api.CheckToken(w, r, addFfmpegConfigRequest.Token)
if err != nil {
return
}
// check name and args not null
if addFfmpegConfigRequest.FfmpegConfig.Name == "" {
api.HandleErrorString(w, r, `"ffmpeg_config.name" can't be empty`)
return
}
if addFfmpegConfigRequest.FfmpegConfig.Args == "" {
api.HandleErrorString(w, r, `"ffmpeg_config.args" can't be empty`)
return
}
log.Println("[api] Add ffmpeg config")
api.APIConfig.FfmpegConfigs[addFfmpegConfigRequest.FfmpegConfig.Name] = &addFfmpegConfigRequest.FfmpegConfig
api.HandleOK(w, r)
}
func NewAPIConfig() (APIConfig) {
apiConfig := APIConfig{
FfmpegConfigs: make(map[string]*FfmpegConfig),
}
return apiConfig
}
type APIConfig struct {
DatabaseName string
Addr string
Token string
DatabaseName string `json:"database_name"`
Addr string `json:"addr"`
Token string `json:"token"`
FfmpegConfigs map[string]*FfmpegConfig `json:"ffmpeg_configs"`
}
func NewAPI(apiConfig APIConfig) (*API, error) {
@@ -444,9 +514,11 @@ func NewAPI(apiConfig APIConfig) (*API, error) {
apiMux.HandleFunc("/get_files_in_folder", api.HandleGetFilesInFolder)
apiMux.HandleFunc("/get_random_files", api.HandleGetRandomFiles)
apiMux.HandleFunc("/get_file_stream", api.HandleGetFileStream)
apiMux.HandleFunc("/get_ffmpeg_config_list", api.HandleGetFfmpegConfigs)
// below needs token
apiMux.HandleFunc("/walk", api.HandleWalk)
apiMux.HandleFunc("/reset", api.HandleReset)
apiMux.HandleFunc("/add_ffmpeg_config", api.HandleAddFfmpegConfig)
mux.Handle("/api/v1/", http.StripPrefix("/api/v1", apiMux))
mux.Handle("/web/", http.StripPrefix("/web", http.FileServer(http.Dir("web"))))