首页 > 其他分享 >使用WebSocket协议实现在ESP32上音频接收播放

使用WebSocket协议实现在ESP32上音频接收播放

时间:2024-09-12 21:21:48浏览次数:15  
标签:WebSocket ESP32 I2S 服务器 websocket audio 音频

 主要目的:学习WebSocket通讯协议和ESP32开发

所需配置:Pycharm, python3.12, ESP32S3N16R8, 扬声器(8欧,2W), 功放模块:MAX98357 I2S AMP。

一、介绍 

1、WebSocket协议 

WebSocket是一种网络通信协议,位于OSI模型的应用层。它提供了在单个TCP连接上进行全双工通信的能力,使得客户端和服务器之间的数据交换变得更加实时和高效。

WebSocket协议主要特点如下:

  1. 全双工通信:在WebSocket协议下,客户端和服务器可以在任何时候,互相发送消息,而不需要轮询。

  2. 持久连接:一旦建立WebSocket连接,客户端和服务器之间的连接会持续开放,直到任何一方显式地关闭连接。

  3. 减少开销:与HTTP相比,WebSocket减少了频繁的头部和握手信息,因此在大量数据交换时,可以减少延迟。

  4. 握手:WebSocket连接的建立是基于HTTP的,使用HTTP的Upgrade头从HTTP协议切换到WebSocket协议。

  5. 消息格式:WebSocket传输的数据可以是文本格式,也可以是二进制格式。

  6. 服务器推送:服务器可以主动推送信息到客户端,这对于实时应用,如在线游戏、实时交易系统等是非常有用的。

WebSocket协议广泛应用于需要实时互动的应用中,如即时聊天、游戏、实时交易系统、在线协作工具等。

WebSocket协议的URL以ws://wss://开始,其中wss://表示使用了SSL加密的WebSocket连接。这个协议在现代的浏览器中得到了广泛的支持。

2、ESP32

ESP32是一款由乐鑫信息科技(Espressif Systems)推出的低成本、低功耗的系统级芯片(SoC),它集成了Wi-Fi和双模蓝牙(经典蓝牙/蓝牙低功耗BLE)功能。ESP32适用于各种物联网(IoT)应用、智能家居项目、无线通信产品以及其他需要网络连接的嵌入式系统。

二、具体实现

(1)服务器端(发送音频):

由于WebSocket可接受的url地址是ws://和wss://(加密)格式的,网上暂时没有找到现成的地址,因此验证时可以自己搭建一个简易服务器。

环境搭建:Python3.12    Pycharm

需安装包:pip install asyncio websockets wave

服务器地址和端口:本电脑当服务器,IP地址就填本电脑的。端口号可以自己配置

查看自己电脑的IP地址请参考:如何快速查看电脑ip地址?四种方法告诉你_电脑ip地址查询-CSDN博客

音频文件:daoxiang.wav

启动方式:点击运行WebServer.py(当前脚本),服务器启动,一直运行

具体代码:

import asyncio
import websockets
import wave

# 服务器地址和端口
HOST = '172.19.1.180'  # 可以替换为服务器的实际 IP 地址或域名(本电脑的IP地址)
PORT = 8765            # WebSocket 服务器端口

# 音频文件路径
AUDIO_FILE_PATH = 'D:\\daoxiang.wav'  # 音频文件路径

async def send_audio(websocket, path):
    print(f"客户端已连接: {websocket.remote_address}")

    # 打开音频文件
    try:
        with wave.open(AUDIO_FILE_PATH, 'rb') as wf:
            print(f"音频文件 {AUDIO_FILE_PATH} 已打开.")

            # 获取音频文件参数
            chunk_size = 1024  # 每次发送的数据块大小
            n_channels = wf.getnchannels()
            sampwidth = wf.getsampwidth()
            framerate = wf.getframerate()

            print(f"音频参数: {n_channels} 通道, {sampwidth} 字节样本宽度, {framerate} 采样率.")

            # 逐块读取音频数据并发送给客户端
            while True:
                audio_data = wf.readframes(chunk_size)
                if not audio_data:  # 如果读取完所有数据,退出循环
                    break

                # 发送音频数据给客户端
                await websocket.send(audio_data)
                await asyncio.sleep(0.01)  # 确保非阻塞发送,控制发送速度

    except websockets.ConnectionClosed as e:
        print(f"客户端断开连接: {e}")
    except Exception as e:
        print(f"发生错误: {e}")

async def start_server():
    # 创建 WebSocket 服务器
    async with websockets.serve(send_audio, HOST, PORT):
        print(f"WebSocket 服务器已启动: ws://{HOST}:{PORT}/")
        await asyncio.Future()  # 运行服务器,直到手动停止

