remove video specific stuff, base off of video, and add support for HTML
This commit is contained in:
parent
3d03f45eac
commit
f348bb92e3
166 changed files with 85 additions and 1430 deletions
148
processor.go
148
processor.go
|
|
@ -1,16 +1,14 @@
|
|||
package imagorvideo
|
||||
package imagorvideoextended
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/antchfx/htmlquery"
|
||||
"github.com/cshum/imagor"
|
||||
"github.com/cshum/imagor/imagorpath"
|
||||
"github.com/cshum/imagorvideo/ffmpeg"
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Processor for imagorvideo that implements imagor.Processor interface
|
||||
|
|
@ -33,22 +31,6 @@ func NewProcessor(options ...Option) *Processor {
|
|||
|
||||
// Startup implements imagor.Processor interface
|
||||
func (p *Processor) Startup(_ context.Context) error {
|
||||
ffmpeg.SetLogging(func(level ffmpeg.AVLogLevel, message string) {
|
||||
message = strings.TrimSuffix(message, "\n")
|
||||
switch level {
|
||||
case ffmpeg.AVLogTrace, ffmpeg.AVLogDebug, ffmpeg.AVLogVerbose:
|
||||
p.Logger.Debug("ffmpeg", zap.String("log", message))
|
||||
case ffmpeg.AVLogInfo:
|
||||
p.Logger.Info("ffmpeg", zap.String("log", message))
|
||||
case ffmpeg.AVLogWarning, ffmpeg.AVLogError, ffmpeg.AVLogFatal, ffmpeg.AVLogPanic:
|
||||
p.Logger.Warn("ffmpeg", zap.String("log", message))
|
||||
}
|
||||
})
|
||||
if p.Debug {
|
||||
ffmpeg.SetFFmpegLogLevel(ffmpeg.AVLogDebug)
|
||||
} else {
|
||||
ffmpeg.SetFFmpegLogLevel(ffmpeg.AVLogError)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -75,15 +57,15 @@ func (p *Processor) Process(ctx context.Context, in *imagor.Blob, params imagorp
|
|||
}
|
||||
}
|
||||
}()
|
||||
var filters imagorpath.Filters
|
||||
var mime = mimetype.Detect(in.Sniff())
|
||||
if typ := mime.String(); !strings.HasPrefix(typ, "video/") &&
|
||||
!strings.HasPrefix(typ, "audio/") {
|
||||
|
||||
if typ := mime.String(); !strings.HasPrefix(typ, "text/html") {
|
||||
// forward identical for non video nor audio
|
||||
err = imagor.ErrForward{Params: params}
|
||||
out = in
|
||||
return
|
||||
}
|
||||
|
||||
rs, size, err := in.NewReadSeeker()
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -100,95 +82,61 @@ func (p *Processor) Process(ctx context.Context, in *imagor.Blob, params imagorp
|
|||
return
|
||||
}
|
||||
}
|
||||
av, err := ffmpeg.LoadAVContext(rs, size)
|
||||
all, err := in.ReadAll()
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
defer av.Close()
|
||||
meta := av.Metadata()
|
||||
if params.Meta {
|
||||
out = imagor.NewBlobFromJsonMarshal(Metadata{
|
||||
Format: strings.TrimPrefix(mime.Extension(), "."),
|
||||
ContentType: mime.String(),
|
||||
Metadata: meta,
|
||||
})
|
||||
return
|
||||
|
||||
doc, err := htmlquery.Parse(strings.NewReader(string(all[:])))
|
||||
meta := Metadata{
|
||||
Format: strings.TrimPrefix(mime.Extension(), "."),
|
||||
Title: "",
|
||||
Description: "",
|
||||
Image: "",
|
||||
}
|
||||
bands := 3
|
||||
for _, filter := range params.Filters {
|
||||
switch filter.Name {
|
||||
case "format":
|
||||
switch strings.ToLower(filter.Args) {
|
||||
case "webp", "png", "gif":
|
||||
switch mime.Extension() {
|
||||
case ".webm", ".flv", ".mov", ".avi":
|
||||
bands = 4
|
||||
}
|
||||
}
|
||||
case "frame":
|
||||
if ts, e := time.ParseDuration(filter.Args); e == nil {
|
||||
if err = av.SelectDuration(ts); err != nil {
|
||||
return
|
||||
}
|
||||
} else if f, e := strconv.ParseFloat(filter.Args, 64); e == nil {
|
||||
if strings.Contains(filter.Args, ".") {
|
||||
if err = av.SelectPosition(f); err != nil {
|
||||
return
|
||||
}
|
||||
} else if n := int(f); n >= 1 {
|
||||
if err = av.SelectFrame(n); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
case "seek":
|
||||
if ts, e := time.ParseDuration(filter.Args); e == nil {
|
||||
if err = av.SeekDuration(ts); err != nil {
|
||||
return
|
||||
}
|
||||
} else if f, e := strconv.ParseFloat(filter.Args, 64); e == nil {
|
||||
if err = av.SeekPosition(f); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case "max_frames":
|
||||
n, _ := strconv.Atoi(filter.Args)
|
||||
if err = av.ProcessFrames(n); err != nil {
|
||||
return
|
||||
}
|
||||
metaTags := htmlquery.Find(doc, "//meta[@property]")
|
||||
for _, metaTag := range metaTags {
|
||||
var property = htmlquery.SelectAttr(metaTag, "property")
|
||||
var val = htmlquery.SelectAttr(metaTag, "content")
|
||||
|
||||
switch property {
|
||||
case "og:image":
|
||||
fallthrough
|
||||
case "twitter:image:src":
|
||||
meta.Image = val
|
||||
break
|
||||
|
||||
case "og:title":
|
||||
fallthrough
|
||||
case "twitter:title":
|
||||
meta.Title = val
|
||||
break
|
||||
|
||||
case "twitter:description":
|
||||
fallthrough
|
||||
case "og:description":
|
||||
meta.Description = val
|
||||
}
|
||||
}
|
||||
if meta.Title == "" {
|
||||
title := htmlquery.FindOne(doc, "//title")
|
||||
if title != nil {
|
||||
meta.Title = htmlquery.InnerText(title)
|
||||
} else {
|
||||
meta.Title = in.FilePath()
|
||||
}
|
||||
}
|
||||
|
||||
switch meta.Orientation {
|
||||
case 3:
|
||||
filters = append(filters, imagorpath.Filter{Name: "orient", Args: "180"})
|
||||
case 6:
|
||||
filters = append(filters, imagorpath.Filter{Name: "orient", Args: "270"})
|
||||
case 8:
|
||||
filters = append(filters, imagorpath.Filter{Name: "orient", Args: "90"})
|
||||
}
|
||||
buf, err := av.Export(bands)
|
||||
if err != nil || len(buf) == 0 {
|
||||
if err == nil {
|
||||
err = imagor.ErrUnsupportedFormat
|
||||
}
|
||||
return
|
||||
}
|
||||
out = imagor.NewBlobFromMemory(buf, meta.Width, meta.Height, bands)
|
||||
|
||||
if len(filters) > 0 {
|
||||
params.Filters = append(params.Filters, filters...)
|
||||
params.Path = imagorpath.GeneratePath(params)
|
||||
}
|
||||
err = imagor.ErrForward{Params: params}
|
||||
out = imagor.NewBlobFromJsonMarshal(meta)
|
||||
return
|
||||
}
|
||||
|
||||
// Metadata imagorvideo metadata
|
||||
type Metadata struct {
|
||||
Format string `json:"format"`
|
||||
ContentType string `json:"content_type"`
|
||||
*ffmpeg.Metadata
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
var transPixel = []byte("\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x21\xF9\x04\x01\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue