mirror of https://github.com/stashapp/stash.git
65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package ffmpeg
|
|
|
|
import (
|
|
"bytes"
|
|
"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
|
|
}
|
|
|
|
// magicContainer returns the container type of a file path.
|
|
// Returns the zero-value on errors or no-match. Implements mkv or
|
|
// webm only, as ffprobe can't distinguish between them and not all
|
|
// browsers support mkv
|
|
func magicContainer(filePath string) (Container, error) {
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
buf := make([]byte, 4096)
|
|
_, err = file.Read(buf)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if webm(buf) {
|
|
return Webm, nil
|
|
}
|
|
if mkv(buf) {
|
|
return Matroska, nil
|
|
}
|
|
return "", nil
|
|
}
|