HarmonyOS鸿蒙Next中Flutter无法使用avcastpicker组件

HarmonyOS鸿蒙Next中Flutter无法使用avcastpicker组件 开发中使用avcastpicker组件遇到问题,因UI框架为Flutter,无法方便地使用原生按钮,希望支持直接触发选项菜单的API或开放设置输出设备的能力。

5 回复

开发者您好,播控中心avsession kit提供以接口方式拉起投播面板功能,可以满足您的要求:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-avsession-avcastpickerhelper#select14

import { common } from '@kit.AbilityKit';
import { avSession } from '@kit.AVSessionKit';

class MyPage {
  private avCastPicker: avSession.AVCastPickerHelper;

  constructor(context: common.Context) {
    this.avCastPicker = new avSession.AVCastPickerHelper(context);
  }

  async selectCastDevice() {
    const avCastPickerOptions: avSession.AVCastPickerOptions = {
      sessionType: 'video',
    };

    this.avCastPicker.select(avCastPickerOptions).then(() => {
      console.info('Succeeded in selecting.');
    });
  }
}

需要注意,创建的AVCastPickerHelper对象,需要保持其生命周期在整个业务流程中存在,防止局部对象被提前回收造成的稳定性或功能问题。

更多关于HarmonyOS鸿蒙Next中Flutter无法使用avcastpicker组件的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


可以分两种情况看,结论其实比“只能用组件”要好一点:

结论

1. 如果你的目标是“拉起投播设备选择菜单”

现在不是只能用 AVCastPicker 组件了。

API 14 开始,官方提供了 AVCastPickerHelper,它可以直接拉起投播选择半模态面板

  • new avSession.AVCastPickerHelper(context)
  • select(options?)

也就是说,你可以不在 Flutter 页面里硬塞一个原生按钮组件,而是通过 Flutter -> Platform Channel -> ArkTS 原生方法,直接调用 AVCastPickerHelper.select() 来弹出设备选择面板。
参考官方接口文档:AVCastPickerHelper

这点正好对应你的诉求:
“希望支持直接触发选项菜单的 API”
现在官方已经有这个 API 了,但它是 ArkTS/原生侧能力,不是 Flutter 直接现成可用的 Widget。


2. 如果你的目标是“程序直接设置投播输出设备”

投播场景下,目前没有看到 AVSession 对外开放“直接指定某个远端投播设备并连接”的通用 API。

官方投播开发指导里,把 AVCastPicker 定义为:

  • 系统级设备切换、投播能力选择入口
  • 用户通过它完成设备发现、认证、连接
  • 连接成功后,应用再通过 AVCastController 控制远端播放
    参考:投播组件开发指导

也就是说在投播这条链路上,平台设计还是:

  • 系统统一设备选择入口
  • 开发者拿到连接结果和控制器
  • 而不是开发者自己静默选中并切到某个投播设备

你这个 Flutter 场景的可行方案

推荐方案:做一个 Harmony 原生插件桥接 AVCastPickerHelper

你可以这样实现:

  1. Flutter 页面点击你自己的 Dart 按钮
  2. 通过 MethodChannel 调到 Harmony 原生侧
  3. 原生侧用 UIAbilityContext 创建:
    • let helper = new avSession.AVCastPickerHelper(context)
  4. 调用:
    • await helper.select({ sessionType: 'audio' | 'video' })
  5. 再通过 AVSession.on('outputDeviceChange') 把连接状态回传 Flutter

这样你就能做到:

  • UI 完全是 Flutter 自己画
  • 设备选择菜单由系统原生弹出
  • 不依赖页面里直接摆 AVCastPicker 组件

你要注意的前置条件

即使用 AVCastPickerHelper.select(),也不是“单独调用就一定能弹出可用设备”,官方要求投播前仍然要先把 AVSession 基础能力接好:

  1. 创建并激活 AVSession
  2. session.setExtras({ requireAbilityList: ['url-cast'] })
  3. 设置 AVMetadata
  4. 按投播协议/资源类型配置 filter 等信息

如果这些没配好,哪怕你成功调用了 select(),也可能:

  • 面板空白
  • 没有设备
  • 或连接后没有后续控制能力

参考:投播组件开发指导


“设置输出设备能力”要区分两类

A. 投播到远端设备

这类还是建议走:

  • AVCastPicker / AVCastPickerHelper.select()

