zephyr架构下Bluetooth advertising接口

目录

概述

1 函数接口

2 主要函数介绍

2.1 bt_le_adv_start函数

2.1.1 函数功能介绍

2.1.2 典型使用示例

2.1.3 广播间隔

2.1.4 注意事项

2.2 bt_le_adv_stop 函数

2.2.1  函数功能

 2.2.2 使用方法介绍

2.2.3 实际应用示例

2.2.4 关键注意事项

 2.2.5 常见问题解决

2.2.6 应用总结 

2.3 bt_enable

2.3.1 函数功能

 2.3.2 典型使用模式

2.3.3 关键处理流程

 2.3.4 注意事项

 2.3.5 初始化失败常见原因

2.3.6  实际应用示例

2.3.7 应用总结

2.4 bt_le_adv_update_data函数

2.4.1 函数功能

 2.4.2 典型使用场景

2.4.3 关键特性

 2.4.4 实现原理

2.4.5 注意事项

 2.4.6 错误处理最佳实践

2.4.7 典型应用案例

2.4.8 应用总结


概述

本文主要介绍zephyr架构下Bluetooth advertising一些接口函数的功能和使用方法,这些函数是bluetooth的最重要的一些接口,掌握这些函数的用法是进行蓝牙功能开发的基础。

1 函数接口

基于zephyr OS架构下实现Bluetooth advertising功能其使用的函数接口有如下这些

函数名称功能说明

bt_le_adv_start

实现广播功能BLE模块被使能后,启用该函数进行广播,可通过设置不同的参数,实现不同的广播方式

bt_enable

使能BLE使能BLE的功能,该函数

bt_le_adv_stop

停止广播关闭广播功能,下次要重新广播时,需要调用bt_le_adv_start

bt_le_adv_update_data

更新广播数据

2 主要函数介绍

2.1 bt_le_adv_start函数

2.1.1 函数功能介绍

bt_le_adv_start 是蓝牙低功耗 (BLE) 协议栈中的一个关键 API 函数,用于启动设备的广播(Advertising)功能。这个函数允许 BLE 设备(Peripheral 角色)向周围设备广播自己的存在,并携带相关信息。bt_le_adv_start 是 BLE 设备广播功能的核心 API,合理配置广播参数和数据可以优化设备发现性、连接速度和功耗表现。开发者需要根据具体应用场景(如 Beacon、可连接外设等)选择合适的广播模式和数据结构。

1)功能概述

  • 作用:启动 BLE 设备的广播功能

  • 适用角色:Peripheral(外设)或 Broadcaster(广播者)

  • 广播模式:可配置为可连接广播、不可连接广播、可扫描广播等

  • 广播数据:可携带设备名称、服务 UUID、厂商数据等

2)函数原型:

int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad,size_t ad_len,const struct bt_data *sd,size_t sd_len);

3)参数说明

参数类型说明
parambt_le_adv_param*广播参数配置(广播类型、间隔等)
adbt_data*广播数据(Advertising Data)
ad_lensize_t广播数据项数量
sdbt_data*扫描响应数据(Scan Response Data)
sd_lensize_t扫描响应数据项数量

4)广播参数配置(bt_le_adv_param)

struct bt_le_adv_param {uint8_t  id;        // 广播集 IDuint32_t options;   // 广播选项(如 BT_LE_ADV_OPT_CONNECTABLE)uint16_t interval_min; // 最小广播间隔(单位:0.625ms)uint16_t interval_max; // 最大广播间隔(单位:0.625ms)uint8_t  peer[6];   // 定向广播的目标地址(可选)
};

常用广播选项(options)

  • BT_LE_ADV_OPT_CONNECTABLE - 可连接广播

  • BT_LE_ADV_OPT_USE_NAME - 在广播中包含设备名称

  • BT_LE_ADV_OPT_SCANNABLE - 允许扫描响应

  • BT_LE_ADV_OPT_ONE_TIME - 仅广播一次

 5)广播数据类型(bt_data)

