【问题标题】:Save audio stream in file using C libwebsockets使用 C libwebsockets 将音频流保存在文件中
【发布时间】:2016-05-11 05:29:45
【问题描述】:

我有一个使用 libwebsockets 的 C 服务器,我想将接收到的音频流保存在磁盘上的文件中。

这是我的代码 sn-p:

#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);
            }
        }
    }
}

我收到消息“客户端已连接”以及文件,但内容不正确,我无法播放。我认为使用fwrite() 将流保存在文件中的方式存在问题。

客户端正在发送编码为 wav、16Khz、单声道的音频块。这是来自客户端的 sn-p(它是一个 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");
}

客户端运行良好,我将它用于完全相同的任务,但使用的是 Java 服务器。如果有人能告诉我如何将这些音频块保存在有效文件中,我将不胜感激。

【问题讨论】:

  • 你能比较一下你尝试发送的文件和写在磁盘上的文件吗?我假设你在 linux 上运行这个程序?
  • 我从麦克风发送实时音频。客户端具有将块编码为 raw 或 wav 的功能。我在 Ubuntu 上。
  • 您能否检查您的 wav 文件是否以 RIFF 之类的开头,为此您可以键入:hexdump -C your_file.wav | head
  • 这是我得到的:00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

标签: c audio libwebsockets


【解决方案1】:

我认为您没有在 wav 文件中写入标题。为此,

  • 你可以写一些函数来做到这一点见specification here
  • 或者你可以使用一个专用的库,比如libsndfile,使用起来并不复杂:

    // 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);
    

【讨论】:

    【解决方案2】:

    我没有使用 libsndfile,但我在客户端更改了一些内容。这是当前的 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  |................|
    *
    

    好像是wav编码的,但我没有内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多