mirror of https://github.com/stashapp/stash.git
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package ffmpeg
|
|
|
|
import (
|
|
"bytes"
|
|
"github.com/stashapp/stash/pkg/logger"
|
|
"os"
|
|
)
|
|
|
|
// detect file format from magic file number
|
|
// https://github.com/lex-r/filetype/blob/73c10ad714e3b8ecf5cd1564c882ed6d440d5c2d/matchers/video.go
|
|
|
|
func mkv(buf []byte) bool {
|
|
return len(buf) > 3 &&
|
|
buf[0] == 0x1A && buf[1] == 0x45 &&
|
|
buf[2] == 0xDF && buf[3] == 0xA3 &&
|
|
containsMatroskaSignature(buf, []byte{'m', 'a', 't', 'r', 'o', 's', 'k', 'a'})
|
|
}
|
|
|
|
func webm(buf []byte) bool {
|
|
return len(buf) > 3 &&
|
|
buf[0] == 0x1A && buf[1] == 0x45 &&
|
|
buf[2] == 0xDF && buf[3] == 0xA3 &&
|
|
containsMatroskaSignature(buf, []byte{'w', 'e', 'b', 'm'})
|
|
}
|
|
|
|
func containsMatroskaSignature(buf, subType []byte) bool {
|
|
limit := 4096
|
|
if len(buf) < limit {
|
|
limit = len(buf)
|
|
}
|
|
|
|
index := bytes.Index(buf[:limit], subType)
|
|
if index < 3 {
|
|
return false
|
|
}
|
|
|
|
return buf[index-3] == 0x42 && buf[index-2] == 0x82
|
|
}
|
|
|
|
//returns container as string ("" on error or no match)
|
|
//implements only mkv or webm as ffprobe can't distinguish between them
|
|
//and not all browsers support mkv
|
|
func MagicContainer(file_path string) Container {
|
|
file, err := os.Open(file_path)
|
|
if err != nil {
|
|
logger.Errorf("[magicfile] %v", err)
|
|
return ""
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
buf := make([]byte, 4096)
|
|
_, err = file.Read(buf)
|
|
if err != nil {
|
|
logger.Errorf("[magicfile] %v", err)
|
|
return ""
|
|
}
|
|
|
|
if webm(buf) {
|
|
return Webm
|
|
}
|
|
if mkv(buf) {
|
|
return Matroska
|
|
}
|
|
return ""
|
|
}
|