内容简介:使用Java sound播放音频文件出现“文件类型不支持”报错的原因分析
(尊重劳动成果,转载请注明出处: http://blog.csdn.net/qq_25827845/article/details/79026786 冷血之心的博客)
Java Sound API是javaSE平台提供底层的(low-level)处理声音接口,可以实现音频文件的播放。
其核心包括:
- AudioSystem
- AudioInputStream
- AudioFormat
- DataLine.Info
- SourceDataLine
- TargetDataLine等
AudioSystem 的默认输入设备是麦克风,默认输出设备是扬声器:
- SourceDataLine:源数据流,指AudioSystem的输入流,把音频文件写入到AudioSystem中
- TargetDataLine:目标数据流,指AudioSystem的输出流
- 当播放文件时,把文件内容写入AudioSystem的SourceDataLine
- 当录音时,把AudioSystem的TargetDataLine中的内容读入内存
关于该API的基础知识,请各位自行查阅API,以下给出一个用来播放音频文件的Demo
package com.ywq3;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class Test {
public static void main(String[] args) throws Exception, IOException {
AudioInputStream audioInputStream;// 文件流
AudioFormat audioFormat;// 文件格式
SourceDataLine sourceDataLine;// 输出设备
File file = new File("D:\\music.wav");
// 取得文件输入流
audioInputStream = AudioSystem.getAudioInputStream(file);
audioFormat = audioInputStream.getFormat();
// 转换文件编码
if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(), 16, audioFormat.getChannels(),
audioFormat.getChannels() * 2, audioFormat.getSampleRate(),
false);
audioInputStream = AudioSystem.getAudioInputStream(audioFormat,
audioInputStream);
}
// 打开输出设备
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
audioFormat, AudioSystem.NOT_SPECIFIED);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat); // 打开具有指定格式的行,这样可以使行获得所有所需的系统资源并变得可操作
sourceDataLine.start(); // 允许某一数据行执行数据I/O
byte tempBuffer[] = new byte[320];
try {
int cnt;
// 读取数据到缓存区
// 从音频流读取指定的最大数量的数据字节,并将其放入给定的字节数组中。
// return: 读入缓冲区的总字节数;如果因为已经到达流末尾而不再有更多数据,则返回-1
while ((cnt = audioInputStream.read(tempBuffer, 0,
tempBuffer.length)) != -1) {
if (cnt > 0) {
// 写入缓存数据
sourceDataLine.write(tempBuffer, 0, cnt); // 通过此源数据行将音频数据写入混频器
}
}
// Block等待临时数据被输出为空
// 通过在清空数据行的内部缓冲区之前继续数据I/O,排空数据行中的列队数据
sourceDataLine.drain();
// 关闭行,指示可以释放的该行使用的所有系统资源。如果此操作成功,则将行标记为 closed,并给行的侦听器指派一个 CLOSE 事件。
sourceDataLine.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
若程序正常运行,我们应该可以听到D盘下的一个叫做music.wav的音频文件被播放。
若程序报错:
could not get audio input stream from input file
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1189)
at com.ywq3.Test.main(Test.java:21)
异常信息是说,不支持的格式,即该音频文件不支持,得不到该文件的输入流。
原因分析:
Javax sound API默认支持的格式通过AudioFileFormate源码可以看出,是支持wav文件的,如下所示:
开始我百思不得其解,后来发现wav格式的音频文件是有其固定格式的,若明明是wav文件,却报错说不支持该格式,则可能是该wav文件内部格式有错误。
关于wav内部格式请详见: http://blog.csdn.net/y96q1023/article/details/70307753
我先前使用的一个wav文件是直接通过io流合成的,所以一直报不支持的错误。后来使用了一个正确的wav文件,则可以播放。
下边给出一段如何使用javax sound合成wav音频文件的Demo,希望可以帮到各位小伙伴~
import java.io.File;
import java.io.IOException;
import java.io.SequenceInputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class WavAppender {
public static void main(String[] args) {
String wavFile1 = "D:\\wav1.wav";
String wavFile2 = "D:\\wav2.wav";
try {
AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(wavFile1));
AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(wavFile2));
AudioInputStream appendedFiles =
new AudioInputStream(
new SequenceInputStream(clip1, clip2),
clip1.getFormat(),
clip1.getFrameLength() + clip2.getFrameLength());
AudioSystem.write(appendedFiles,
AudioFileFormat.Type.WAVE,
new File("D:\\wavAppended.wav"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果对你有帮助,记得 点赞 哦~欢迎大家关注我的博客,可以 进群366533258 一起交流学习哦~
本群给大家提供一个学习交流的平台,内设菜鸟 Java 管理员一枚、精通算法的金牌讲师一枚、Android管理员一枚、蓝牙BlueTooth管理员一枚、Web前端管理一枚以及C#管理一枚。欢迎大家进来交流技术。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Flex读取txt文件中的内容报错原因分析及解决
- Python 抓取网页乱码原因分析
- 生产系统 SQL 执行异常原因分析
- go http 框架性能大幅下降原因分析
- ajax获取json数据为undefined原因分析
- RocketMQ 消息发送 system busy、broker busy 原因分析与解决方案
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Pragmatic Programmer
Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!