1
0
Fork 0
ffmpeg-webapi/main.go

115 lines
2.5 KiB
Go

package main
import (
"crypto/md5"
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"strconv"
"strings"
)
var tempDir *string
var ffmpeg = "ffmpeg"
func main() {
b := flag.String("b", ":8080", "Server Bind Address")
tempDir = flag.String("temp", os.TempDir(), "")
flag.Parse()
if _, err := exec.LookPath(ffmpeg); err != nil {
fmt.Printf("Error Can't Find %s Client...", ffmpeg)
return
}
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
if strings.HasPrefix(req.RequestURI, "/amr2mp3") {
amr2mp3(resp, req)
return
}
api(resp, req)
})
http.ListenAndServe(*b, nil)
fmt.Printf("FFmpeg WebInterface Listen on %s ...\n", *b)
}
func api(w http.ResponseWriter, r *http.Request) {
handleInternal(w, r, r.FormValue("o"), r.FormValue("t"))
}
func amr2mp3(w http.ResponseWriter, r *http.Request) {
handleInternal(w, r, "amr", "mp3")
}
func handleInternal(w http.ResponseWriter, r *http.Request, origin, target string) {
// Read Byte From File Or URL
bytes, err := readBytesFromRequest(r)
if err != nil {
w.Write([]byte("Error Read Bytes: " + err.Error()))
return
}
// Convert origin to target
out, err := convert(bytes, origin, target)
if err != nil {
w.Write([]byte("Error Handler: " + err.Error()))
return
}
w.Write(out)
}
func convert(in []byte, origin, target string) (out []byte, err error) {
source := *tempDir + "/" + fmt.Sprintf("ffmpeg-webapi-%s-%s", MD5(in), strconv.Itoa(len(in)))
amr := source + "." + origin
ioutil.WriteFile(amr, in, os.ModeAppend)
defer os.Remove(amr)
mp3 := source + "." + target
err = exec.Command(ffmpeg, "-i", amr, mp3).Run()
defer os.Remove(mp3)
if err != nil {
// Ignore Error Bucause ffmpeg will return not zero when amr to mp3
}
// check target file is exist if not maybe exec error
if _, err := exec.LookPath(mp3); err == nil {
return nil, err
}
return ioutil.ReadFile(mp3)
}
func readBytesFromRequest(r *http.Request) (out []byte, err error) {
var reader io.Reader
url := r.FormValue("url")
if url != "" {
fmt.Printf("[A2M] url request " + url + "\n")
var resp *http.Response
resp, err = http.Get(url)
if err != nil {
return nil, err
}
reader = resp.Body
} else {
fmt.Printf("[A2M] file request\n")
reader, _, err = r.FormFile("file")
if err != nil {
return nil, err
}
}
return ioutil.ReadAll(reader)
}
// MD5 生成32位MD5
func MD5(bytes []byte) string {
ctx := md5.New()
ctx.Write(bytes)
return hex.EncodeToString(ctx.Sum(nil))
}