struct bt_data {uint8_t type;  // 数据类型(如 BT_DATA_NAME_COMPLETE)uint8_t data_len;const uint8_t *data;
};

2.1.2 典型使用示例

1)1. 基本可连接广播

static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};static const struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME,BT_GAP_ADV_FAST_INT_MIN_1,BT_GAP_ADV_FAST_INT_MAX_1,NULL
);bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), NULL, 0);

2)不可连接广播(Beacon 模式)

static const uint8_t beacon_data[] = {0x01, 0x02, 0x03, 0x04, // 厂商特定数据
};static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NONCONN_IND),BT_DATA(BT_DATA_MANUFACTURER_DATA, beacon_data, sizeof(beacon_data)),
};bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);

2.1.3 广播间隔

BLE 广播间隔以 0.625ms 为单位:

  • 快速广播:20ms - 60ms(BT_GAP_ADV_FAST_INT_MIN_1 = 32 = 20ms)

  • 慢速广播:100ms - 150ms(BT_GAP_ADV_SLOW_INT_MIN = 160 = 100ms)

返回值

  • 0:广播启动成功

  • 负值:错误码(如 -EINVAL 参数错误,-ENOMEM 内存不足)

2.1.4 注意事项

  1. 广播数据总长度不能超过 31 字节

  2. 扫描响应数据也受 31 字节限制

  3. 广播间隔影响功耗和可发现性

  4. 某些广播模式(如定向广播)有额外限制

2.2 bt_le_adv_stop 函数

2.2.1  函数功能

bt_le_adv_stop 是蓝牙低功耗 (BLE) 协议栈中的一个关键 API 函数,用于停止正在进行的广播。它通常与 bt_le_adv_start 配对使用,用于控制 BLE 设备的广播生命周期。

1)核心功能

  • 停止广播:立即终止当前正在进行的 BLE 广播

  • 释放资源:释放与广播相关的协议栈资源

  • 配合广播控制:通常用于动态广播管理场景

 2)函数原型(基于 Zephyr BLE 协议栈)

int bt_le_adv_stop(void);

参数

  • 无参数:直接停止当前活跃的广播

返回值

返回值说明
0停止广播成功
-EALREADY当前没有活跃的广播
其他负值其他错误(如协议栈错误)

 2.2.2 使用方法介绍

1) 基本启停控制

// 启动广播
bt_le_adv_start(...);// 一段时间后停止广播
bt_le_adv_stop();

2)条件性停止广播

if (need_to_stop_advertising) {int err = bt_le_adv_stop();if (err) {printk("Stop failed (err %d)\n", err);}
}

3) 广播模式切换

// 先停止当前广播
bt_le_adv_stop();// 更换参数后重新启动
bt_le_adv_start(new_params, ...);

2.2.3 实际应用示例

场景:温度传感器按需广播

void start_temp_advertising(void) {bt_le_adv_start(..., temp_ad_data, ...);
}void stop_advertising_when_connected(void) {// 当连接建立时自动停止广播// 或手动调用:bt_le_adv_stop();
}void on_button_press(void) {// 按钮按下时重新广播bt_le_adv_stop();  // 先确保停止start_temp_advertising();
}

2.2.4 关键注意事项

  1. 无广播时的调用

    如果没有活跃的广播,调用会返回 -EALREADY(非致命错误)
  2. 线程安全性

    建议在协议栈线程(如 Zephyr 的 Bluetooth 线程)上下文中调用
  3. 与连接的交互

    如果设备已通过广播建立连接,广播会自动停止,此时调用会返回 -EALREADY
  4. 低功耗场景

    停止广播会显著降低功耗(广播是功耗主要来源之一)
  5. 广播集支持

    在支持多广播集的协议栈中(如 Zephyr 2.7+),可能需要指定广播集 ID

 2.2.5 常见问题解决

