Golang结合ffmpeg实现动态视频编码时invalid character错误求助
问题排查及解决方案
你遇到的报错invalid character '-' in numeric literal是JSON反序列化阶段触发的错误,当前代码和请求逻辑存在多处错误,修正方案如下:
invalid character '-' in numeric literal
错误点逐一说明
- JSON解码用法错误:
Decode方法必须传入指针类型参数才能把解析结果写入结构体,你当前传入的是值类型encode,同时错误地将Decode返回的error赋值给了video变量,完全不符合预期。 - 依赖包缺失:代码中用到的
os、log、io/ioutil、os/exec、bytes包均未导入,会直接导致编译失败。 - 请求格式和解析逻辑不匹配:你Postman使用
form-data格式传参,但代码是按JSON格式解析请求体,格式不兼容直接触发JSON解析报错。 - 未定义变量:代码中创建输出文件用到的
encodeFile变量没有定义,执行到对应逻辑会直接崩溃。
修正后代码(适配JSON传本地文件路径场景)
package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "os" "os/exec" "github.com/gorilla/mux" ) type Encode struct { Video string `json:"video"` } func encodeFfmpeg(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") fmt.Println("Encoding Started") var encode Encode // 修正JSON解码逻辑,传入指针并处理错误 err := json.NewDecoder(r.Body).Decode(&encode) if err != nil { log.Println("JSON解析失败:", err) http.Error(w, "请求参数格式错误", http.StatusBadRequest) return } // 自定义输出文件路径 encodeFile := "out.avi" file, err := os.Open(encode.Video) if err != nil { log.Println("打开输入文件失败:", err) http.Error(w, "输入文件不存在", http.StatusBadRequest) return } defer file.Close() buf, err := ioutil.ReadAll(file) if err != nil { log.Fatalln("读取输入文件失败:", err) return } cmd := exec.Command("ffmpeg", "-i", "pipe:0", "-c:a", "libmp3lame", "-f", "avi", "pipe:1", ) resultBuffer := bytes.NewBuffer(make([]byte, 5*1024*1024)) cmd.Stderr = os.Stderr cmd.Stdout = resultBuffer stdin, err := cmd.StdinPipe() if err != nil { log.Fatalln("打开stdin管道失败:", err) return } err = cmd.Start() if err != nil { log.Fatalln("启动ffmpeg失败:", err) return } _, err = stdin.Write(buf) if err != nil { log.Fatalln("写入stdin失败:", err) return } err = stdin.Close() if err != nil { log.Fatalln("关闭stdin失败:", err) return } err = cmd.Wait() if err != nil { log.Fatalln("ffmpeg执行失败:", err) return } outputFile, err := os.Create(encodeFile) if err != nil { log.Fatalln("创建输出文件失败:", err) return } defer outputFile.Close() _, err = outputFile.Write(resultBuffer.Bytes()) if err != nil { log.Fatalln("写入输出文件失败:", err) return } json.NewEncoder(w).Encode(map[string]interface{}{ "status": "success", "statusCode": 200, "data": "Successfully Encoded file", }) } func main() { router := mux.NewRouter() router.HandleFunc("/encode", encodeFfmpeg).Methods("POST") fmt.Printf("Starting server at 8080 \n") http.ListenAndServe(":8080", router) }
请求操作说明
Postman请求按如下配置即可正常调用:
- 请求方法选POST,地址填
http://localhost:8080/encode - Body选
raw,格式选择JSON - 请求体填入如下内容,路径替换为服务端本地真实存在的视频文件路径:
{"video": "/your/local/path/video.mp4"}
执行请求后,转码后的文件会保存在服务端运行目录下的out.avi。
内容的提问来源于stack exchange,提问作者Ramesh S
相关产品推荐
相关产品推荐

