我想使用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服务器的套接字连接以发送数据。
答案 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中的例程。