# 运行服务器
asyncio.run(start_server())

(2)接收端(接收音频并播放):

a. ESP32S3

Arduino需安装WebSockets包(这里是2.3.6版本,其他版本兼容性未做测试):

MAX98357 I2S AMP(Speaker – 和 + 连接扬声器)

代码如下

#include "Arduino.h"

#include "WiFi.h"

#include <WebSocketsClient.h>

#include <driver/i2s.h> // 使用ESP32 I2S库

// WiFi 信息

const char* ssid = "your wifi"; // 替换为WiFi名称

const char* password = "12345678"; // 替换为WiFi密码

// WebSocket 服务器信息

const char* websocket_server = "172.19.1.170"; // 替换为WebSocket服务器IP地址

const uint16_t websocket_port = 8765; // WebSocket服务器端口

const char* websocket_path = "/"; // WebSocket路径

WebSocketsClient webSocket; // 创建 WebSocket 客户端对象

void onWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {

    switch (type) {

        case WStype_CONNECTED:

            Serial.println("Connected to WebSocket server");

            break;

        case WStype_DISCONNECTED:

            Serial.println("Disconnected from WebSocket server");

            break;

        case WStype_BIN:

            // 将接收到的二进制音频数据写入 I2S

            size_t bytes_written;

            i2s_write(I2S_NUM_0, payload, length, &bytes_written, portMAX_DELAY);

            break;

        case WStype_ERROR:

            Serial.println("WebSocket Error");

            break;

        default:

            break;

    }

}

void setup() {

    Serial.begin(115200);

    // 连接到 WiFi

    WiFi.disconnect();

    WiFi.mode(WIFI_STA);

    WiFi.begin(ssid, password);

    // 等待连接到 WiFi

    while (WiFi.status() != WL_CONNECTED) {

        delay(500);

        Serial.print(".");

    }

    Serial.println("Connected to WiFi");

    // 初始化 I2S

    i2s_config_t i2s_config = {

        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),

        .sample_rate = 44100,

        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,

        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,

        .communication_format = I2S_COMM_FORMAT_I2S_MSB,

        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,

        .dma_buf_count = 8,

        .dma_buf_len = 1024,

        .use_apll = false,

        .tx_desc_auto_clear = true,

        .fixed_mclk = 0

    };

    i2s_pin_config_t pin_config = {

        .bck_io_num = 3,    // BCLK 引脚

        .ws_io_num = 4,     // LRC 引脚

        .data_out_num = 5,  // DATA 输出引脚

        .data_in_num = I2S_PIN_NO_CHANGE

    };

    // 配置 I2S 接口

    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);

    i2s_set_pin(I2S_NUM_0, &pin_config);

    i2s_zero_dma_buffer(I2S_NUM_0);

    // 初始化 WebSocket 客户端

    webSocket.begin(websocket_server, websocket_port, websocket_path);

    webSocket.onEvent(onWebSocketEvent); // 设置 WebSocket 事件处理函数

    // 开始 WebSocket 连接

    webSocket.setReconnectInterval(5000); // 自动重连间隔

}

void loop() {

    webSocket.loop(); // 处理 WebSocket 客户端事件

}

b. 另一台PC运行py脚本

用于验证搭建的简易服务器是否在工作。

环境搭建:Python3.12    Pycharm

需安装包:pip install asyncio websockets pyaudio

服务器地址和端口:填服务器的IP地址和端口号如

# WebSocket 服务器的 URL
WS_URL = "ws://192.168.127.22:8765/"  # 服务器的实际 IP 地址或域名

配置音频播放参数:

CHUNK = 1024  # 每个数据块的大小
FORMAT = pyaudio.paInt16  # 音频格式
CHANNELS = 2  # 音频通道数量
RATE = 44100  # 采样率

启动方式:点击运行WebClient.py(当前脚本),确保服务器是在启动状态,连接音频设备,可以听到声音。

代码如下

import asyncio
import websockets
import pyaudio

# WebSocket 服务器的 URL
WS_URL = "ws://192.168.127.22:8765/"  # 服务器的实际 IP 地址或域名

# 配置音频播放参数
CHUNK = 1024  # 每个数据块的大小
FORMAT = pyaudio.paInt16  # 音频格式
CHANNELS = 2  # 音频通道数量(立体声)
RATE = 44100  # 采样率(每秒样本数)

# 初始化 PyAudio
audio = pyaudio.PyAudio()

# 创建流对象用于音频播放
stream = audio.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    output=True,
                    frames_per_buffer=CHUNK)


