微信小程序实现蓝牙开启自动播放BGM

下面是一个完整的微信小程序实现方案,当蓝牙设备连接时自动播放背景音乐(BGM)。

实现思路

  1. 监听蓝牙设备连接状态

  2. 当检测到蓝牙设备连接时,自动播放音乐

  3. 当蓝牙断开时,停止音乐播放

  4. 处理相关权限和用户交互

完整代码实现

1. 项目结构

text

复制代码
/pages
  /index
    index.js
    index.json
    index.wxml
    index.wxss

2. index.wxml

xml

复制代码
<view class="container">
  <view class="status">当前蓝牙状态: {{bluetoothStatus}}</view>
  <button bindtap="initBluetooth">初始化蓝牙</button>
  <button bindtap="startSearch">搜索设备</button>
  <view class="devices">
    <block wx:for="{{devices}}" wx:key="deviceId">
      <view class="device" bindtap="connectDevice" data-device="{{item}}">
        {{item.name}} ({{item.deviceId}})
      </view>
    </block>
  </view>
  <audio id="bgm" src="/assets/bgm.mp3" loop></audio>
</view>

3. index.wxss

css

复制代码
.container {
  padding: 20px;
}

.status {
  margin: 20px 0;
  font-size: 16px;
  color: #333;
}

button {
  margin-bottom: 10px;
}

.device {
  padding: 10px;
  border: 1px solid #eee;
  margin-bottom: 5px;
}

4. index.js

javascript

复制代码
Page({
  data: {
    bluetoothStatus: '未初始化',
    devices: [],
    connectedDeviceId: null,
    audioCtx: null
  },

  onLoad() {
    // 创建音频上下文
    this.setData({
      audioCtx: wx.createInnerAudioContext()
    });
    this.data.audioCtx.src = '/assets/bgm.mp3';
    this.data.audioCtx.loop = true;
    
    // 监听蓝牙适配器状态
    this.onBluetoothAdapterStateChange();
  },

  // 初始化蓝牙
  initBluetooth() {
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('蓝牙初始化成功', res);
        this.setData({ bluetoothStatus: '已初始化,未连接' });
        this.startBluetoothDevicesDiscovery();
      },
      fail: (err) => {
        console.error('蓝牙初始化失败', err);
        wx.showToast({
          title: '请打开手机蓝牙',
          icon: 'none'
        });
      }
    });
  },

  // 开始搜索设备
  startSearch() {
    this.startBluetoothDevicesDiscovery();
  },

  // 开始发现设备
  startBluetoothDevicesDiscovery() {
    wx.startBluetoothDevicesDiscovery({
      success: (res) => {
        console.log('开始搜索设备', res);
        this.onBluetoothDeviceFound();
      },
      fail: (err) => {
        console.error('搜索设备失败', err);
      }
    });
  },

  // 监听发现新设备事件
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      const devices = res.devices;
      console.log('发现新设备', devices);
      if (devices.length > 0) {
        this.setData({
          devices: this.data.devices.concat(devices)
        });
      }
    });
  },

  // 连接设备
  connectDevice(e) {
    const device = e.currentTarget.dataset.device;
    const deviceId = device.deviceId;
    
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        console.log('连接成功', res);
        this.setData({ 
          bluetoothStatus: `已连接: ${device.name}`,
          connectedDeviceId: deviceId
        });
        
        // 连接成功后播放BGM
        this.playBGM();
      },
      fail: (err) => {
        console.error('连接失败', err);
      }
    });
  },

  // 播放背景音乐
  playBGM() {
    this.data.audioCtx.play();
    wx.showToast({
      title: '蓝牙已连接,开始播放音乐',
      icon: 'none'
    });
  },

  // 停止背景音乐
  stopBGM() {
    this.data.audioCtx.stop();
    wx.showToast({
      title: '蓝牙已断开,停止播放音乐',
      icon: 'none'
    });
  },

  // 监听蓝牙适配器状态变化
  onBluetoothAdapterStateChange() {
    wx.onBluetoothAdapterStateChange((res) => {
      console.log('蓝牙适配器状态变化', res);
      if (!res.available) {
        this.setData({ bluetoothStatus: '蓝牙不可用' });
        this.stopBGM();
      } else if (res.discovering) {
        this.setData({ bluetoothStatus: '正在搜索设备...' });
      } else {
        this.setData({ bluetoothStatus: '蓝牙已开启' });
      }
    });
  },

  // 监听BLE连接状态变化
  onBLEConnectionStateChange() {
    wx.onBLEConnectionStateChange((res) => {
      console.log('BLE连接状态变化', res);
      if (res.connected) {
        this.setData({ 
          bluetoothStatus: `已连接: ${res.deviceId}`,
          connectedDeviceId: res.deviceId
        });
        this.playBGM();
      } else {
        this.setData({ 
          bluetoothStatus: '蓝牙已断开',
          connectedDeviceId: null
        });
        this.stopBGM();
      }
    });
  },

  onUnload() {
    // 页面卸载时停止搜索和断开连接
    wx.stopBluetoothDevicesDiscovery();
    if (this.data.connectedDeviceId) {
      wx.closeBLEConnection({ deviceId: this.data.connectedDeviceId });
    }
    wx.closeBluetoothAdapter();
    
    // 停止音乐
    this.data.audioCtx.stop();
    this.data.audioCtx.destroy();
  }
});

5. index.json

json

复制代码
{
  "usingComponents": {},
  "requiredBackgroundModes": ["audio", "bluetooth"]
}

关键点说明

  1. 权限配置:

    • app.json中配置requiredBackgroundModes以保证后台运行权限

    • 需要用户授权蓝牙和音频权限

  2. 蓝牙流程:

    • 初始化蓝牙适配器(openBluetoothAdapter)

    • 开始搜索设备(startBluetoothDevicesDiscovery)

    • 监听发现设备(onBluetoothDeviceFound)

    • 连接设备(createBLEConnection)

    • 监听连接状态(onBLEConnectionStateChange)

  3. 音频控制:

    • 使用wx.createInnerAudioContext创建音频上下文

    • 连接成功时调用play()方法

    • 断开连接时调用stop()方法

  4. 用户体验:

    • 显示蓝牙状态变化

    • 连接/断开时有Toast提示

    • 页面卸载时清理资源

注意事项

  1. 真机测试:

    • 此功能必须在真机上测试,开发者工具可能无法完全模拟蓝牙功能
  2. 音频文件:

    • 将背景音乐文件放在/assets/目录下

    • 确保音频文件格式兼容(建议使用mp3格式)

  3. 蓝牙限制:

    • iOS和Android的蓝牙API有差异,需测试兼容性

    • 部分旧机型可能不支持某些蓝牙功能

  4. 后台播放:

    • 小程序进入后台后可能会被暂停,需要合理配置后台运行权限
  5. 用户授权:

    • 首次使用蓝牙功能时需要用户授权

    • 处理用户拒绝授权的场景

这个实现提供了完整的蓝牙连接监听和音频自动播放功能,你可以根据实际需求进一步定制UI和交互逻辑。