[英]Save audio stream in file using C libwebsockets
I have a C server that uses libwebsockets and I want to save a received audio stream in a file on disk. 我有一个使用libwebsockets的C服务器,我想将收到的音频流保存在磁盘上的文件中。
Here is my code snippet: 这是我的代码片段:
#define FILENAME "/home/ubuntu/Desktop/file.wav"
FILE *received_file;
struct lws_context *Audiocontext;
static int callback_audio(
struct lws *wsi,
enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
switch (reason) {
case LWS_CALLBACK_ESTABLISHED:
{
printf("client is connected\n");
received_file = fopen(FILENAME, "w+");
if (received_file == NULL)
{
printf("Failed to open file\n");
exit(EXIT_FAILURE);
}
}
break;
case LWS_CALLBACK_RECEIVE: {
if(strcmp((char*)in,"EOS")==0)
{
printf("End of stream!\n");
fclose(received_file);
}
else
{
fwrite(in, 1, len, received_file);
}
}
}
}
I got the message "client is connected" and also the file, but the content isn't ok, I cannot play it. 我收到消息“客户端已连接”以及文件,但内容不正常,我无法播放。 I think there is a problem regarding the way I save the stream on file using fwrite()
. 我认为使用fwrite()
文件流保存到文件的方式存在问题。
The client is sending audio chunks encoded as wav, 16Khz, mono. 客户端正在发送编码为wav,16Khz,mono的音频块。 Here is a snippet from client (it's a javascript client, the full code is here: http://kaljurand.github.io/dictate.js/ ). 这是客户端的一个片段(它是一个javascript客户端,完整代码在这里: http : //kaljurand.github.io/dictate.js/ )。
if (recorder) {
recorder.stop();
config.onEvent(MSG_STOP, 'Stopped recording');
// Push the remaining audio to the server
recorder.export16kMono(function(blob) {
socketSend(blob);
socketSend(TAG_END_OF_SENTENCE);
recorder.clear();
}, 'export16kMono');
config.onEndOfSpeech();
} else {
config.onError(ERR_AUDIO, "Recorder undefined");
}
The client is working well, I use it for exactly the same task, but using a Java server. 客户端运行良好,我使用它完成相同的任务,但使用Java服务器。 I would appreciate if someone could indicate me how to save these audio chunks in a valid file. 如果有人能指出我如何将这些音频块保存在有效文件中,我将不胜感激。
I think that you do not write header in your wav file. 我认为你不在你的wav文件中写标题。 To do so, 为此,
or you can use a dedicaded library, like libsndfile , which is not so complicated to use: 或者您可以使用像libsndfile这样的dedicaded库,它使用起来并不复杂:
// instead of fopen, write something like SF_INFO info; SNDFILE * sf; info.samplerate = sample_rate; info.channels = 1; info.sections = 1; info.seekable = 0; info.frames = 0; info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; sf = sf_open(filename, SFM_WRITE, &info);
// instead of fwrite, something like sf_write_short(sf, in, len / sizeof(short));
// and instead of fclose sf_close(sf);
I didn't use libsndfile, but I change something on the client side. 我没有使用libsndfile,但我在客户端改变了一些东西。 This is the current hexdump output: 这是当前的hexdump输出:
00000000 52 49 46 46 20 60 00 00 57 41 56 45 66 6d 74 20 |RIFF `..WAVEfmt |
00000010 10 00 00 00 01 00 02 00 44 ac 00 00 10 b1 02 00 |........D.......|
00000020 04 00 10 00 64 61 74 61 00 60 00 00 00 00 00 00 |....data.`......|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00006020 00 00 00 00 00 00 00 00 00 00 00 00 52 49 46 46 |............RIFF|
00006030 20 60 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 | `..WAVEfmt ....|
00006040 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 |....D...........|
00006050 64 61 74 61 00 60 00 00 00 00 00 00 00 00 00 00 |data.`..........|
00006060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0000c050 00 00 00 00 00 00 00 00 52 49 46 46 20 60 00 00 |........RIFF `..|
0000c060 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00 |WAVEfmt ........|
0000c070 44 ac 00 00 10 b1 02 00 04 00 10 00 64 61 74 61 |D...........data|
0000c080 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.`..............|
0000c090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
It seems to be wav encoded, but i don't have a content. 它似乎是wav编码,但我没有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.