Icecast流源客户端iOS

时间:2012-10-16 14:30:04

标签: ios core-audio audio-streaming icecast

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

1)是我应该发送此流的AudioQueueInputCallback吗?

2)我已经能够确定ICEcast的协议 Icecast 2: protocol description, streaming to it using 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服务器的套接字连接以发送数据。

1 个答案:

答案 0 :(得分: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中的例程。