2012-12-19 21 views
0

我正在將一個Android應用程序移植到iPhone(更像是改進基於Android版本的iPhone應用程序),我需要拆分併合並大型未壓縮的音頻文件。如何在iOS中將它寫入NSOutputStream時讀取NSInputStream?

目前,我將所有文件加載到內存中並拆分它們並將它們組合到不同的函數中。它與100MB +文件崩潰。

這是做它需要新的流程:

我有兩個錄音(文件1和文件2),並在那裏我想文件2被插入內部文件1分割位置。

- 爲file1和file2創建輸入流,爲輸出文件創建輸出流。

-rewrite新CAF頭

從inputStream1閱讀操作數據,直到它達到分割點,我寫的所有數據到輸出文件。 並將其寫入輸出流。

- 從inputStream2讀取所有數據並將其寫入輸出文件。

- 從inputStream1中讀取剩餘的數據並將其寫入輸出文件。

這裏是我的過程中的Android代碼:

File file1File = new File(file1); 
    File file2File = new File(file2); 

    long file1Length = file1File.length(); 
    long file2Length = file2File.length(); 

    FileInputStream file1ByteStream = new FileInputStream(file1); 
    FileInputStream file2ByteStream = new FileInputStream(file2); 
    FileOutputStream outputFileByteStream = new FileOutputStream(outputFile); 


    // time = fileLength/(Sample Rate * Channels * Bits per sample/8) 
    // convert position to number of bytes for this function 
    long sampleRate = eRecorder.RECORDER_SAMPLERATE; 
    int channels = 1; 
    long bitsPerSample = eRecorder.RECORDER_BPP; 
    long bytePositionLength = (position * (sampleRate * channels * bitsPerSample/8))/1000; 



    //calculate total data size 
      int dataSize = 0; 
      dataSize = (int)(file1Length + file2Length); 

      WriteWaveFileHeaderForMerge(outputFileByteStream, dataSize, 
        dataSize + 36, 
        eRecorder.RECORDER_SAMPLERATE, 1, 
        2 * eRecorder.RECORDER_SAMPLERATE); 




    long bytesWritten = 0; 

    int length = 0; 

    //set limit for bytes read, and write file1 bytes to outputfile until split position reached 
    int limit = (int)bytePositionLength; 


    //read bytes to limit 
    writeBytesToLimit(file1ByteStream, outputFileByteStream, limit);  
    file1ByteStream.close(); 


    file2ByteStream.skip(44);//skip wav file header 
    writeBytesToLimit(file2ByteStream, outputFileByteStream, (int)file2Length); 
    file2ByteStream.close(); 

    //calculate length of remaining file1 bytes to be written 
    long file1offset = bytePositionLength; 

    //reinitialize file1 input stream 
    file1ByteStream = new FileInputStream(file1); 

    file1ByteStream.skip(file1offset); 
    writeBytesToLimit(file1ByteStream, outputFileByteStream, (int)file1Length); 

    file1ByteStream.close(); 
    outputFileByteStream.close(); 

這是我writeBytesToLimit功能:

private void writeBytesToLimit(FileInputStream inputStream, FileOutputStream outputStream, int byteLimit) throws IOException 
{ 
    int bytesRead = 0; 
    int chunkSize = 65536; 
    int length = 0; 
    byte[] buffer = new byte[chunkSize]; 
    while((length = inputStream.read(buffer)) != -1) 
    { 
     bytesRead += length; 
     if(bytesRead >= byteLimit) 
     { 
      int leftoverBytes = byteLimit % chunkSize;    
      byte[] smallBuffer = new byte[leftoverBytes]; 
      System.arraycopy(buffer, 0, smallBuffer, 0, leftoverBytes); 
      outputStream.write(smallBuffer); 
      break; 
     } 

     if(length == chunkSize) 
      outputStream.write(buffer); 
     else 
     { 
      byte[] smallBuffer = new byte[length]; 
      System.arraycopy(buffer, 0, smallBuffer, 0, length); 
      outputStream.write(smallBuffer); 
     } 

    } 

} 

如何在iOS中做到這一點?兩個NSInputStreams和一個NSOutputStream使用相同的代理看起來會變得非常混亂。 有沒有人看過如何做到這一點(並做到乾淨)的例子?

回答

2

我結束了使用NSFileHandle。例如,這是我正在做的第一部分。

NSData *readData = [[NSData alloc] init]; 
NSFileHandle *reader1 = [NSFileHandle fileHandleForReadingAtPath:file1Path]; 
NSFileHandle *writer = [NSFileHandle fileHandleForWritingAtPath:outputFilePath]; 

//start reading data from file1 to split point and writing it to file 
long bytesRead = 0; 
while(bytesRead < splitPointInBytes) 
{ 

    //read a chunk of data 
    readData = [reader1 readDataOfLength:chunkSize]; 
    if(readData.length == 0)break; 
    //trim data if too much was read 
    if(bytesRead + readData.length > splitPointInBytes) 
    { 
     //get difference of read bytes and byte limit 
     long difference = bytesRead + readData.length - splitPointInBytes; 

     //trim data 
     NSMutableData *readDataMutable = [NSMutableData dataWithData:readData]; 
     [readDataMutable setLength:readDataMutable.length - difference]; 
     readData = [NSData dataWithData:readDataMutable]; 

     NSLog(@"Too much data read, trimming"); 
    } 

    //write data to output file 
    [writer writeData:readData]; 

    //update byte counter 
    bytesRead += readData.length; 
} 
long file1BytesWritten = bytesRead; 
相關問題