thumbnails: extract pictures from audio files
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package preprocessor
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type LazyReadSeeker struct {
|
||||
reader io.Reader
|
||||
buffer []byte
|
||||
position int64
|
||||
}
|
||||
|
||||
func NewLazyReadSeeker(r io.Reader) *LazyReadSeeker {
|
||||
return &LazyReadSeeker{
|
||||
reader: r,
|
||||
buffer: make([]byte, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LazyReadSeeker) Read(p []byte) (int, error) {
|
||||
// Fill buffer if necessary
|
||||
if l.position >= int64(len(l.buffer)) {
|
||||
temp := make([]byte, len(p))
|
||||
n, err := l.reader.Read(temp)
|
||||
if err != nil && err != io.EOF {
|
||||
return 0, err
|
||||
}
|
||||
if n == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
l.buffer = append(l.buffer, temp[:n]...)
|
||||
}
|
||||
|
||||
// Read from buffer
|
||||
n := copy(p, l.buffer[l.position:])
|
||||
l.position += int64(n)
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (l *LazyReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||
var newPos int64
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
newPos = offset
|
||||
case io.SeekCurrent:
|
||||
newPos = l.position + offset
|
||||
default:
|
||||
return 0, errors.New("seekEnd is not supported")
|
||||
}
|
||||
|
||||
if newPos < 0 {
|
||||
return 0, errors.New("negative position is invalid")
|
||||
}
|
||||
|
||||
l.position = newPos
|
||||
return l.position, nil
|
||||
}
|
||||
@@ -2,10 +2,12 @@ package preprocessor
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"image"
|
||||
"image/draw"
|
||||
"image/gif"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"mime"
|
||||
"strings"
|
||||
@@ -15,6 +17,8 @@ import (
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/opentype"
|
||||
"golang.org/x/image/math/fixed"
|
||||
|
||||
"github.com/dhowden/tag"
|
||||
)
|
||||
|
||||
type FileConverter interface {
|
||||
@@ -41,6 +45,28 @@ func (i GifDecoder) Convert(r io.Reader) (interface{}, error) {
|
||||
return img, nil
|
||||
}
|
||||
|
||||
type AudioDecoder struct{}
|
||||
|
||||
func (i AudioDecoder) Convert(r io.Reader) (interface{}, error) {
|
||||
readSeeker := NewLazyReadSeeker(r)
|
||||
m, err := tag.ReadFrom(readSeeker)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
picture := m.Picture()
|
||||
if picture == nil {
|
||||
return nil, errors.New(`could not extract image from audio file`)
|
||||
}
|
||||
|
||||
converter := ForType(picture.MIMEType, nil)
|
||||
if converter == nil {
|
||||
return nil, errors.New(`could not find converter for image extraced from audio file`)
|
||||
}
|
||||
|
||||
return converter.Convert(bytes.NewReader(picture.Data))
|
||||
}
|
||||
|
||||
type TxtToImageConverter struct {
|
||||
fontLoader *FontLoader
|
||||
}
|
||||
@@ -197,6 +223,12 @@ func ForType(mimeType string, opts map[string]interface{}) FileConverter {
|
||||
}
|
||||
case "image/gif":
|
||||
return GifDecoder{}
|
||||
case "audio/flac":
|
||||
fallthrough
|
||||
case "audio/mpeg":
|
||||
fallthrough
|
||||
case "audio/ogg":
|
||||
return AudioDecoder{}
|
||||
default:
|
||||
return ImageDecoder{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user