Feat: 获取&写入 音频文件的 Metadata #43
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -208,6 +209,25 @@ func tryDecFile(inputFile string, outputDir string, allDec []common.NewDecoderFu
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if coverGetter, ok := dec.(common.CoverImageGetter); ok {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cover, err := coverGetter.GetCoverImage(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn("get cover image failed", zap.Error(err))
|
||||||
|
} else if imgExt, ok := sniff.ImageExtension(cover); !ok {
|
||||||
|
logger.Warn("sniff cover image type failed", zap.Error(err))
|
||||||
|
} else {
|
||||||
|
coverPath := filepath.Join(outputDir, inFilename+imgExt)
|
||||||
|
err = os.WriteFile(coverPath, cover, 0644)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn("write cover image failed", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// if source file need to be removed
|
// if source file need to be removed
|
||||||
if removeSource {
|
if removeSource {
|
||||||
err := os.RemoveAll(inputFile)
|
err := os.RemoveAll(inputFile)
|
||||||
|
@ -13,7 +13,7 @@ type Sniffer interface {
|
|||||||
|
|
||||||
var audioExtensions = map[string]Sniffer{
|
var audioExtensions = map[string]Sniffer{
|
||||||
// ref: https://mimesniff.spec.whatwg.org
|
// ref: https://mimesniff.spec.whatwg.org
|
||||||
".mp3": prefixSniffer("ID3"),
|
".mp3": prefixSniffer("ID3"), // todo: check mp3 without ID3v2 tag
|
||||||
".ogg": prefixSniffer("OggS"),
|
".ogg": prefixSniffer("OggS"),
|
||||||
".wav": prefixSniffer("RIFF"),
|
".wav": prefixSniffer("RIFF"),
|
||||||
|
|
||||||
|
30
internal/sniff/image.go
Normal file
30
internal/sniff/image.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package sniff
|
||||||
|
|
||||||
|
// ref: https://mimesniff.spec.whatwg.org
|
||||||
|
var imageMIMEs = map[string]Sniffer{
|
||||||
|
"image/jpeg": prefixSniffer{0xFF, 0xD8, 0xFF},
|
||||||
|
"image/png": prefixSniffer{'P', 'N', 'G', '\r', '\n', 0x1A, '\n'},
|
||||||
|
"image/bmp": prefixSniffer("BM"),
|
||||||
|
"image/webp": prefixSniffer("RIFF"),
|
||||||
|
"image/gif": prefixSniffer("GIF8"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageMIME sniffs the well-known image types, and returns its MIME.
|
||||||
|
func ImageMIME(header []byte) (string, bool) {
|
||||||
|
for ext, sniffer := range imageMIMEs {
|
||||||
|
if sniffer.Sniff(header) {
|
||||||
|
return ext, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageExtension is equivalent to ImageMIME, but returns file extension
|
||||||
|
func ImageExtension(header []byte) (string, bool) {
|
||||||
|
ext, ok := ImageMIME(header)
|
||||||
|
if !ok {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
// todo: use mime.ExtensionsByType
|
||||||
|
return "." + ext[6:], true // "image/" is 6 bytes
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user