我目前正在开展一个学校项目,其中我正在创建 Shazam 的一种克隆版本。 我现在可以成功录制音频,并将其解码为 Base64 字符串,就像 api 所要求的那样,但它无法识别任何歌曲,因为这可能是错误的解码过程或错误的录制过程。 目前,我正在手动将数据插入 api,因此不存在连接问题。
这就是 api 的要求: 从小于 500KB 的原始数据生成的 byte[] 的 Base64 编码字符串(3-5 秒的样本足以用于检测)。原始声音数据必须是 44100Hz、1 通道(单声道)、带符号的 16 位 PCM 小端。不支持其他类型的媒体,例如:mp3、wav、e...
我有一个 AudioRecorder 类来处理音频的录制:
override fun start(outputFile: File) {
createRecorder().apply {
setAudioSource(MediaRecorder.AudioSource.MIC)
setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
setAudioChannels(1)
setAudioSamplingRate(44100)
setAudioEncodingBitRate(16 * 44100)
setOutputFile(outputFile.absolutePath)
prepare()
start()
recorder = this
}
}
override fun stop() {
recorder?.stop()
recorder?.reset()
recorder = null
}
fun readAudioFile(file: File): ByteArray {
return file.readBytes()
}
然后我有一个处理我的录音的函数,它也会在正确的时间执行
private suspend fun launchAudioRecording(audioRecorder: AudioRecorder, context: Context): String {
Log.d("be.howest.rythmradar.ui.SearchingSongScreen", "be.howest.rythmradar.ui.launchAudioRecording - Start")
// Start recording
File(context.cacheDir, "audio.3gp").also {
audioRecorder.start(it)
audioFile = it
}
// Delay for 5 seconds to record audio
delay(5000)
// Stop recording
audioRecorder.stop()
// Do something with the recorded audio, such as converting it to Base64 string
val audioData = audioRecorder.readAudioFile(audioFile!!)
val base64String = convertToBase64String(audioData)
return base64String
}
最后是我的 base64string 转换器:
private fun convertToBase64String(audioData: ByteArray): String {
return Base64.encodeToString(audioData, Base64.DEFAULT)
}
我最近参与了一个类似的项目。 RapidApi 也不适合我,但AudDApi!做。我设法通过将其值设置为 base64String 并将其传递给 AudDApi,将其保存到隐藏的表单输入元素中,效果非常好。但是,录音时间不得超过 5 秒,否则会导致负载错误。
您可以尝试下面的代码来调整您的录音和base65String。
<div>
<form action="/" method="post">
<input id="audioString" hidden />
<button type="submit">Fetch</button>
</form>
</div>
<script type="text/javascript">
class VoiceRecorder {
constructor() {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
console.log("getUserMedia supported");
} else {
console.log("getUserMedia is not supported on your browser!");
}
this.mediaRecorder;
this.stream;
this.chunks = [];
this.isRecording = false;
this.recorderRef = document.querySelector("#recorder");
this.playerRef = document.querySelector("#player");
this.startRef = document.querySelector("#start");
this.stopRef = document.querySelector("#stop");
this.startRef.onclick = this.startRecording.bind(this);
this.stopRef.onclick = this.stopRecording.bind(this);
this.constraints = {
audio: true,
video: false,
};
}
handleSuccess(stream) {
this.stream = stream;
this.stream.oninactive = () => {
console.log("Stream ended!");
};
this.recorderRef.srcObject = this.stream;
this.mediaRecorder = new MediaRecorder(this.stream);
console.log(this.mediaRecorder);
this.mediaRecorder.ondataavailable =
this.onMediaRecorderDataAvailable.bind(this);
this.mediaRecorder.onstop = this.onMediaRecorderStop.bind(this);
this.recorderRef.play();
this.mediaRecorder.start();
}
handleError(error) {
console.log("navigator.getUserMedia error: ", error);
}
onMediaRecorderDataAvailable(e) {
this.chunks.push(e.data);
}
onMediaRecorderStop(e) {
const blob = new Blob(this.chunks, { type: "audio/ogg; codecs=opus" });
const audioURL = window.URL.createObjectURL(blob);
this.playerRef.src = audioURL;
this.chunks = [];
this.stream.getAudioTracks().forEach((track) => track.stop());
this.stream = null;
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
var base64String = reader.result;
base64String = base64String.substring(base64String.indexOf(',') + 1);
document.querySelector("#audioString").value = base64String;
};
}
startRecording() {
if (this.isRecording) return;
this.isRecording = true;
this.startRef.innerHTML =
'<em>Recording <span class="material-symbols-outlined listen">noise_aware</span></em>';
this.playerRef.src = "";
navigator.mediaDevices
.getUserMedia(this.constraints)
.then(this.handleSuccess.bind(this))
.catch(this.handleError.bind(this));
}
stopRecording() {
if (!this.isRecording) return;
this.isRecording = false;
this.startRef.innerHTML =
"<span class='material-symbols-outlined'>mic</span>";
this.recorderRef.pause();
this.mediaRecorder.stop();
}
}
window.voiceRecorder = new VoiceRecorder();
</script>