-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfingerprint.go
114 lines (92 loc) · 2.92 KB
/
fingerprint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2020 Pexeso Inc. All rights reserved.
package pex
// #include <stdlib.h>
// #include <pex/sdk/lock.h>
// #include <pex/sdk/fingerprint.h>
import "C"
import "unsafe"
// FingerprintType is a bit flag specifying one or more fingerprint types.
type FingerprintType int
const (
FingerprintTypeVideo FingerprintType = 1
FingerprintTypeAudio FingerprintType = 2
FingerprintTypeMelody FingerprintType = 4
FingerprintTypeAll = FingerprintTypeVideo | FingerprintTypeAudio | FingerprintTypeMelody
)
// Fingerprint is how the SDK identifies a piece of digital content.
// It can be generated from a media file or from a memory buffer. The
// content must be encoded in one of the supported formats and must be
// longer than 1 second.
type Fingerprint struct {
b []byte
}
func (x *Fingerprint) Dump() []byte {
return x.b
}
func NewFingerprint(b []byte) *Fingerprint {
return &Fingerprint{
b: b,
}
}
type fingerprinter struct{}
// FingerprintFile is used to generate a fingerprint from a
// file stored on a disk. The path parameter must be a path
// to a valid file in supported format. The types parameter
// specifies which types of fingerprints to create. If not
// types are provided, FingerprintTypeAll is assumed.
func (x *fingerprinter) FingerprintFile(path string, types ...FingerprintType) (*Fingerprint, error) {
return newFingerprint([]byte(path), true, reduceTypes(types))
}
// FingerprintBuffer is used to generate a fingerprint from a
// media file loaded in memory as a byte slice. The types parameter
// specifies which types of fingerprints to create. If not
// types are provided, FingerprintTypeAll is assumed.
func (x *fingerprinter) FingerprintBuffer(buffer []byte, types ...FingerprintType) (*Fingerprint, error) {
return newFingerprint(buffer, false, reduceTypes(types))
}
func reduceTypes(in []FingerprintType) (out FingerprintType) {
if len(in) == 0 {
return FingerprintTypeAll
}
for _, t := range in {
out = out | t
}
return out
}
func newFingerprint(input []byte, isFile bool, typ FingerprintType) (*Fingerprint, error) {
C.Pex_Lock()
defer C.Pex_Unlock()
status := C.Pex_Status_New()
if status == nil {
panic("out of memory")
}
defer C.Pex_Status_Delete(&status)
ft := C.Pex_Buffer_New()
if ft == nil {
panic("out of memory")
}
if isFile {
cFile := C.CString(string(input))
defer C.free(unsafe.Pointer(cFile))
C.Pex_Fingerprint_File(cFile, ft, status, C.int(typ))
} else {
buf := C.Pex_Buffer_New()
if buf == nil {
panic("out of memory")
}
defer C.Pex_Buffer_Delete(&buf)
data := unsafe.Pointer(&input[0])
size := C.size_t(len(input))
C.Pex_Buffer_Set(buf, data, size)
C.Pex_Fingerprint_Buffer(buf, ft, status, C.int(typ))
}
if err := statusToError(status); err != nil {
C.Pex_Buffer_Delete(&ft)
return nil, err
}
data := C.Pex_Buffer_GetData(ft)
size := C.int(C.Pex_Buffer_GetSize(ft))
return &Fingerprint{
b: C.GoBytes(data, size),
}, nil
}