将FileInputStream的一部分写入FileOutPutstream

时间:2017-10-26 15:36:43

标签: java android audio

我正在尝试使用我录制的.wav,然后创建一个部分wav的新输出流。最终的目标是允许我拍摄一个wav,将其分割到某个点并在其中间插入新的音频。

我使用FFMPEG来做这件事,但是使用最新版本的Android,FFMPEG性能已经相当糟糕。

我认为我最大的问题是缺乏对.read()和.write()方法的完全理解。

以下是我的尝试

final int SAMPLE_RATE = 44100; // Hz
final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
final int CHANNEL_MASK = AudioFormat.CHANNEL_IN_MONO;

in1 = new FileInputStream(Environment.getExternalStorageDirectory() + "/recording.wav");

out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/recording_part_1.wav");    

// Write out the wav file header
wavHeader.writeWavHeader(out, CHANNEL_MASK, SAMPLE_RATE, ENCODING);

while (in1.read(buffer, 0, buffer.length) != -1) {
           out.write(buffer);
}

out.close();
in1.close();

File fileToSave = new File(Environment.getExternalStorageDirectory() + "/GMT/recording_part_1.wav");

try {
    // This is not put in the try/catch/finally above since it needs to run
    // after we close the FileOutputStream
    wavHeader.updateWavHeader(fileToSave);
} catch (IOException ex) {

}

上述作品,但它只是复制了整个事情。记录代码,writeWaveHeader和updateWavHeader都来自这个要点,https://gist.github.com/kmark/d8b1b01fb0d2febf5770

我尝试过像

这样的事情
for (int i = 0; i < in1.getChannel().size() / 2; i++) {
            out.write(in1.read(buffer, i, 1));
}

但这根本不起作用。我也想过可能

            byte[] byteInput = new byte[(int)in1.getChannel().size() - 44];
        while (in1.read(byteInput, 44, byteInput.length - 45) != -1) {
            out.write(byteInput, 44, byteInput.length /2);
        }

希望只创建一个包含文件一半的新文件。我一直在看文档,但是我做错了。

1 个答案:

答案 0 :(得分:1)

查看FileInputStream

的文档

你的方法并不坏。这个可以用于一些工作:

alist = {
    '12345': ['2', 'my_url.com', 'James', ['James corp', 'a', '100', '30']],
    '35299': ['5', 'another_url.org', 'Carrie', ['Carrie corp', 'b', '60', '20']],
    }

blist = {
    '12345': ['actual_case', 'my_url.com'],
    '35299': ['actual_case', 'another_url.org'],
    }

clist = {}

for acct_number, value in alist.items():
    clist[blist[acct_number][1]] = value

文档说:

读取(byte [] b,int off,int len) 将此输入流中最多len个字节的数据读入一个字节数组。

将缓冲区作为byte []传递,这是正确的。

然后你传递i作为偏移量。你的偏移应该是 0 (所以从音频文件的开头)。

对于len你传递1.这应该是你要复制的长度。所以传递 in1.getChannel()。size()/ 2 (直到音频文件的中间位置)。

在这种情况下,您甚至不需要循环,因为read方法会为您完成所有操作。要编辑零件的开始和结束,您需要更改2.&amp; 3。参数。

所以这对你有用:

for (int i = 0; i < in1.getChannel().size() / 2; i++) {
    out.write(in1.read(buffer, i, 1));
}