1

我想使用 iPhone 作为 ICEcast 流的音频源。

1) AudioQueueInputCallback 是我应该发送这个流的地方吗?

2)我已经能够识别ICEcast Icecast 2的协议:协议描述,使用C#流式传输 但是,我不确定如何在回调代码中执行此操作(即如何发送二进制音频)

更新

static void MyAQInputCallback( void *inUserData, 
  AudioQueueRef inQueue,
  AudioQueueBufferRef inBuffer,
  const AudioTimeStamp *inStartTime,
  UInt32 inNumPackets,
  cont AudioStreamPacketDescription *inPacketDesc)
{

    if (inNumPackets > 0)
    {
       // instead of
       //     AudioFileWritePackets(someFile, FALSE, 
       //           inBuffer->mAudioDataByteSize,
       //           inPacketDesc, recordPacketNumber, 
       //           &inNumPackets, inBuffer->mAudioData);

       // I want to send to http://myicecastserver
       // instead
    }

}

更新

我将打开与我的 icecast 服务器的套接字连接以发送数据。

4

1 回答 1

1

这是一个不平凡的问题。您提到的“协议”只是一些嗅探几个数据包并做出一些猜测的人。如果您检查 ICES 源代码,您可以看到发送到 Icecast 服务器的实际方法,它是一个高度复杂的自定义流协议。相关代码位于两个文件中:stream.c 和 stream_shared.c 假设您的流已经编码为 PCM。为了了解这种流算法的复杂性,下面是来自发送方的一小段摘录:

   else if (sdsc->enc)
    {
        ogg_page og;
        int be = (sdsc->input->subtype == INPUT_PCM_BE_16)?1:0;
        int ret=1;

        /* We use critical as a flag to say 'start a new stream' */
        if(buffer->critical)
        {
            if(sdsc->resamp) {
                resample_finish(sdsc->resamp);
                encode_data_float(sdsc->enc, sdsc->resamp->buffers,
                        sdsc->resamp->buffill);
                resample_clear(sdsc->resamp);
                sdsc->resamp = resample_initialise (sdsc->stream->channels,
                        sdsc->stream->resampleinrate, sdsc->stream->resampleoutrate);
            }
            encode_finish(sdsc->enc);
            while(encode_flush(sdsc->enc, &og) != 0)
            {
                if ((ret = stream_send_data(sdsc, og.header, og.header_len)) == 0)
                    return 0;
                if ((ret = stream_send_data(sdsc, og.body, og.body_len)) == 0)
                    return 0;
            }
            encode_clear(sdsc->enc);

            if(sdsc->input->metadata_update)
            {
                vorbis_comment_clear(&sdsc->vc);
                vorbis_comment_init(&sdsc->vc);

                sdsc->input->metadata_update(sdsc->input->internal, &sdsc->vc);
            }

正如我所说,这只是代码的 10% 左右。字面上有页面和页面的错误检查、元数据传输等。如果你想创建一个自定义的 Icecast 源客户端,你必须复制所有这些代码,将其移植到你的程序,然后将你的输入编码为 PCM,然后打包它用于传递给 stream.c 和 stream_shared.c 中的例程。

于 2012-10-25T16:41:17.020 回答