1
0
Fork 0

Create & Init Project...

master
502647092 2018-11-21 18:57:30 +08:00
commit ce2baaca4b
3 changed files with 133 additions and 0 deletions

18
Dockerfile Normal file
View File

@ -0,0 +1,18 @@
FROM golang:alpine AS build
WORKDIR /go/src/github.com/yumc.pw/cloud/ffmpeg-webapi
ADD main.go .
RUN go build -o main
FROM alpine:edge
LABEL maintainer="MiaoWoo<admin@yumc.pw>"
WORKDIR /root
RUN set -x && \
apk add --no-cache ca-certificates yasm ffmpeg && \
rm -rf /var/cache/apk/*
COPY --from=build /go/src/github.com/yumc.pw/cloud/ffmpeg-webapi/main ./main
CMD ./main

1
go.mod Normal file
View File

@ -0,0 +1 @@
module yumc.pw/cloud/ffmpeg-webapi

114
main.go Normal file
View File

@ -0,0 +1,114 @@
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))
}