im currently developing a music detector based on shazam api on rapid api. When i use .mp3 file from assets, the HTTP response works well. but when i use the file saved by the recorder, the response look like this
{"location":{"accuracy":0.01},"matches":[],"tagid":"5F410A1F-49B5-42AB-BC28-8E03D8FD1476","timestamp":1561151162,"timezone":"Europe/Moscow"}
The api is here: Shazam Recognition. Here is my code: shazam.dart
class Shazam extends StatefulWidget {
const Shazam({super.key});
@override
State<Shazam> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<Shazam> {
bool isListening = false;
final recorder = FlutterSoundRecorder();
bool isRecorderReady = false;
String audioPath = '';
ResultSong song = ResultSong(name: '', images: '', artist: '');
Future<void> fetchSong() async {
final audioFile = File(audioPath);
final song = await SongApi.getRecipe(audioFile);
setState(() {
this.song = song[0];
log(song.toString());
});
}
@override
void initState() {
initRecorder();
super.initState();
}
@override
void dispose() {
recorder.closeRecorder();
super.dispose();
}
Future<void> start() async {
if (!isRecorderReady) {
return;
}
await recorder.startRecorder(toFile: 'audio');
}
Future stop() async {
if (!isRecorderReady) {
return;
}
final path = await recorder.stopRecorder();
setState(() {
audioPath = path!;
});
fetchSong();
}
Future<void> initRecorder() async {
final status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('Microphone permission not granted');
}
await recorder.openRecorder();
isRecorderReady = true;
recorder.setSubscriptionDuration(const Duration(milliseconds: 500));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
Center(
child: Column(
children: <Widget>[
AvatarGlow(
animate: isListening,
child: GestureDetector(
onTap: () async {
if (recorder.isRecording) {
await stop();
setState(() {
isListening = false;
});
} else {
await start();
setState(() {
isListening = true;
});
}
},
child: Container(
height: 200,
width: 200,
padding: const EdgeInsets.all(40),
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset('assets/icon.png'),
),
)),
IconButton(
onPressed: () {
Navigator.pushNamed(context, '/result', arguments: song);
},
icon: const Icon(Icons.close, color: Colors.white),
),
],
),
),
]),
);
}
}
post_song_api.dart
import 'dart:convert';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'song_recognized.dart';
import 'dart:developer';
Future<File> getFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.create(recursive: true);
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
//the audioFile is the successful responded post API and file is the one generated by recorder.
class SongApi {
static Future<List<ResultSong>> getRecipe(File file) async {
File audioFile = await getFileFromAssets('audios/TTL.mp3');
var uri = Uri.https(
'shazam-song-recognition-api.p.rapidapi.com', '/recognize/file');
final response = await http.post(
uri,
headers: {
"content-type": "application/octet-stream",
"x-rapidapi-key": "my_api_key",
"x-rapidapi-host": "shazam-song-recognition-api.p.rapidapi.com",
},
//I change the file in here to test.
body: await file.readAsBytes(),
);
log(response.body);
Map data = jsonDecode(response.body);
List temp = [];
temp.add(data['track']);
return ResultSong.recipesFromSnapshot(temp);
}
}
Im thinking about 2 ways:
- The first one is because of the api doesn't support this file type (although i didn't know what it is) so the api refuse. Their docs says only accept (mp3/ogg/wav).
- The second one, I think something happened with the file path or i pass it to the HTTP request body wrong way using file.readAsBytes(). I did test the recorded file in another project and it is completely normal and playable. Really appreciate any help!