commit 9385ac9a4d38d740bc836cc25b5074d5e00c8da0
parent 6ae2b35917c871e9d65259e1042bfb5611a90fb1
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date: Mon, 12 Nov 2018 18:53:09 +1300
[~] Cleanup hash code and respond to upstream api changes.
Diffstat:
| M | cmd/desktop/giffer.go | | | 91 | ++++++++++++++++--------------------------------------------------------------- |
1 file changed, 18 insertions(+), 73 deletions(-)
diff --git a/cmd/desktop/giffer.go b/cmd/desktop/giffer.go
@@ -3,16 +3,11 @@ package main
import (
"bytes"
"fmt"
- "image"
- "image/gif"
"io"
- "log"
"path/filepath"
"strings"
- "sync"
"github.com/OneOfOne/xxhash"
- "github.com/disintegration/imaging"
"github.com/jackmordaunt/giffer"
"github.com/pkg/errors"
)
@@ -41,14 +36,11 @@ func (g Giffer) GififyURL(
if g.Store == nil {
return g.make(url, start, end, fps, width, height, q)
}
- hasher := xxhash.New64()
- input := fmt.Sprintf("%s_%f_%f_%f_%d_%d_%d", url, start, end, fps, width, height, q)
- _, err := hasher.WriteString(input)
+ key, err := hash(fmt.Sprintf("%s_%f_%f_%f_%d_%d_%d", url, start, end, fps, width, height, q))
if err != nil {
- return nil, errors.Wrap(err, "hashing input")
+ return nil, err
}
- hash := fmt.Sprintf("%d", hasher.Sum64())
- img, ok, err := g.Store.Lookup(hash)
+ img, ok, err := g.Store.Lookup(key)
if err != nil {
return nil, errors.Wrap(err, "store lookup")
}
@@ -63,7 +55,7 @@ func (g Giffer) GififyURL(
Reader: bytes.NewBuffer([]byte(img.Reader.(*bytes.Buffer).String())),
FileName: img.FileName,
}
- if err := g.Store.Insert(hash, dup); err != nil {
+ if err := g.Store.Insert(key, dup); err != nil {
return nil, errors.Wrap(err, "inserting gif into store")
}
return img, nil
@@ -75,71 +67,14 @@ func (g Giffer) make(
width, height int,
q giffer.Quality,
) (*RenderedGif, error) {
- videofile, err := g.Download(url, q)
+ video, err := g.Download(url, q)
if err != nil {
return nil, errors.Wrap(err, "downloading")
}
- frames, err := g.Extract(videofile, start, end, fps)
- if err != nil {
- return nil, errors.Wrap(err, "extracting frames")
- }
- type processed struct {
- Img *image.Paletted
- Index int
- }
- images := make(chan processed)
- wg := &sync.WaitGroup{}
- wg.Add(len(frames))
- for ii, frame := range frames {
- ii := ii
- frame := frame
- go func() {
- defer wg.Done()
- if width != 0 || height != 0 {
- frame = imaging.Resize(frame, width, height, imaging.Box)
- }
- buf := bytes.Buffer{}
- if err := gif.Encode(&buf, frame, nil); err != nil {
- log.Printf("encoding gif: %v", err)
- return
- }
- tmpimg, err := gif.Decode(&buf)
- if err != nil {
- log.Printf("decoding gif: %v", err)
- return
- }
- images <- processed{
- Img: tmpimg.(*image.Paletted),
- Index: ii,
- }
- }()
- }
- go func() {
- wg.Wait()
- close(images)
- }()
- paletted := make([]*image.Paletted, len(frames))
- for frame := range images {
- paletted[frame.Index] = frame.Img
- }
- delays := make([]int, len(frames))
- delay := int(100 / fps)
- for ii := range delays {
- delays[ii] = delay
- }
- buf := bytes.NewBuffer(nil)
- cfg := &gif.GIF{
- Image: paletted,
- Delay: delays,
- LoopCount: 0,
- }
- if err := gif.EncodeAll(buf, cfg); err != nil {
- return nil, errors.Wrap(err, "encoding animated gif")
- }
+ gif, err := g.Convert(video, start, end, fps, width, height, "gif", "gif")
img := &RenderedGif{
- Reader: buf,
- // Keep the title but replace the .mp4 extension with .gif
- FileName: sanitiseFilepath(strings.Split(filepath.Base(videofile), ".")[0] + ".gif"),
+ Reader: gif,
+ FileName: sanitiseFilepath(strings.Split(filepath.Base(video), ".")[0] + ".gif"),
}
return img, nil
}
@@ -150,3 +85,13 @@ type RenderedGif struct {
// FileName is <title>.<ext>
FileName string
}
+
+func hash(input string) (string, error) {
+ hasher := xxhash.New64()
+ _, err := hasher.WriteString(input)
+ if err != nil {
+ return "", errors.Wrap(err, "hashing input")
+ }
+ h := fmt.Sprintf("%d", hasher.Sum64())
+ return h, nil
+}