You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用CapacitorJS实现向两台蓝牙设备发送独立音频流?

问题解答

1. CapacitorJS 是否支持向两台蓝牙设备分别发送独立音频流?

CapacitorJS 本身是跨平台容器层,没有内置蓝牙音频流传输能力,但可以通过社区蓝牙插件结合 iOS 原生 CoreBluetooth 框架实现该功能。iOS 原生支持同时连接多个 BLE(低功耗蓝牙)设备,只要目标蓝牙设备支持音频数据接收的 GATT 服务/特征,就能分别向不同设备推送独立的音频数据流。

2. capacitor-community/bluetooth-le 能否实现定向传输音频到指定设备?

可以实现。该插件支持多设备同时连接,每个连接的设备会被分配唯一的 deviceId(或 UUID),你只需要在连接设备时保存每个设备的标识,后续发送数据时指定对应的 deviceId 即可实现定向传输。

需要注意:

  • 音频数据需要转换为二进制格式(比如将音频文件切片为符合 BLE MTU 大小的 Uint8Array 分片)
  • 需提前确认目标蓝牙设备的 GATT 服务 UUID 和可写特征 UUID,确保数据能被设备正确接收

3. 简单实现示例(Vue + Quasar + Capacitor Bluetooth LE)

以下是核心功能的实现代码,包含多设备连接、音频分片发送的逻辑:

1. 安装插件

npm install @capacitor-community/bluetooth-le
npx cap sync

2. 核心业务代码(Vue 组件)

<template>
  <q-page>
    <q-btn label="扫描并连接设备" @click="connectDevices" />
    <q-btn label="发送音频到设备1" @click="sendAudioToDevice(connectedDevices[0])" />
    <q-btn label="发送音频到设备2" @click="sendAudioToDevice(connectedDevices[1])" />
  </q-page>
</template>

<script setup>
import { BluetoothLe } from '@capacitor-community/bluetooth-le';
import { ref } from 'vue';

// 保存已连接的设备列表
const connectedDevices = ref([]);
// 音频文件转二进制分片(示例)
const audioChunks = ref([]);

// 初始化蓝牙并连接多设备
const connectDevices = async () => {
  try {
    // 初始化蓝牙
    await BluetoothLe.initialize({ requestPermissions: true });
    
    // 扫描设备(这里过滤目标设备,可根据名称或UUID筛选)
    const scanResult = await BluetoothLe.startScan({
      services: ['YOUR_TARGET_GATT_SERVICE_UUID'], // 替换为设备的服务UUID
      scanMode: 'lowLatency'
    });

    // 取前两个符合条件的设备连接
    const targetDevices = scanResult.devices.slice(0, 2);
    for (const device of targetDevices) {
      // 连接设备
      await BluetoothLe.connect({ deviceId: device.deviceId });
      // 发现服务和特征
      await BluetoothLe.discoverServices({ deviceId: device.deviceId });
      // 保存已连接设备
      connectedDevices.value.push(device);
    }

    await BluetoothLe.stopScan();
  } catch (error) {
    console.error('蓝牙连接失败:', error);
  }
};

// 加载音频文件并转为二进制分片
const loadAudioChunks = async (audioPath) => {
  // 从项目assets加载音频文件,转为ArrayBuffer
  const response = await fetch(audioPath);
  const arrayBuffer = await response.arrayBuffer();
  // 按BLE MTU大小分片(MTU通常为20-512,根据设备调整)
  const mtuSize = 200;
  audioChunks.value = [];
  for (let i = 0; i < arrayBuffer.byteLength; i += mtuSize) {
    const chunk = new Uint8Array(arrayBuffer.slice(i, i + mtuSize));
    audioChunks.value.push(chunk);
  }
};

// 向指定设备发送音频分片
const sendAudioToDevice = async (device) => {
  if (!device) return;
  // 提前加载音频分片(示例用项目内的audio1.mp3)
  await loadAudioChunks('assets/audio1.mp3');
  
  const characteristicUuid = 'YOUR_TARGET_CHARACTERISTIC_UUID'; // 替换为可写特征UUID
  try {
    for (const chunk of audioChunks.value) {
      await BluetoothLe.write({
        deviceId: device.deviceId,
        service: 'YOUR_TARGET_GATT_SERVICE_UUID',
        characteristic: characteristicUuid,
        value: chunk.buffer,
        writeType: 'withoutResponse' // 根据设备选择写入类型
      });
      // 加小延迟避免数据拥塞
      await new Promise(resolve => setTimeout(resolve, 10));
    }
    console.log('音频发送完成');
  } catch (error) {
    console.error('音频发送失败:', error);
  }
};
</script>

关键注意事项

  • 替换代码中的 YOUR_TARGET_GATT_SERVICE_UUID 和 YOUR_TARGET_CHARACTERISTIC_UUID 为实际蓝牙设备的对应UUID
  • iOS真机测试时,需在 Info.plist 中添加蓝牙权限描述:NSBluetoothAlwaysUsageDescription 和 NSBluetoothPeripheralUsageDescription
  • 音频分片大小需根据设备支持的MTU调整,过大的分片会导致传输失败
  • 写入类型 withoutResponse 适合音频流(低延迟),但无确认;需可靠传输可改用 withResponse

内容的提问来源于stack exchange,提问作者Qiuzman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:27:37