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

如何用Python通过蓝牙从iPhone接收音频数据及元数据?

问题:Python蓝牙脚本无法接收iPhone音频数据

背景

我正在编写Python脚本,实现通过蓝牙将iPhone音频传输到树莓派。目前iPhone在「设置>蓝牙」中选择已配对的树莓派后,音频能正常从树莓派扬声器输出。我将树莓派设备类型设为「车载音响」,以便后续通过AVRCP连接获取播放歌曲的元数据。

我使用PyBluez获取到iPhone的可用蓝牙服务列表,返回的字典列表格式如下:

{'service-classes': ['110A'], 'profiles': [('110D', 259)], 'name': 'Audio Source', 'description': None, 'provider': None, 'service-id': None, 'protocol': 'RFCOMM', 'port': 13, 'host': 'FF:FF:FF:FF:FF:FF'}

当前问题

我的代码仅能打印可用服务列表,之后就不再输出任何内容。我尝试了包括'Audio Source'、'Wireless iAP'在内的多数可用服务,均无效果。另外,只有当iPhone打开「设置>蓝牙」(相当于配对模式)时,代码才能正常运行。

现有代码

import bluetooth as bt
from bluetooth import BluetoothSocket

if __name__ == "__main__":
    services = bt.find_service()
    
    print(sep='\n', *services)
    
    for service in services:
        if service['name'] == 'Audio Source':
            socket = BluetoothSocket()
            socket.bind((service['host'], service['port']))
    
    print('\nListening...')
    
    while True:
        print(socket.recv(1024))

解决方案

你的代码存在几个关键问题,以下是修复步骤:

  • 指定套接字协议:创建BluetoothSocket时需要明确传入RFCOMM协议参数,因为音频服务基于RFCOMM
  • 修正绑定地址:不能绑定广播地址FF:FF:FF:FF:FF:FF,应该绑定树莓派自身的蓝牙地址,或者用空字符串''监听所有本地蓝牙接口
  • 添加监听与连接逻辑:绑定后需要调用listen()开始监听,再用accept()等待并接受iPhone的连接,之后才能接收数据
  • 处理连接后的循环接收:只有在建立连接后,才能进入循环调用recv()

修复后的代码示例

import bluetooth as bt
from bluetooth import BluetoothSocket, RFCOMM

if __name__ == "__main__":
    # 获取可用服务(可选,用于确认端口)
    services = bt.find_service()
    print(sep='\n', *services)

    # 初始化RFCOMM套接字
    server_socket = BluetoothSocket(RFCOMM)
    # 绑定到本地蓝牙接口(空字符串表示所有接口),端口用服务列表中的13
    server_socket.bind(('', 13))
    # 开始监听,最多允许1个连接
    server_socket.listen(1)

    print('\nListening for iPhone audio connection...')
    # 等待接受连接,返回连接套接字和客户端地址
    client_socket, client_info = server_socket.accept()
    print(f'Connected from {client_info}')

    try:
        while True:
            # 接收音频数据,注意音频是二进制数据,直接打印会乱码
            data = client_socket.recv(1024)
            if not data:
                break
            # 可以替换为处理音频数据的逻辑,比如写入扬声器设备
            print(f'Received {len(data)} bytes of audio data')
    except KeyboardInterrupt:
        print('\nStopping server')
    finally:
        client_socket.close()
        server_socket.close()

额外说明

  1. 音频数据是二进制格式,直接打印会显示乱码,建议将数据写入树莓派的音频输出设备(比如/dev/audio或使用PyAudio库处理)
  2. 确保树莓派的蓝牙服务(比如bluetoothd)已正确配置,且AVRCP相关模块已启用
  3. iPhone连接时需要在蓝牙设置中选择树莓派作为音频输出设备,此时才会建立音频流连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:15:14