上次我編寫了用websocket傳輸視頻 http://www.reibang.com/p/a9ee255fc0ae 州既,發(fā)現(xiàn)有很多人問怎么沒有語音。
還有就是之前覺得簡書廣告多就離開了乳愉,轉(zhuǎn)戰(zhàn)CSDN(床上等你)剥啤「愣快來關(guān)注給我點個贊吧:
https://blog.csdn.net/weixin_44480167
語音的本質(zhì)還是字節(jié)的傳輸汽摹,聲音采集→轉(zhuǎn)化字節(jié)→傳輸→播放。按照這個思路惭蟋,我們可以開發(fā)一個即時通話的系統(tǒng)苗桂,下面我會演示基于http的實時語音。
要知道告组,現(xiàn)在的音視頻入門削微有點難度煤伟。網(wǎng)上的那些SDK都是收費教你做人的,你看到這篇文章就等于白嫖
只要你邏輯處理得好就能做到超低延遲木缝,性能就別在意了便锨,現(xiàn)在的設(shè)備分分鐘可以忽略這點能耗,大規(guī)模就需要花點信息我碟,例如使用FFmpeg
做混音放案、消除回響處理(多人通話)
創(chuàng)建普通springboot項目
我們隨手創(chuàng)建一個springboot項目
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
編寫一個controller
package top.lingkang.avdemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletResponse;
import javax.sound.sampled.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* @author lingkang
* Created by 2022/4/30
*/
@RestController
public class WebController {
@GetMapping("")
public ModelAndView index() {
return new ModelAndView("index");
}
// 用于實時響應(yīng)音頻
@GetMapping("/a")
public void a(HttpServletResponse response) throws Exception {
System.out.println("進入音頻錄制....");
response.setContentType("audio/wav");// 要在http響應(yīng)內(nèi)容為wav,用于瀏覽器識別和播放
// 基本聲道設(shè)置矫俺、聲音采集等
AudioFormat format = new AudioFormat(16000, 8, 2, true, true);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine auline = (TargetDataLine) AudioSystem.getLine(info);
auline.open(format);
auline.start();
// 創(chuàng)建一個臨時文件用來一邊讀取一邊寫入音頻 實際開發(fā)應(yīng)該注意內(nèi)存溢出等問題處理
File temp = File.createTempFile(".wav", ".tmp");
new Thread(new Runnable() {// 用線程來讀取
@Override
public void run() {
try {
Thread.sleep(100);
byte[] by = new byte[512];
InputStream in = new FileInputStream(temp);
for (; ; ) {
int read = in.read(by);
if (read == -1) {// 未能讀到字節(jié)就延遲一下
Thread.sleep(500);
} else {
response.getOutputStream().write(by);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
AudioInputStream ais = new AudioInputStream(auline);
// 寫入 wav 一定要格式轉(zhuǎn)化吱殉,否則瀏覽器無法識別流
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, temp);
}
}
以上使用java的音源錄入其實挺拉胯的
然后編寫一個前端html用于實時播放
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<audio src="./a" controls="controls">wav</audio>
</body>
</html>
點擊播放
訪問
即可達到實時語音通話。
想要聽到效果厘托,電腦端用網(wǎng)易云播放音樂友雳,再使用手機打開 192.168.31.199:8080 (與電腦處于局域網(wǎng)下,同一個路由器即可) 走遠(yuǎn)點催烘,別讓回聲影響沥阱。
例如自己用js處理自動播放、使用多線程伊群、netty等實現(xiàn)字節(jié)流分發(fā)考杉。要求高性能還能用go、rust舰始、c++等實現(xiàn)音頻流轉(zhuǎn)發(fā)崇棠。
其他文章:websocket實現(xiàn)簡單的直播:http://www.reibang.com/p/a9ee255fc0ae