java - 将部分 FileInputStream 写入 FileOutPutstream

标签 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);
        }

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

最佳答案

查看 FileInputStream 的文档

你的方法并没有那么糟糕。这个可以完成一些工作:

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

文档说:

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

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

然后你将 i 作为偏移量传递。您的偏移量应为0(即从音频文件的开头开始)。

对于您传递的 len 1。这应该是您要复制的长度。因此,将 in1.getChannel().size()/2 传递到那里(直到音频文件的中间)。

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

所以这应该适合你:

 byte[] buffer = new byte[(int)(in1.gerChannel().size() / 2)];
 in1.read(buffer, 0, (int)(in1.gerChannel().size() / 2));
 out.write(buffer);

关于java - 将部分 FileInputStream 写入 FileOutPutstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46958411/

相关文章:

java - 复杂的 json 到 pojo

java - 如何在 Java 中高效地在机器之间传输对象

android - 改造编码特殊字符

java - postDelayed方法中触发OnTouchlistener

c# - 将不同的格式转换为未压缩的音频C#

Java passByValue 或 Reference 混淆

java - MongoDB 返回的 ObjectId 值与存储的值不同(使用 GridFS)

android - 如何使用事件管理创建自定义日历?

jquery - HTML5和jQuery:使用音频播放器作为if语句的计时器吗?

android - 音频完成后,ProgressBar不会重置