B. 本机音频路由切换

如果你说的是:

  • 扬声器
  • 听筒
  • 蓝牙耳机
  • 有线耳机

那从 API 20 开始,Audio Kit 的 AudioSessionManager 提供了:

  • setDefaultOutputDevice(...)

也就是本机默认音频输出设备可以由应用设置。
参考:查询和监听音频输出设备

但这个能力更偏:

  • 本机音频路由
  • 不等同于“投播远端设备选择”

所以如果你的诉求是“像音箱投播、智慧屏投播”,还是 AV Cast 体系;
如果只是“切扬声器/蓝牙耳机”,那可以看 AudioSessionManager。


对你问题的直接回答

“Flutter 无法方便使用原生按钮,希望支持直接触发选项菜单 API”

支持,API 14+ 可以用 AVCastPickerHelper.select()
你可以通过 Flutter 原生桥接调用。

“希望开放设置输出设备的能力”

  • 投播远端设备:目前公开能力仍以系统选择入口为主,没有看到通用“直接指定远端设备连接”的开放 API
  • 本机音频输出设备:API 20+ 可用 AudioSessionManager.setDefaultOutputDevice(...)

给你的实施建议

如果你现在项目是 Flutter,我建议优先这样做:

  1. 保持 Flutter 自定义 UI 按钮
  2. 在 Harmony 原生插件里封装一个方法:
    • showCastPicker(sessionType)
  3. 原生侧调用 AVCastPickerHelper.select()
  4. 再封装一个事件通道,把:
    • outputDeviceChange
    • picker 状态变化
    • cast 连接结果 回传给 Flutter

这样是当前最接近你诉求、也最符合官方设计的方案。

先说原因: AVCastPicker 是 ArkTS/ArkUI 组件(@kit.AVSessionKit),只能在鸿蒙原生页面(.ets)里声明式使用。

Flutter 是独立渲染树,不支持直接嵌入鸿蒙原生 UI 组件(不像 AndroidView/UIView 那样简单),而且鸿蒙目前没有官方 Flutter 插件封装 AVCastPicker。

它本质是「系统弹窗 + 设备选择 + 连接认证」一体化控件,不是一个单纯可被外部触发的 API,必须由原生组件实例触发。所以在 Flutter 里,你拿不到、也放不了 AVCastPicker 按钮,自然无法直接点它弹出设备列表。

然后是解决方案,你参考下:

  1. 在 Flutter 里放一个自定义按钮(IconButton/Image)。
  2. 点击后通过鸿蒙 Flutter 插件通道调用原生 ArkTS 代码。
  3. 原生代码里:
    • 调用 avSession.getOutputDevices() 获取设备列表。或直接调用 picker.select() 弹出系统选择框。
    • 结果回调给 Flutter 显示 / 处理。

原生侧关键代码(ArkTS):

import { avSession } from '[@kit](/user/kit).AVSessionKit';
import { AVCastPicker } from '[@kit](/user/kit).AVSessionKit';

// 1. 创建会话(必须,否则无设备)
let session = await avSession.createAVSession(context, 'my_cast', 'video');

// 2. 直接弹出系统设备选择框(不用原生按钮)
let picker = new AVCastPicker();
picker.select(); // ✅ 这就是你要的“直接触发选项菜单”

// 3. 或直接获取设备列表,自己在 Flutter 画弹窗
let devices = await session.getOutputDevices();

在HarmonyOS Next中,Flutter的avcastpicker组件无法使用,因为该组件依赖Android/iOS原生音视频播控API(如MediaRouter、AVRoutePickerView),而鸿蒙Next的分布式软总线与媒体框架接口(如AVCastPicker控件)与Android/iOS不兼容。当前Flutter-OpenHarmony社区尚未实现对应OHOS原生插件,故不可用。

HarmonyOS NEXT 的 Flutter 框架暂未提供直接调用 AVCastPicker 选项菜单的 Dart API,但可通过 Platform Channel 让 Flutter 与原生 ArkUI 通信。在原生侧基于 @ohos.multimedia.avCastPicker 封装一个方法,例如 showDevicePicker,由 Flutter 通过 MethodChannel 调用该原生方法,原生侧启动选择器并回调选中的设备 ID。这样即可在 Flutter UI 中自由触发投播设备列表,无需依赖原生按钮。当前官方未内置此功能,需自行封装插件解决。

回到顶部