Q1:停止广播后为什么设备仍可被扫描到?
A1:可能是其他广播实例仍在运行,或广播停止有延迟(检查返回值)

Q2:如何确保广播完全停止?
A2:

do {err = bt_le_adv_stop();
} while (err == 0); // 直到返回-EALREADY

Q3:停止广播会影响已建立的连接吗?
A3:不会,只影响广播行为,不影响现有连接

2.2.6 应用总结 

bt_le_adv_stop 是 BLE 设备广播管理的核心控制点,合理使用可以实现:

  • 精确的广播生命周期控制

  • 动态广播策略切换

  • 有效的功耗管理

在需要频繁切换广播模式或优化功耗的场景中,正确使用该API至关重要。

2.3 bt_enable

2.3.1 函数功能

bt_enable 是蓝牙协议栈中的核心初始化函数,用于启用和初始化蓝牙控制器及协议栈。它是任何蓝牙应用程序的第一个关键调用,为后续所有蓝牙操作建立基础环境。

函数原型(基于Zephyr等常见协议栈)

int bt_enable(bt_ready_cb_t cb);

参数说明

参数类型说明
cbbt_ready_cb_t蓝牙初始化完成后的回调函数(可设为NULL)

 回调函数类型定义:

typedef void (*bt_ready_cb_t)(int err);

核心功能

  1. 硬件初始化

    • 初始化蓝牙射频控制器(Radio)

    • 配置底层硬件(如时钟、电源等)

  2. 协议栈加载

    • 加载HCI层、L2CAP、ATT/GATT等协议栈组件

    • 初始化安全管理器(SM)

  3. 默认配置应用

    • 设置默认蓝牙MAC地址

    • 应用编译时配置的默认参数

  4. 状态切换

    • 将蓝牙控制器从OFF状态切换到READY状态

返回值

返回值说明
0初始化流程成功启动(注意:实际结果通过回调返回)
-EALREADY蓝牙协议栈已启用
-ENOMEM内存不足
-EIO硬件初始化失败

 2.3.2 典型使用模式

1) 同步初始化(无回调)

int err = bt_enable(NULL);
if (err) {printk("Bluetooth init failed (err %d)\n", err);return;
}
// 继续其他蓝牙操作

2)异步初始化(带回调)

void bt_ready(int err) {if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");// 在这里启动广播/扫描等操作
}void main(void) {int err = bt_enable(bt_ready);if (err) {printk("Bluetooth enable failed (err %d)\n", err);}
}

2.3.3 关键处理流程

 2.3.4 注意事项

  1. 单次调用限制

    • 多数实现要求全局只调用一次

    • 重复调用需先调用bt_disable()

  2. 回调上下文

    • 回调函数通常在蓝牙线程执行

    • 避免在回调中进行阻塞操作

  3. 依赖关系

    • 必须在所有其他蓝牙API前调用

    • 通常应在系统初始化完成后调用

  4. 调试支持

    • 可通过CONFIG_BT_DEBUG等选项启用调试日志

 2.3.5 初始化失败常见原因

  1. 硬件问题

    • 蓝牙芯片未正确供电

    • 射频电路故障

  2. 配置冲突

    • 与其他无线服务(如WiFi)共用资源

    • 错误的时钟配置

  3. 资源不足

    • 内存池大小不足(检查CONFIG_BT_*_TX_COUNT等配置)

    • 中断冲突

2.3.6  实际应用示例

1) 简单外设初始化

void main(void) 
{bt_enable(NULL); // 同步初始化bt_le_adv_start(...); // 立即开始广播
}

2)带错误恢复的初始化

