📄 captureplaybackclient.java
字号:
for (int i = 0; i < audioBytes.length; i++) {
audioData[i] = audioBytes[i] - 128;
}
}
}
int frames_per_pixel = audioBytes.length / format.getFrameSize() / w;
byte my_byte = 0;
double y_last = 0;
int numChannels = format.getChannels();
for (double x = 0; x < w && audioData != null; x++) {
int idx = (int) (frames_per_pixel * numChannels * x);
if (format.getSampleSizeInBits() == 8) {
my_byte = (byte) audioData[idx];
}
else {
my_byte = (byte) (128 * audioData[idx] / 32768);
}
double y_new = (double) (h * (128 - my_byte) / 256);
//增加点!
lines.add(new Line2D.Double(x, y_last, x, y_new));
y_last = y_new;
}
//repaint();//???
}
//使用线程画波形图!hlf
public void paint(Graphics g) {
// 组件JPanel的大小;Returns the size of this component in the form of a <code>Dimension</code> object
Dimension d = getSize();
int w = d.width;
int h = d.height;
int INFOPAD = 15;
// 精确控制几何图形 Graphics2D——sophisticated control over geometry
// 在JPanel上画画!
Graphics2D g2 = (Graphics2D) g;
g2.setBackground(getBackground());
g2.clearRect(0, 0, w, h); //???300,60
g2.setColor(Color.white);
g2.fillRect(0, h - INFOPAD, w, INFOPAD);
//捕获出错的情况1
if (errStr != null) {
g2.setColor(jfcBlue);
g2.setFont(new Font("serif", Font.BOLD, 18));
g2.drawString("ERROR", 5, 20);
AttributedString as = new AttributedString(errStr);
as.addAttribute(TextAttribute.FONT, font12, 0, errStr.length());
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = g2.getFontRenderContext();
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
float x = 5, y = 25;
lbm.setPosition(0);
while (lbm.getPosition() < errStr.length()) {
TextLayout tl = lbm.nextLayout(w - x - 5);
if (!tl.isLeftToRight()) {
x = w - tl.getAdvance();
}
tl.draw(g2, x, y += tl.getAscent());
y += tl.getDescent() + tl.getLeading();
}
}
//正捕获中的情况2
else if (capture.thread != null) {
g2.setColor(Color.black);
g2.setFont(font12);
g2.drawString("Length: " + String.valueOf(seconds), 3, h - 4);
}
//捕获结束的情况3
else {
g2.setColor(Color.black);
g2.setFont(font12);
g2.drawString("文件名: " + fileName + " 长度: " +
String.valueOf(duration) + " 当前位置(秒): " +
String.valueOf(seconds), 3, h - 4);
if (audioInputStream != null) {
// 画声音波形图.. render sampling graph ..
g2.setColor(jfcBlue);
for (int i = 1; i < lines.size(); i++) {
g2.draw( (Line2D) lines.get(i));
}
// 画当前位置图.. draw current position ..
if (seconds != 0) {
double loc = seconds / duration * w;
g2.setColor(pink);
g2.setStroke(new BasicStroke(3));
g2.draw(new Line2D.Double(loc, 0, loc, h - INFOPAD - 2));
}
}
}
}
public void start() {
thread = new Thread(this);
thread.setName("SamplingGraph");
thread.start();
seconds = 0;
}
public void stop() {
if (thread != null) {
thread.interrupt();
}
thread = null;
}
public void run() {
seconds = 0;
while (thread != null) {
if ( (playback.line != null) && (playback.line.isOpen())) {
long milliseconds = (long) (playback.line.getMicrosecondPosition() /
1000);
seconds = milliseconds / 1000.0;
}
else if ( (capture.line != null) && (capture.line.isActive())) {
long milliseconds = (long) (capture.line.getMicrosecondPosition() /
1000);
seconds = milliseconds / 1000.0;
}
try {
thread.sleep(100);
}
catch (Exception e) {
break;
}
repaint();
while ( (capture.line != null && !capture.line.isActive()) ||
(playback.line != null && !playback.line.isOpen())) {
try {
thread.sleep(10);
}
catch (Exception e) {
break;
}
}
}
seconds = 0;
repaint();
}
} // End class SamplingGraph
public static void main(String s[]) {
CapturePlaybackClient CapturePlaybackClient = new CapturePlaybackClient();
CapturePlaybackClient.open();
JFrame f = new JFrame("欢迎使用客户端语音系统");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.getContentPane().add("Center", CapturePlaybackClient);
f.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int w = 400;//720;
int h = 340;
//使frame居中
f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h / 2);
f.setSize(w, h);
f.show();
}
class ConnSocket
implements Runnable { //extend Thead;
Socket socket;
boolean runing = true;
//输出流:BufferedOutputStream
BufferedOutputStream bos;
OutputStream os;
//声音流
AudioInputStream audioInputStream = null;
Thread thread;
public void start() {
thread = new Thread(this);
thread.setName("Client");
startup();
thread.start();
}
public void stop() {
try {
socket.close();
socket = null;
}
catch (IOException ex) {
}
thread = null;
}
public void startup(){
if (socket==null)
try {
socket = new Socket("localhost", 1983);
}
catch (UnknownHostException ex) {
System.out.println("意外错误");
}
catch (IOException ex) {
System.out.println("IO错误");
}
}
public void run() {
/**
* 声明soundAPI里的 AudioFormat格式对象
*/
AudioFormat DEFAULT_AUDIO_FORMAT = new AudioFormat(
//Encoding
AudioFormat.Encoding.PCM_SIGNED,
//Sample rate
22050f, //Sample size in bytes
16, //Number of channels
2, //Frame size
4, //Frame rate
22050f, //Big endian
false
);
//interface TargetDataLine (Autoformat,bufsize)
TargetDataLine line;
FormatControls formatControls=new FormatControls();
AudioFormat format = formatControls.getFormat();
// AudioFormat format = DEFAULT_AUDIO_FORMAT;
boolean recording = false;
try {
//懒汉模式
os = socket.getOutputStream();
bos = new BufferedOutputStream(socket.getOutputStream());
System.out.println("连接成功");
/**
*
*/
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
//转化为TargetDataLine接口类型,以使用open(format, line.getBufferSize())函数!
line = (TargetDataLine) AudioSystem.getLine(info);
System.out.println(line.getBufferSize());
line.open(format, line.getBufferSize());
//返回每帧的大小
int frameSizeInBytes = format.getFrameSize();
//返回buf里的(8字节)帧数The number of frames = the size of the buffer
int bufferLengthInFrames = line.getBufferSize() / 8;
//buf总大小Number of frames * frame size = total bytes
int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
//新建的buf大小的字节数组Make a new byte[] the size of the AudioBuffer
byte[] buf = new byte[bufferLengthInBytes];
System.out.println("bufferLengthInBytes:" + bufferLengthInBytes);
//ByteArrayOutputStream 见78行的ByteArrayInputStream
ByteArrayOutputStream out = new ByteArrayOutputStream();
int numBytesRead; //缓存Cache the number of bytes we have read
line.start();
while (runing) {
System.out.println(runing);
if ( (numBytesRead = line.read(buf, 0, bufferLengthInBytes)) == -1) {
break;
}
//out.write(buf, 0, numBytesRead);
//byte audioBytes[] = out.toByteArray();字节数组流
//(buf)是 新建的buf大小的字节数组
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
buf);
/**ByteArrayInputStream--->AudioInputStream
* AudioInputStream(buf大小的字节数组,声音格式,帧数)
*/
audioInputStream = new AudioInputStream(byteArrayInputStream, format,
buf.length / frameSizeInBytes);
System.out.println("audioInputStream.available:" +
audioInputStream.available() + "buf.length " +
buf.length + " frameSizeInBytes" +
frameSizeInBytes);
/**
* Writes a stream of bytes representing an audio file of the specified file type
* to the output stream provided. Some file types require that
* the length be written into the file header; such files cannot be written from
* start to finish unless the length is known in advance. An attempt
* to write a file of such a type will fail with an IOException if the length in
* the audio file type is <code>AudioSystem.NOT_SPECIFIED</code>.
*
* @param stream the audio input stream containing audio data to be
* written to the file
* @param fileType the kind of audio file to write
* @param out the stream to which the file data should be written
* @return the number of bytes written to the output stream
* @throws IOException if an input/output exception occurs
* @throws IllegalArgumentException if the file type is not supported by
* the system
* @see #isFileTypeSupported
* @see #getAudioFileTypes
*/
//将输入流写入输出字节buf流 bos==BufferedOutputStream
//AudioFileFormat(Type type, int byteLength, AudioFormat format, int frameLength)
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, bos); //bos-->os
//API说明:write(AudioInputStream stream, AudioFileFormat.Type fileType,OutputStream out)
/**关于socket:
*将字符串转化成为out输出流,out.println && 从流中得到字符串: in.readLine()
* PrintWriter =out类型 out.println(string s); BufferedReader=in类型 in.readline();
*/
}
System.out.println("完成...");
System.exit(0);
}
catch (Exception err) {
System.out.println("youProblem");
err.printStackTrace();
connB.setText("连接");
this.stop();
}
}
/*
public void runBare()throws Throwable {
try{
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, bos);
}
catch (Exception err) {
System.out.println("Problem");
err.printStackTrace();
throw err;
}
}
*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -