Android アプリを iPhone に移植しています (Android バージョンに基づいて iPhone アプリを改善するようなものです)。大きな非圧縮オーディオ ファイルを分割して結合する必要があります。
現在、すべてのファイルをメモリにロードして分割し、別々の関数に結合しています。100MB以上のファイルでクラッシュします。
これを行うために必要な新しいプロセスは次のとおりです。
2 つの録音 (file1 と file2) と、file2 を file1 内に挿入する分割位置があります。
-file1 と file2 の入力ストリームと、outputfile の出力ストリームを作成します。
- 新しい 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でこれを行うにはどうすればよいですか? 2 つの NSInputStream と 1 つの NSOutputStream に同じデリゲートを使用すると、非常に面倒になるようです。これを行う(そしてきれいにする)方法の例を見た人はいますか?