void bt_retry_init(int err)
{if (err) {k_sleep(K_SECONDS(1));bt_enable(bt_retry_init); // 重试初始化}
}void main(void) 
{bt_enable(bt_retry_init);
}

2.3.7 应用总结

bt_enable 是蓝牙开发的第一个关键调用,其核心价值在于:

  • 建立蓝牙操作的基础环境

  • 提供同步/异步两种初始化模式

  • 协调硬件和协议栈的启动

正确使用该API需要注意:

  1. 调用时机(早于其他蓝牙操作)

  2. 错误处理机制

  3. 特定协议栈的特殊要求

在复杂应用中,建议使用异步回调模式,以便在初始化完成后自动执行后续蓝牙操作流程。

2.4 bt_le_adv_update_data函数

2.4.1 函数功能

bt_le_adv_update_data 是蓝牙低功耗 (BLE) 协议栈中的一个关键 API 函数,用于动态更新正在进行的广播数据或扫描响应数据,而无需停止并重新启动广播。

核心功能

  • 动态更新广播数据:修改广播包(Advertising Data)或扫描响应包(Scan Response Data)内容

  • 无需重启广播:保持广播持续进行,避免广播中断导致的设备不可见期

  • 实时数据刷新:适用于需要频繁更新广播信息的场景(如传感器数据变化)

 函数原型(基于Zephyr等常见协议栈)

int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd,size_t sd_len);

参数说明

参数类型说明
adbt_data*新的广播数据数组
ad_lensize_t广播数据项数量
sdbt_data*新的扫描响应数据数组
sd_lensize_t扫描响应数据项数量

返回值

返回值说明
0数据更新成功
-EINVAL参数无效(如数据长度超限)
-ENOMEM内存不足
-EAGAIN协议栈繁忙,需重试
-ENOTCONN当前未进行广播

 2.4.2 典型使用场景

1) 传感器数据实时更新

// 初始广播
bt_le_adv_start(..., initial_ad, ...);// 当温度变化时更新数据
void update_temp_data(float new_temp) 
{uint8_t temp_encoded = (uint8_t)(new_temp * 2);struct bt_data new_ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL),BT_DATA(BT_DATA_MANUFACTURER_DATA, &temp_encoded, 1)};bt_le_adv_update_data(new_ad, ARRAY_SIZE(new_ad), NULL, 0);
}

2) 动态切换广播模式

// 从普通广播切换到信标模式
struct bt_data beacon_ad[] = 
{BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NONCONN_IND),BT_DATA(BT_DATA_MANUFACTURER_DATA, beacon_payload, sizeof(beacon_payload))
};bt_le_adv_update_data(beacon_ad, ARRAY_SIZE(beacon_ad), NULL, 0);

2.4.3 关键特性

原子性更新

1)数据更新在单个广播间隔内完 ;
 2)接收端不会看到部分更新的数据


广播连续

1)保持现有广播间隔不变;
2)避免传统"停止-修改-重启"方式导致的 ~300ms 广播中断


数据限制

1)仍需遵守31字节的广播数据长度限制; 
2)数据类型需符合蓝牙规范(不能动态修改AD Type)

 2.4.4 实现原理

2.4.5 注意事项

广播必须处于活跃状态


1)需在bt_le_adv_start之后调用

2)已连接的设备会自动停止广播

数据一致性


1)更新期间应避免修改原始数据缓冲区

2)建议使用静态或全局数据数组


性能考量


1)频繁更新(如每秒多次)可能影响射频稳定性

2)建议合并更新(如每200ms批量更新一次)

厂商限制


1)某些低端蓝牙芯片可能不支持实时更新

2)需要检查协议栈实现是否支持该功能

 2.4.6 错误处理最佳实践

