美文网首页
http实时语音

http实时语音

作者: 凌康ACG | 来源:发表于2022-04-30 15:28 被阅读0次

    上次我编写了用websocket传输视频 https://www.jianshu.com/p/a9ee255fc0ae ,发现有很多人问怎么没有语音。

    还有就是之前觉得简书广告多就离开了,转战CSDN(床上等你)。快来关注给我点个赞吧:
    https://blog.csdn.net/weixin_44480167

    语音的本质还是字节的传输,声音采集→转化字节→传输→播放。按照这个思路,我们可以开发一个即时通话的系统,下面我会演示基于http的实时语音。

    要知道,现在的音视频入门削微有点难度。网上的那些SDK都是收费教你做人的,你看到这篇文章就等于白嫖

    只要你逻辑处理得好就能做到超低延迟,性能就别在意了,现在的设备分分钟可以忽略这点能耗,大规模就需要花点信息,例如使用FFmpeg做混音、消除回响处理(多人通话)

    创建普通springboot项目

    我们随手创建一个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");
        }
    
        // 用于实时响应音频
        @GetMapping("/a")
        public void a(HttpServletResponse response) throws Exception {
            System.out.println("进入音频录制....");
            response.setContentType("audio/wav");// 要在http响应内容为wav,用于浏览器识别和播放
    
            // 基本声道设置、声音采集等
            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();
    
            // 创建一个临时文件用来一边读取一边写入音频   实际开发应该注意内存溢出等问题处理
            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) {// 未能读到字节就延迟一下
                                Thread.sleep(500);
                            } else {
                                response.getOutputStream().write(by);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            AudioInputStream ais = new AudioInputStream(auline);
            // 写入 wav  一定要格式转化,否则浏览器无法识别流
            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>
    

    点击播放
    访问


    image.png

    即可达到实时语音通话。

    想要听到效果,电脑端用网易云播放音乐,再使用手机打开 192.168.31.199:8080 (与电脑处于局域网下,同一个路由器即可) 走远点,别让回声影响。

    例如自己用js处理自动播放、使用多线程、netty等实现字节流分发。要求高性能还能用go、rust、c++等实现音频流转发。
    其他文章:websocket实现简单的直播:https://www.jianshu.com/p/a9ee255fc0ae

    点个赞再走呗

    相关文章

      网友评论

          本文标题:http实时语音

          本文链接:https://www.haomeiwen.com/subject/okjyyrtx.html