1package magic 2 3import ( 4 "bytes" 5) 6 7var ( 8 // Flv matches a Flash video file. 9 Flv = prefix([]byte("\x46\x4C\x56\x01")) 10 // Asf matches an Advanced Systems Format file. 11 Asf = prefix([]byte{ 12 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 13 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C, 14 }) 15 // Rmvb matches a RealMedia Variable Bitrate file. 16 Rmvb = prefix([]byte{0x2E, 0x52, 0x4D, 0x46}) 17) 18 19// WebM matches a WebM file. 20func WebM(raw []byte, limit uint32) bool { 21 return isMatroskaFileTypeMatched(raw, "webm") 22} 23 24// Mkv matches a mkv file. 25func Mkv(raw []byte, limit uint32) bool { 26 return isMatroskaFileTypeMatched(raw, "matroska") 27} 28 29// isMatroskaFileTypeMatched is used for webm and mkv file matching. 30// It checks for .Eߣ sequence. If the sequence is found, 31// then it means it is Matroska media container, including WebM. 32// Then it verifies which of the file type it is representing by matching the 33// file specific string. 34func isMatroskaFileTypeMatched(in []byte, flType string) bool { 35 if bytes.HasPrefix(in, []byte("\x1A\x45\xDF\xA3")) { 36 return isFileTypeNamePresent(in, flType) 37 } 38 return false 39} 40 41// isFileTypeNamePresent accepts the matroska input data stream and searches 42// for the given file type in the stream. Return whether a match is found. 43// The logic of search is: find first instance of \x42\x82 and then 44// search for given string after n bytes of above instance. 45func isFileTypeNamePresent(in []byte, flType string) bool { 46 ind, maxInd, lenIn := 0, 4096, len(in) 47 if lenIn < maxInd { // restricting length to 4096 48 maxInd = lenIn 49 } 50 ind = bytes.Index(in[:maxInd], []byte("\x42\x82")) 51 if ind > 0 && lenIn > ind+2 { 52 ind += 2 53 54 // filetype name will be present exactly 55 // n bytes after the match of the two bytes "\x42\x82" 56 n := vintWidth(int(in[ind])) 57 if lenIn > ind+n { 58 return bytes.HasPrefix(in[ind+n:], []byte(flType)) 59 } 60 } 61 return false 62} 63 64// vintWidth parses the variable-integer width in matroska containers 65func vintWidth(v int) int { 66 mask, max, num := 128, 8, 1 67 for num < max && v&mask == 0 { 68 mask = mask >> 1 69 num++ 70 } 71 return num 72} 73 74// Mpeg matches a Moving Picture Experts Group file. 75func Mpeg(raw []byte, limit uint32) bool { 76 return len(raw) > 3 && bytes.HasPrefix(raw, []byte{0x00, 0x00, 0x01}) && 77 raw[3] >= 0xB0 && raw[3] <= 0xBF 78} 79 80// Avi matches an Audio Video Interleaved file. 81func Avi(raw []byte, limit uint32) bool { 82 return len(raw) > 16 && 83 bytes.Equal(raw[:4], []byte("RIFF")) && 84 bytes.Equal(raw[8:16], []byte("AVI LIST")) 85} 86