我有一个关于修改音频文件的快速问题。我可以通过输入流(解码等)访问样本,但我无法找到一种方法来操作输入流中的样本(可能是多个样本的情况)。
我想要实现的是获取文件 Ex A.mp3
,从中删除几秒钟,最后将其存储到新文件中。
通过查看JavaSoundApi examples,我发现可以通过以下方式创建文件:
File fileOut = new File(someNewPathName);
AudioFileFormat.Type fileType = fileFormat.getType();
if (AudioSystem.isFileTypeSupported(fileType,audioInputStream)) {
AudioSystem.write(audioInputStream, fileType, fileOut);
}
答案 0 :(得分:3)
你只需要使AudioInputStream 谎言大小。为此,您可以创建自己的AudioInputStream类,并将委托用于从声音API(仅限骨架)获取的普通AudioInputStream:
public class CuttingAudioInputStream extends AudioInputStream {
private AudioInputStream delegate;
public CuttingAudioInputStream(AudioInputStream delegate) {
this.delegate = delegate;
}
/**
* Lie about length of delegate
*/
public long getFrameLength() {
// simple demo, make the caller think the stream is 44100 samples long
return Math.min(delegate.getFrameLength(), 44100);
}
// Overrides for all other methods of AudioInputStream,
// left as excercise to the reader
}
您只需要实现所有其他方法以符合您想要的限制。您也可以在中间剪切部分,在read()方法中稍微复杂一点。
然而,我觉得有必要指出,如果源/目的地是有损格式(例如MP3被解码和重新编码),这种方法可以降低音频质量。如果质量损失是不可接受的(仅当您多次处理相同的流时才重要),您最好不解码文件,而是将切割过程直接应用于编码数据。当然这更复杂(你需要对你想要处理的每种格式有一个很好的了解),并且你可以通过不同的格式来限制你的位置。
答案 1 :(得分:2)
您的教程适用于Java 1.5!目前有更多版本。
在您引用的页面上,“阅读声音文件”标题下有一些示例代码。请注意带有注释的区域:
// Here, do something useful with the audio data that's
// now in the audioBytes array...
这是在正在读取audioInputStream的while循环中。如果在通过此区域时跟踪帧,则可以计算经过的时间。加载的数据可以保存到字节数组中。或者,所需帧中的数据可能是读取audioInputStream并实现TargetDataLine的类的输出。如果我没记错的话,可以使用TargetDataLine来处理AudioSystem.write(...
我不知道直接编辑压缩数据甚至是wav。 Wav格式不统一,没有统一的标题。这就是为什么我让Java读取流,并使用数据,因为它以这种方式暴露。