thumbnails: extract pictures from audio files

This commit is contained in:
Dominik Schmidt
2023-10-28 01:16:58 +02:00
parent 5a3e4f5b78
commit 0b88ef8c95
23 changed files with 3169 additions and 0 deletions
@@ -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{}
}