115 lines
2.5 KiB
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))
|
|
}
|