2013-07-20 46 views
3

我一直在嘗試爲ios創建冰投的源客戶端。我已經能夠使用asyncsocket連接到套接字。我也能夠將數據寫入服務器。 icecast配置是爲mp3格式完成的。但寫入服務器的mp3文件已損壞。我提供了一些代碼片段。ios的冰投源客戶端

頁眉:

NSString *string = @"SOURCE /sync HTTP/1.0\r\n" 
     "Authorization: Basic c291cmNlOmhhY2ttZQ==\r\n" 
     "User-Agent: butt-0.1.12\r\n" 
     "User-Agent: butt-0.1.12\r\n" 
     "content-type: audio/mpeg\r\n" 
     "ice-name: sync's Stream\r\n" 
     "ice-public: 0\r\n" 
     "ice-genre: Rock\r\n" 
     "ice-description: This is my server description\r\n" 
     "Connection: keep-alive\r\n" 
     "ice-audio-info: ice-samplerate=44100;ice-bitrate=48;ice-channels=2\r\n\r\n"; 

    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; 

    //sending http request to write the header 
    NSLog(@"Sending HTTP Request."); 
    [socket writeData:data withTimeout:-1 tag:1]; 

    //write buffer data to server 
    [socket writeData:self.dataBuffer withTimeout:-1 tag:1]; 

對我使用aqrecorder使用下面的代碼來記錄它記錄。

void AQRecorder::MyInputBufferHandler( void *        inUserData, 
             AudioQueueRef      inAQ, 
             AudioQueueBufferRef     inBuffer, 
             const AudioTimeStamp *    inStartTime, 
             UInt32        inNumPackets, 
             const AudioStreamPacketDescription* inPacketDesc) 
{ 
    AQRecorder *aqr = (AQRecorder *)inUserData; 
    try { 
     if (inNumPackets > 0) { 
      // write packets to file 
      XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize, 
              inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData), 
         "AudioFileWritePackets failed"); 
      aqr->mRecordPacket += inNumPackets; 

      NSLog(@"size = %u",(unsigned int)inBuffer->mAudioDataByteSize); 

      data = [[[NSData alloc]initWithBytes:inBuffer->mAudioData length:inBuffer->mAudioDataByteSize]retain]; 

      server *srv = [[server alloc]init]; 
      srv.dataBuffer=data; 
      [srv connecting]; 

     } 

     // if we're not stopping, re-enqueue the buffe so that it gets filled again 
     if (aqr->IsRunning()) 
      XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed"); 
    } catch (CAXException e) { 
     char buf[256]; 
     fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); 
    } 
} 



void AQRecorder::StartRecord(CFStringRef inRecordFile) 
{ 
// server *srv=[[server alloc]init]; 
// [srv connecting]; 

    int i, bufferByteSize; 
    UInt32 size; 
    CFURLRef url = nil; 

    try {  
     mFileName = CFStringCreateCopy(kCFAllocatorDefault, inRecordFile); 

//  // specify the recording format 
//  SetupAudioFormat(kAudioFormatMPEG4AAC); 

     // specify the recording format, use hardware AAC if available 
     // otherwise use IMA4 
     if(IsAACHardwareEncoderAvailable()) 
      SetupAudioFormat(kAudioFormatMPEG4AAC); 
     else 
      SetupAudioFormat(kAudioFormatAppleIMA4); 

     // create the queue 
     XThrowIfError(AudioQueueNewInput(
             &mRecordFormat, 
             MyInputBufferHandler, 
             this /* userData */, 
             NULL /* run loop */, NULL /* run loop mode */, 
             0 /* flags */, &mQueue), "AudioQueueNewInput failed"); 

     // get the record format back from the queue's audio converter -- 
     // the file may require a more specific stream description than was necessary to create the encoder. 
     mRecordPacket = 0; 

     size = sizeof(mRecordFormat); 
     XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_StreamDescription, 
             &mRecordFormat, &size), "couldn't get queue's format"); 

     NSString *recordFile = [NSTemporaryDirectory() stringByAppendingPathComponent: (NSString*)inRecordFile];  

     //url = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)recordFile, NULL); 
     url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)recordFile, kCFURLPOSIXPathStyle, false); 
     // create the audio file 
     OSStatus status = AudioFileCreateWithURL(url, kAudioFileCAFType, &mRecordFormat, kAudioFileFlags_EraseFile, &mRecordFile); 
     CFRelease(url); 

     XThrowIfError(status, "AudioFileCreateWithURL failed"); 

     // copy the cookie first to give the file object as much info as we can about the data going in 
     // not necessary for pcm, but required for some compressed audio 
     CopyEncoderCookieToFile(); 

     // allocate and enqueue buffers 
     bufferByteSize = ComputeRecordBufferSize(&mRecordFormat, kBufferDurationSeconds); // enough bytes for half a second 
     for (i = 0; i < kNumberRecordBuffers; ++i) { 
      XThrowIfError(AudioQueueAllocateBuffer(mQueue, bufferByteSize, &mBuffers[i]), 
         "AudioQueueAllocateBuffer failed"); 
      XThrowIfError(AudioQueueEnqueueBuffer(mQueue, mBuffers[i], 0, NULL), 
         "AudioQueueEnqueueBuffer failed"); 
     } 
     // start the queue 
     mIsRunning = true; 
     XThrowIfError(AudioQueueStart(mQueue, NULL), "AudioQueueStart failed"); 
    } 
    catch (CAXException e) { 
     char buf[256]; 
     fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); 
    } 
    catch (...) { 
     fprintf(stderr, "An unknown error occurred\n");; 
    } 

} 

是否需要更改寫入服務器的格式?

回答

1

您不發送MP3數據,您發送的是AAC或M4A數據。我不相信Icecast支持M4A。你真的在使用Icecast或其他服務器嗎?

對於AAC,您的Content-Type標題不正確。請嘗試audio/aac,audio/aacp,audio/mp4audio/mpeg4-generic

此外,您只需要一個User-Agent標題,您應該選擇與您正在編寫的軟件相匹配的內容,而不是複製其他人的內容。將來,可能需要對代碼進行協議調整,並且這隻有在使用自己的用戶代理字符串時纔有可能。

+0

我正在使用icecast服務器,如果我使用kAudioFormatLinearPCM什麼應該是Content-Type – Naresh

+0

@NareshKukkala,你可以嘗試'audio/wav',但我不確定Icecast是否支持這個。它不只是關於流,還有一個容器(在你的情況下是文件頭)需要在流數據之前發送,告訴客戶如何解碼它。這對於PCM來說尤爲重要,因爲這些只是原始樣本。在PCM音頻中沒有內部幀標題,所以初始標題需要告訴播放器採樣率,比特深度和數據的字節順序。 – Brad

+0

我的icecast配置爲mp3格式。當我打開服務器寫入的文件不包含標題的細節。什麼都可以,我能夠通過流,但唯一的噪音將數據發送到服務器流播放 – Naresh