async def play_audio_from_websocket():
    async with websockets.connect(WS_URL) as websocket:
        print("已连接到 WebSocket 服务器...")
        try:
            while True:
                # 接收音频数据
                audio_data = await websocket.recv()

                # 将接收到的数据写入到音频流中播放
                stream.write(audio_data)

        except websockets.ConnectionClosed as e:
            print(f"WebSocket 连接关闭: {e}")
        except Exception as e:
            print(f"发生错误: {e}")


# 运行异步任务
asyncio.run(play_audio_from_websocket())

# 关闭流和 PyAudio
stream.stop_stream()
stream.close()
audio.terminate()

标签:WebSocket,ESP32,I2S,服务器,websocket,audio,音频
From: https://blog.csdn.net/m0_58445456/article/details/142185720

相关文章

  • AOSP配置音频政策-音量
    https://source.android.google.cn/docs/core/audio/implement-policy?hl=zh-cn配置音频政策Android10版本对音频政策管理器进行了重大重构,有助于更灵活地支持复杂的车载使用情形:提供了OEM专用路由策略。针对使用相同音量曲线的旧版音频流类型组提供了可自定义音量组。......
  • Websocket防护的重要性及应对策略:快快网络专家团队的创新实践
    WebSocket(WSS)因其双向和全双工通信的特点,在现代网络通信中得到广泛应用,尤其是在需要低延迟和实时数据交互的场景中。然而,随着WebSocket的普及,其安全性问题也日益凸显,各种针对WSS的攻击手段层出不穷,给企业的数据安全带来了严峻的挑战。针对WSS的攻击具有多样性和隐蔽性。其中,最......
  • C# WebSocket Fleck 内存泄漏
    最近在维护公司旧项目,内存泄漏严重,找了行业内大佬帮忙分析Dump文件(windbg我不擅长),大佬指出问题在于Fleck,这里记录一下。整理一下问题:1.大佬指出System.Threading.Tasks.ContinuationTaskFromTask和System.ObjectDisposedException有71完个对象。2.System.ObjectDisposedE......
  • tronado websocket
    server代码:fromflaskimportFlaskfromflask_corsimportCORSfromtornadoimportwebsocket,ioloop,webfromtornado.webimportFallbackHandlerfromtornado.wsgiimportWSGIContainerfromapps.monitorimportinit_app#fromapps.utilsimportNumpyJSONPr......
  • 同三维TM810-8 200平米左右中型会议室音频解决方案
    同三维TM810-8有线8级联会议全向麦克风通过网线级联,A1机通过USB线连接电脑,A1机需接电源适配器,其它级联麦克风支持POE供电,每条网线是3米同三维TM810-8有线8级联会议全向麦克风TM810-8是一套内置4阵列麦克风和大功率扬声器的一拖八级联全向阵列麦克风,200平米中型会议室音......
  • NS4263B 3.1Wx2 双声道 AB/D 类双模音频功率放大器附加耳机模式
    1特性●工作电压范围:3.0V-5.5V●AB类和D类工作模式切换●一线脉冲控制工作模式与关断模式●内置立体声耳机输出功能●输出功率3.1W@ClassD/Load=4ohm●THD+N=0.2%@VDD=5V/Po=1W●优异的全带宽EMI抑制能力●优异的“上电和掉电”噪声抑制●内置过流保护......
  • pydub 基于python的音频剪辑包
    1下载ffmegwgethttps://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip把bin目录配置到path中,或者cd到ffmeg的bin目录下调用脚本2下载pydubpipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simplepydub3使用#导入f......
  • 如何将mp4转为mp3音频?4个方法详细分享给你
    将MP4视频转换为3GP视频的方法,对于许多用户来说是一个实用的需求,尤其是在需要将视频文件传输到老旧手机或特定设备上时。以下是几种常见且高效的转换方法,旨在帮助用户轻松完成视频格式的转换。方法一:使用【汇帮视频格式转换器】步骤一:选择并安装软件首先,用户需要在电脑上下载......
  • NS4263 3.0Wx2 双声道 AB/D 类双模音频功率放大器附加耳机模式
    1特性●工作电压范围:3.0V-5.25V●AB类和D类工作模式切换●一线脉冲控制工作模式与关断模式●内置立体声耳机输出功能●输出功率3W@ClassD/Load=4ohm●THD+N=0.1%@VDD=5V/Po=1W●优异的全带宽EMI抑制能力●优异的“上电和掉电”噪声抑制●内置过流保护......
  • websocket协议与http协议
    WebSocket协议和HTTP协议都是用于网络通信的协议,但它们在设计目标、通信方式和应用场景上有一些关键的区别。以下是它们的主要区别:1.设计目标HTTP:设计目标:HTTP旨在为万维网提供一种标准化的请求/响应机制,允许客户端和服务器之间进行数据交换。它是无状态的,每个请求都......