-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEasyFingerPrinting.cs
122 lines (110 loc) · 4.58 KB
/
EasyFingerPrinting.cs
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
115
116
117
118
119
120
121
122
using System.Text;
using SoundFingerprinting.Audio;
using SoundFingerprinting.Builder;
using SoundFingerprinting.Data;
using SoundFingerprinting.Emy;
using SoundFingerprinting.InMemory;
using SoundFingerprinting.Query;
namespace Info
{
class EasyFingerPrinting
{
InMemoryModelService modelService;
IAudioService audioService;
string directoryToSearch;
string deserPath;
bool rebuild;
int? maxToProcess;
public EasyFingerPrinting(string directoryToSearch, string deserPath, bool rebuild = false, int? maxToProcess = null)
{
this.rebuild = rebuild;
this.directoryToSearch = directoryToSearch;
this.deserPath = deserPath;
this.modelService = new InMemoryModelService(); // store fingerprints in RAM
bool useFFMPEG = true;
if (useFFMPEG)
{
this.audioService = new FFmpegAudioService();
}
else
{
this.audioService = new SoundFingerprintingAudioService(); // default audio library
}
this.maxToProcess = maxToProcess;
}
public string GetDirectoryName() => directoryToSearch;
public async Task LoadOrRegenerate()
{
if (rebuild || !Directory.Exists(deserPath))
{
string[] database_paths = Directory.GetFiles(directoryToSearch, "*.*", SearchOption.AllDirectories);
int i = 0;
foreach (string path in database_paths)
{
i++;
// VideoInfo info = new VideoInfo(path);
Console.WriteLine($"Processing {i}/{database_paths.Count()}: {path}");
// sb.AppendLine(info.ToString());
// Console.WriteLine(pathToVideoInfo[path]);
await StoreForLaterRetrieval(path);
if (maxToProcess != null && i >= maxToProcess)
{
break;
}
}
// File.WriteAllText("testunicode.txt", sb.ToString());
modelService.Snapshot(deserPath);
}
else
{
modelService = new InMemoryModelService(deserPath);
}
}
async Task StoreForLaterRetrieval(string path)
{
// For now, use the path as the ID
string id = path;
string title = "title";
string artist = "Unknown";
var track = new TrackInfo(id, title, artist);
// create fingerprints
AVHashes avHashes = null;
try
{
avHashes = await FingerprintCommandBuilder.Instance
.BuildFingerprintCommand()
.From(path)
.UsingServices(audioService)
.Hash();
}
catch (NullReferenceException e)
{
Console.WriteLine($"ERROR: probably missing ffmpeg binary. On Windows, please put the binaries at FFmpeg\\bin\\x64 (including dll files) from https://github.com/GyanD/codexffmpeg/releases/download/4.4.1/ffmpeg-4.4.1-full_build-shared.7z. On Unix-like OS, ensure ffmpeg is installed (probably need version 4.x.x): {e}");
throw e;
}
// There is a bug where snapshot won't load if a file with no hashes is snapshotted.
// Since such files aren't useful anyway, skip them.
if (!avHashes.IsEmpty)
{
// store hashes in the database for later retrieval
modelService.Insert(track, avHashes);
}
else
{
Console.WriteLine($"WARNING: Skipped file {path} because it generated no audio hashes (too short?)");
}
}
public async Task<AVQueryResult> QueryPath(string path)
{
// For some reason, if this is not specified, can produce poor quality matches?
float secondsToAnalyse = 30;
float startAtSecond = 0;
return await QueryCommandBuilder.Instance
.BuildQueryCommand()
//.From(path)
.From(path, secondsToAnalyse, startAtSecond)
.UsingServices(modelService, audioService)
.Query();
}
}
}