1use songrec::{SongRec, Config, OutputFormat, RecognitionOutput};
2use std::path::Path;
3
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("SongRec Library Usage Examples");
6 println!("===============================\n");
7
8 println!("Example 1: Configuration");
10 println!("------------------------");
11
12 let config = Config::default()
13 .with_quiet_mode(true)
14 .with_network_timeout(15)
15 .with_sensitivity(0.7);
16
17 let songrec = SongRec::new(config);
18 println!("Created SongRec instance with custom settings\n");
19
20 println!("Example 2: File Recognition");
22 println!("---------------------------");
23
24 let audio_file = "tests/test_audio.wav";
25
26 if Path::new(audio_file).exists() {
27 match songrec.recognize_from_file(audio_file) {
28 Ok(result) => {
29 println!("Recognition data:");
31 println!(" Artist: {}", result.artist_name);
32 println!(" Song: {}", result.song_name);
33 println!(" Album: {}", result.album_name.as_deref().unwrap_or("Unknown"));
34 println!(" Year: {}", result.release_year.as_deref().unwrap_or("Unknown"));
35 println!(" Genre: {}", result.genre.as_deref().unwrap_or("Unknown"));
36 println!(" Track Key: {}", result.track_key);
37 println!(" Timestamp: {}", result.recognition_timestamp);
38
39 println!("\nExample 3: Output Formats");
41 println!("-------------------------");
42
43 let simple = RecognitionOutput::format_result(&result, OutputFormat::Simple);
45 println!("Simple: {}", simple.content);
46
47 let json = RecognitionOutput::format_result(&result, OutputFormat::Json);
49 println!("JSON length: {} characters", json.content.len());
50
51 let parsed: serde_json::Value = serde_json::from_str(&json.content)?;
53 println!("Parsed JSON - Song: {}", parsed["song_name"]);
54
55 let csv = RecognitionOutput::format_result(&result, OutputFormat::Csv);
57 println!("CSV: {}", csv.content);
58
59 println!("\nExample 4: Raw API Data");
61 println!("-----------------------");
62
63 if let Some(track) = result.raw_response.get("track") {
65 if let Some(images) = track.get("images") {
66 println!("Album art available: {}", images.is_object());
67 }
68 if let Some(hub) = track.get("hub") {
69 println!("Streaming links available: {}", hub.is_object());
70 }
71 }
72
73 }
74 Err(e) => {
75 println!("Recognition failed: {}", e);
76 }
77 }
78 } else {
79 println!("Audio file not found, skipping recognition");
80 }
81
82 println!("\nExample 5: Integration Function");
84 println!("-------------------------------");
85
86 fn recognize_audio(file_path: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
87 let config = Config::default().with_quiet_mode(true);
88 let songrec = SongRec::new(config);
89
90 let result = songrec.recognize_from_file(file_path)?;
91 let json_output = RecognitionOutput::format_result(&result, OutputFormat::Json);
92 let parsed = serde_json::from_str(&json_output.content)?;
93
94 Ok(parsed)
95 }
96
97 if Path::new(audio_file).exists() {
98 match recognize_audio(audio_file) {
99 Ok(data) => {
100 println!("Function returned JSON with {} fields",
101 data.as_object().map(|o| o.len()).unwrap_or(0));
102 }
103 Err(e) => println!("Function error: {}", e)
104 }
105 }
106
107 println!("\nExample 6: Configuration Options");
109 println!("--------------------------------");
110
111 let configs = [
112 ("High sensitivity", Config::default().with_sensitivity(0.9)),
113 ("Low sensitivity", Config::default().with_sensitivity(0.3)),
114 ("Fast timeout", Config::default().with_network_timeout(5)),
115 ("Long timeout", Config::default().with_network_timeout(30)),
116 ("Verbose mode", Config::default().with_quiet_mode(false)),
117 ];
118
119 for (name, config) in configs {
120 let _instance = SongRec::new(config);
121 println!("Created: {}", name);
122 }
123
124 println!("\nExample 7: Error Handling");
126 println!("-------------------------");
127
128 fn safe_recognize(file_path: &str) -> Result<(String, String), String> {
129 if !Path::new(file_path).exists() {
130 return Err(format!("File not found: {}", file_path));
131 }
132
133 let config = Config::default().with_quiet_mode(true);
134 let songrec = SongRec::new(config);
135
136 match songrec.recognize_from_file(file_path) {
137 Ok(result) => Ok((result.artist_name, result.song_name)),
138 Err(e) => Err(format!("Recognition error: {}", e)),
139 }
140 }
141
142 match safe_recognize("nonexistent.wav") {
144 Ok((artist, song)) => println!("Result: {} - {}", artist, song),
145 Err(e) => println!("Expected error: {}", e),
146 }
147
148 println!("\nExample 8: Data Structure Access");
150 println!("--------------------------------");
151
152 if Path::new(audio_file).exists() {
153 if let Ok(result) = songrec.recognize_from_file(audio_file) {
154 println!("Available data fields:");
156 println!(" song_name: {}", result.song_name);
157 println!(" artist_name: {}", result.artist_name);
158 println!(" album_name: {:?}", result.album_name);
159 println!(" track_key: {}", result.track_key);
160 println!(" release_year: {:?}", result.release_year);
161 println!(" genre: {:?}", result.genre);
162 println!(" recognition_timestamp: {}", result.recognition_timestamp);
163 println!(" raw_response keys: {:?}",
164 result.raw_response.as_object().map(|o| o.keys().collect::<Vec<_>>()));
165 }
166 }
167
168 println!("\nExample 9: Available Audio Devices");
170 println!("----------------------------------");
171
172 match songrec::audio::AudioRecorder::list_input_devices() {
173 Ok(devices) => {
174 println!("Found {} audio input devices:", devices.len());
175 for (index, device_name) in devices.iter().enumerate() {
176 println!(" Device {}: {}", index, device_name);
177 }
178
179 if !devices.is_empty() {
181 println!("\nExample: Using device for live recognition:");
182 println!("let device_name = \"{}\";", devices[0]);
183 println!("let stream = songrec.start_continuous_recognition_with_device(Some(device_name.to_string()))?;");
184 println!("for result in stream {{");
185 println!(" match result {{");
186 println!(" Ok(recognition) => println!(\"Recognized: {{}} - {{}}\", recognition.artist_name, recognition.song_name),");
187 println!(" Err(e) => eprintln!(\"Recognition error: {{}}\", e),");
188 println!(" }}");
189 println!("}}");
190 }
191 }
192 Err(e) => {
193 println!("Error listing audio devices: {}", e);
194 println!("This may occur if no audio devices are available or there are permission issues.");
195 }
196 }
197
198 println!("\nExample 10: Device Selection Function");
200 println!("------------------------------------");
201
202 fn select_audio_device(device_name_pattern: &str) -> Result<String, String> {
203 let devices = songrec::audio::AudioRecorder::list_input_devices()
204 .map_err(|e| format!("Failed to list devices: {}", e))?;
205
206 for device in devices {
208 if device.to_lowercase().contains(&device_name_pattern.to_lowercase()) {
209 return Ok(device);
210 }
211 }
212
213 Err(format!("No device found matching pattern: {}", device_name_pattern))
214 }
215
216 match select_audio_device("microphone") {
218 Ok(device) => println!("Found microphone device: {}", device),
219 Err(e) => println!("Device selection result: {}", e),
220 }
221
222 match select_audio_device("voicemeeter") {
223 Ok(device) => println!("Found Voicemeeter device: {}", device),
224 Err(e) => println!("Voicemeeter search result: {}", e),
225 }
226
227 println!("\nExample 11: Complete Device Integration");
229 println!("--------------------------------------");
230
231 fn get_best_audio_device() -> Result<String, String> {
232 let devices = songrec::audio::AudioRecorder::list_input_devices()
233 .map_err(|e| format!("Cannot access audio devices: {}", e))?;
234
235 if devices.is_empty() {
236 return Err("No audio devices available".to_string());
237 }
238
239 let preferred_patterns = ["voicemeeter", "stereo mix", "microphone", "mic"];
241
242 for pattern in preferred_patterns {
243 for device in &devices {
244 if device.to_lowercase().contains(pattern) {
245 return Ok(device.clone());
246 }
247 }
248 }
249
250 Ok(devices[0].clone())
252 }
253
254 match get_best_audio_device() {
255 Ok(device) => {
256 println!("Selected audio device: {}", device);
257 println!("This device can be used for live recognition:");
258 println!(" songrec.start_continuous_recognition_with_device(Some(\"{}\".to_string()))", device);
259 }
260 Err(e) => println!("Device selection failed: {}", e),
261 }
262
263 println!("\nLibrary demonstration complete.");
264
265 Ok(())
266}