int err = bt_le_adv_update_data(new_ad, ad_len, NULL, 0);
if (err == -ENOTCONN) 
{// 广播未激活,重新启动bt_le_adv_start(...);
} 
else if (err){printk("Update failed (err %d), retrying...\n", err);k_sleep(K_MSEC(100));// 重试逻辑}

2.4.7 典型应用案例

  1. 电子价签系统

    • 不建立连接,通过广播更新价格信息

    • 每15分钟更新一次广播数据

  2. 运动传感器

    • 实时广播心率/步数变化

    • 保持低功耗的同时更新数据

  3. 智能信标

    • 动态调整广播内容(如店铺促销信息)

    • 基于位置切换广播UUID

2.4.8 应用总结

bt_le_adv_update_data 提供了高效的广播数据动态更新机制,特别适合:

  • 需要保持持续广播可见性的场景

  • 实时数据传输但无需建立连接的用例

  • 低功耗设备的数据更新需求

正确使用该API可以避免传统重启广播方式带来的连接中断风险,同时保证数据更新的实时性和可靠性。开发者应注意目标平台的协议栈实现差异,并进行充分的错误场景测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/77745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8、HTTPD服务--ab压力测试

一、ab压力测试 # ab ‐c 100 ‐n 1000 http://vedio.linux.com/index.html 2 This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 4 Licensed to The Apache Software Foundation,…

E2E 测试

以下是关于端到端(E2E)测试的基本知识总结: 一、E2E 测试核心认知 1. 定义与价值定位 "模拟真实用户在完整应用环境中的操作流程"核心价值: 验证跨系统/模块的集成功能检测用户流程中的关键路径保障核心业务场景的可用性测试金字塔定位:单元测试(70%) → 集…

python之数字类型的操作

Python数据类型与操作符完全指南&#xff1a;详解各类数据操作技巧 目录 数字类型 字符串 列表 元组 字典 集合 布尔 通用操作符 注意事项 1. 数字类型&#xff08;int, float, complex&#xff09; 数字类型是Python中最基础的数据类型&#xff0c;支持多种数学运算…

基于Spring Boot+Vue 网上书城管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

从拒绝采样到强化学习,大语言模型推理极简新路径!

大语言模型&#xff08;LLMs&#xff09;的推理能力是当下研究热点&#xff0c;强化学习在其复杂推理任务微调中广泛应用。这篇论文深入剖析了相关算法&#xff0c;发现简单的拒绝采样基线方法表现惊人&#xff0c;还提出了新算法。快来一探究竟&#xff0c;看看这些发现如何颠…

测试——BUG篇

1. 软件测试的生命周期 软件测试贯穿于软件的整个生命周期&#xff0c;针对这句话我们⼀起来看⼀下软件测试是如何贯穿软件的整个生命周期。 软件测试的⽣命周期是指测试流程&#xff0c;这个流程是按照⼀定顺序执⾏的⼀系列特定的步骤&#xff0c;去保证产品质量符合需求。在…

【Hive入门】Hive函数:内置函数与UDF开发

Apache Hive作为Hadoop生态系统中的重要组件&#xff0c;为大数据分析提供了强大的SQL-like查询能力。Hive不仅支持丰富的内置函数&#xff0c;还允许用户开发自定义函数&#xff08;UDF&#xff09;以满足特定需求。本文将深入探讨Hive的内置函数&#xff08;包括数学函数、字…

关于汇编语言与程序设计——子程序设计

学习目标&#xff1a; 编程实现两个数&#xff1a;#8888H 和 #79H 的乘除运算。 一、实验要求 能够熟练掌握算术运算汇编指令的使用&#xff1b;熟练掌握子程序设计的基本方法&#xff1b;熟练掌握程序的调试方法。 二、实验设计 1.整体思路 乘法&#xff1a;将单字节的乘数…

AWS SQS 队列策略配置指南:常见错误与解决方案

在 AWS 云服务中,Simple Queue Service (SQS) 是一种完全托管的消息队列服务,广泛应用于分布式系统组件间的解耦。为了确保队列的安全访问,正确配置队列策略至关重要。本文将详细介绍 SQS 队列策略的配置方法,常见错误及其解决方案。 SQS 队列策略基础 SQS 队列策略是基于…

Webshell管理工具的流量特征

目录 一、常见Webshell工具流量特征 1. ​​中国菜刀&#xff08;Chopper&#xff09;​​ 2. ​​冰蝎&#xff08;Behinder&#xff09;​​ 3. ​​哥斯拉&#xff08;Godzilla&#xff09;​​ 4. ​​蚁剑&#xff08;AntSword&#xff09;​​ 5. ​​C99 Shell​​…

【每日八股】复习 MySQL Day3:锁

文章目录 昨日内容复习MySQL 使用 B 树作为索引的优势是什么&#xff1f;索引有哪几种&#xff1f;什么是最左匹配原则&#xff1f;索引区分度&#xff1f;联合索引如何排序&#xff1f;使用索引有哪些缺陷&#xff1f;什么时候需要建立索引&#xff0c;什么时候不需要&#xf…

Arkts完成数据请求http以及使用axios第三方库

import http from ohos.net.http Entry Component struct HttpPage {State message: string Hello Worldbuild() {Column({space:20}) {Row(){Button(发送http请求).onClick(()>{let httpRequest http.createHttp();httpRequest.request(https://zzgoodqc.cn/index.php/in…

SELinux 从理论到实践:深入解析与实战指南

文章目录 引言&#xff1a;为什么需要 SELinux&#xff1f;第一部分&#xff1a;SELinux 核心理论1.1 SELinux 的三大核心模型1.2 安全上下文&#xff08;Security Context&#xff09;1.3 策略语言与模块化 第二部分&#xff1a;实战操作指南2.1 SELinux 状态管理2.2 文件上下…

CD34.【C++ Dev】STL库的string的使用 (上)

目录 1.知识回顾 2.串联类和对象的知识重新理解 构造函数 string(); string (const string& str); string (const string& str, size_t pos, size_t len npos); string (const char* s); string (size_t n, char c); append和push_back string& append …

Git常用指令速查

Git常用指令速查 基本操作类&#xff1a; git init &#xff1a;初始化仓库git log&#xff1a;查看日志&#xff0c;这个命令很重要&#xff01;git add <文件名|.>&#xff1a;添加到暂存区git commit -m 注释&#xff1a;提交到仓库git merge <分支名>&#xf…

探索无人机模拟环境的多元景象及AI拓展

无人驾驶飞行器&#xff08;UAVs&#xff09;在各行各业的迅速普及&#xff0c;从农业和检测到空中操作和人机交互等令人兴奋的前沿领域&#xff0c;都引发了一个关键需求&#xff1a;强大而逼真的模拟环境。直接在物理硬件上测试尖端算法存在固有的风险——成本高昂的坠机、中…

AI Agent开源技术栈

构建和编排Agent的框架 如果您是从头开始构建&#xff0c;请从这里开始。这些工具可以帮助您构建Agent的逻辑——做什么、何时做以及如何处理工具。您可以将其视为将原始语言模型转化为更自主的模型的核心大脑。 2. 计算机和浏览器的使用 一旦你的Agent能够规划&#xff0c…

jspm老年体检信息管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 信息化时代&#xff0c;各行各业都以网络为基础飞速发展&#xff0c;而医疗服务行业的发展却进展缓慢&#xff0c;传统的医疗服务行业已经逐渐不满足民众的需求&#xff0c;有些还在以线下预约的方式接待病人&#xff0c;特别是针对于老年体检的服务&#xff0c;是少之又…

ESP32- 开发笔记- 软件开发 4 - GPIO 口

1 背景介绍 GPIO&#xff08;General Purpose Input/Output&#xff09; ——通用输入输出口&#xff0c;就是能由软件自由控制输入&#xff08;接收外界信号&#xff09;或输出&#xff08;发出电平信号&#xff09;的引脚。 ESP32 最核心的功能之一&#xff0c;能被用来控制…

格式工厂:多媒体转换工具

格式工厂&#xff08;FormatFactory&#xff09;是一款免费且功能全面的多媒体格式转换工具&#xff0c;支持视频、音频、图片及文档等多种格式的转换&#xff0c;覆盖超过70种语言&#xff0c;并兼容Windows XP至Win10/11系统。软件基于FFmpeg解码库开发&#xff0c;支持高效转…