commit 2fd50cd77ccdb32dcb67917594e395a8fc6f816c
parent 7cda7146def9244f915310fc1f6c22d7e1acfef4
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date: Wed, 21 Nov 2018 15:27:12 +1300
[~] Use Engine instead of Transcoder; and accpet Fuzz value in http
request.
Diffstat:
4 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/cmd/desktop/giffer.go b/cmd/desktop/giffer.go
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
+ "io/ioutil"
"path/filepath"
"strings"
@@ -15,7 +16,7 @@ import (
// Giffer wraps the giffer business logic.
type Giffer struct {
*giffer.Downloader
- *giffer.Transcoder
+ *giffer.Engine
Store GifStore
}
@@ -30,11 +31,11 @@ type GifStore interface {
func (g Giffer) GififyURL(
url string,
start, end, fps float64,
- width, height int,
+ width, height, fuzz int,
q giffer.Quality,
) (*RenderedGif, error) {
if g.Store == nil {
- return g.make(url, start, end, fps, width, height, q)
+ return g.make(url, start, end, fps, width, height, fuzz, q)
}
key, err := hash(fmt.Sprintf("%s_%f_%f_%f_%d_%d_%d", url, start, end, fps, width, height, q))
if err != nil {
@@ -47,7 +48,7 @@ func (g Giffer) GififyURL(
if ok && img != nil {
return img, nil
}
- img, err = g.make(url, start, end, fps, width, height, q)
+ img, err = g.make(url, start, end, fps, width, height, fuzz, q)
if err != nil {
return nil, err
}
@@ -64,16 +65,27 @@ func (g Giffer) GififyURL(
func (g Giffer) make(
url string,
start, end, fps float64,
- width, height int,
+ width, height, fuzz int,
q giffer.Quality,
) (*RenderedGif, error) {
video, err := g.Download(url, start, end, q)
if err != nil {
return nil, errors.Wrap(err, "downloading")
}
- gif, err := g.Convert(video, fps, width, height, "gif", "gif")
+ gif, err := g.Transcode(video, start, end, width, height, fps)
+ if err != nil {
+ return nil, errors.Wrap(err, "transcoding video to gif")
+ }
+ if err := g.Crush(gif, fuzz); err != nil {
+ return nil, errors.Wrap(err, "optimising gif image")
+ }
+ defer g.Clean()
+ gifdata, err := ioutil.ReadFile(gif)
+ if err != nil {
+ return nil, errors.Wrap(err, "buffering gif")
+ }
img := &RenderedGif{
- Reader: gif,
+ Reader: bytes.NewBuffer(gifdata),
FileName: sanitiseFilepath(strings.Split(filepath.Base(video), ".")[0] + ".gif"),
}
return img, nil
diff --git a/cmd/desktop/main.go b/cmd/desktop/main.go
@@ -75,13 +75,15 @@ func main() {
App: &Giffer{
Downloader: &giffer.Downloader{
Dir: filepath.Join(filepath.Dir(ffmpeg), "tmp/downloads"),
- Debug: verbose,
FFmpeg: ffmpeg,
+ Debug: verbose,
Out: logf,
},
- Transcoder: &giffer.Transcoder{
- Debug: verbose,
- FFmpeg: ffmpeg,
+ Engine: &giffer.Engine{
+ FFmpeg: ffmpeg,
+ Convert: "convert",
+ Debug: verbose,
+ Out: logf,
},
Store: &gifdb{
Dir: filepath.Join(filepath.Dir(ffmpeg), "tmp/gifs"),
diff --git a/cmd/desktop/server.go b/cmd/desktop/server.go
@@ -25,7 +25,7 @@ type UI struct {
Router *mux.Router
Static http.Handler
Verbose bool
- Out io.Writer
+ Out io.Writer
gifmap map[string]http.Handler
init sync.Once
@@ -72,6 +72,7 @@ func (ui *UI) gifify() http.HandlerFunc {
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Output string `json:"output,omitempty"`
+ Fuzz int `json:"fuzz,omitempty"`
Quality int `json:"quality,omitempty"`
}
var req request
@@ -104,6 +105,7 @@ func (ui *UI) gifify() http.HandlerFunc {
req.FPS,
req.Width,
req.Height,
+ req.Fuzz,
giffer.Quality(req.Quality))
})
key := fmt.Sprintf("%d", h.Sum64())
@@ -112,8 +114,8 @@ func (ui *UI) gifify() http.HandlerFunc {
File string `json:"file"`
Info string `json:"info"`
}
- // FIXME(jfm): Should these endpoints be typed, instead of
- // relying on assumptions about the routing?
+ // FIXME(jfm): Should these endpoints be typed values, instead
+ // of relying on assumptions about the routing?
writeJSON(w, response{
File: fmt.Sprintf("/gifs/%s", key),
Info: fmt.Sprintf("/gifs/%s/info", key),
@@ -147,7 +149,7 @@ func (ui *UI) gifs() http.HandlerFunc {
// gif isn't ready to be downloaded, an appropriate message is returned.
type Gif struct {
Upgrader *websocket.Upgrader
- Out io.Writer
+ Out io.Writer
file *RenderedGif
subs map[*websocket.Conn]struct{}
@@ -253,4 +255,4 @@ func (g *Gif) logf(f string, v ...interface{}) (int, error) {
return 0, nil
}
return fmt.Fprintf(g.Out, f, v...)
-}
-\ No newline at end of file
+}
diff --git a/engine.go b/engine.go
@@ -81,7 +81,7 @@ func (eng *Engine) Cut(video string, cuts ...[2]int) (string, error) {
// Returns a filepath to the gif image.
func (eng *Engine) Transcode(
video string,
- start, end int,
+ start, end float64,
width, height int,
fps float64,
) (string, error) {
@@ -116,8 +116,8 @@ func (eng *Engine) Transcode(
}()
genPalette := eng.command(
eng.FFmpeg,
- "-ss", fmt.Sprintf("%d;omitempty", start),
- "-t", fmt.Sprintf("%d;omitempty", duration),
+ "-ss", fmt.Sprintf("%2f;omitempty", start),
+ "-t", fmt.Sprintf("%2f;omitempty", duration),
"-i", video,
"-vf", palettegen,
"-y", "palette.png",
@@ -127,8 +127,8 @@ func (eng *Engine) Transcode(
}
makeGif := eng.command(
eng.FFmpeg,
- "-ss", fmt.Sprintf("%d;omitempty", start),
- "-t", fmt.Sprintf("%d;omitempty", duration),
+ "-ss", fmt.Sprintf("%2f;omitempty", start),
+ "-t", fmt.Sprintf("%2f;omitempty", duration),
"-i", video, "-i", "palette.png",
"-lavfi", fmt.Sprintf("%s [x]; [x][1:v] paletteuse", filters),
"-y", output,
@@ -157,13 +157,12 @@ func (eng *Engine) Crush(gif string, fuzz int) error {
}
// Clean the temporary files.
-func (eng *Engine) Clean() error {
+func (eng *Engine) Clean() {
for _, f := range eng.Junk {
if err := os.Remove(f); err != nil {
- return err
+ eng.logf("clean: %v\n", err)
}
}
- return nil
}
// command creates a new exec.Cmd after removing empty arguments.