1. 插件介绍

fluttertpc_flutter_webrtc 是一个专为开源鸿蒙(HarmonyOS)平台适配的 Flutter WebRTC 插件,基于官方的 flutter_webrtc 项目进行定制修改,提供了完整的 WebRTC 功能支持,包括实时音视频通信、设备管理、屏幕共享等核心能力。

主要功能特性

  • 设备管理:支持枚举、选择音频/视频输入输出设备
  • 媒体流处理:获取摄像头、麦克风媒体流,支持自定义分辨率和帧率
  • 对等连接:实现完整的 WebRTC 信令流程和媒体协商
  • 屏幕共享:支持获取屏幕共享媒体流
  • 数据通道:支持点对点数据传输

2. 插件安装与配置

2.1 Git 依赖引入

由于这是一个专为鸿蒙平台定制的修改版本,需要通过 Git 方式引入依赖。在 Flutter 项目的 pubspec.yaml 文件中添加以下配置:

dependencies:
  flutter_webrtc:
    git:
      url: https://gitcode.com/openharmony-sig/fluttertpc_flutter_webrtc

然后执行以下命令获取依赖:

flutter pub get

2.2 鸿蒙平台权限配置

在鸿蒙应用中使用 WebRTC 功能需要配置以下权限:

2.2.1 配置旋转权限

打开 entry/src/main/module.json5 文件,为 EntryAbility 添加自动旋转配置:

"abilities": [
  {
    "name": "EntryAbility",
    "srcEntry": "./ets/entryability/EntryAbility.ets",
    "description": "$string:EntryAbility_desc",
    "icon": "$media:icon",
    "label": "$string:EntryAbility_label",
    "startWindowIcon": "$media:startIcon",
    "startWindowBackground": "$color:start_window_background",
    "exported": true,
    "skills": [
      // ...
    ],
    "orientation": "auto_rotation", // 添加自动旋转支持
  }
]
2.2.2 配置应用权限

entry/src/main/module.json5 文件中添加以下权限配置:

"requestPermissions": [
  {
    "name" : "ohos.permission.INTERNET",
    "reason": "$string:internet"
  },
  {
    "name" : "ohos.permission.CAMERA",
    "reason": "$string:camera"
  },
  {
    "name": "ohos.permission.MICROPHONE",
    "reason": "$string:microphone"
  }
]
2.2.3 配置权限描述

打开 entry/src/main/resources/base/element/string.json 文件,添加权限描述:

{
  "string": [
    {
      "name": "internet",
      "value": "需要网络权限以进行实时通信"
    },
    {
      "name": "camera",
      "value": "需要相机权限以捕获视频"
    },
    {
      "name": "microphone",
      "value": "需要麦克风权限以捕获音频"
    },
  ]
}

3. API 使用示例

3.1 设备枚举

import 'package:flutter_webrtc/flutter_webrtc.dart';

// 枚举所有媒体设备
Future<void> enumerateDevices() async {
  List<MediaDeviceInfo> devices = await navigator.mediaDevices.enumerateDevices();

  // 分类设备
  List<MediaDeviceInfo> audioInputs = devices.where((device) => device.kind == 'audioinput').toList();
  List<MediaDeviceInfo> audioOutputs = devices.where((device) => device.kind == 'audiooutput').toList();
  List<MediaDeviceInfo> videoInputs = devices.where((device) => device.kind == 'videoinput').toList();

  // 打印设备信息
  print('音频输入设备: ${audioInputs.map((d) => d.label).toList()}');
  print('音频输出设备: ${audioOutputs.map((d) => d.label).toList()}');
  print('视频输入设备: ${videoInputs.map((d) => d.label).toList()}');
}

3.2 获取媒体流

// 初始化视频渲染器
final RTCVideoRenderer _localRenderer = RTCVideoRenderer();
await _localRenderer.initialize();

// 获取摄像头和麦克风媒体流
Future<void> getUserMedia() async {
  try {
    MediaStream stream = await navigator.mediaDevices.getUserMedia({
      'audio': true,
      'video': {
        'width': 1280,
        'height': 720,
        'frameRate': 30,
      },
    });

    // 设置渲染器源
    _localRenderer.srcObject = stream;

    // 获取轨道信息
    List<MediaStreamTrack> tracks = stream.getTracks();
    print('获取到的媒体轨道: ${tracks.map((t) => t.kind).toList()}');
  } catch (e) {
    print('获取媒体流失败: $e');
  }
}

3.3 配置对等连接

// 创建对等连接
RTCPeerConnection? _peerConnection;

Future<void> initPeerConnection() async {
  try {
    _peerConnection = await createPeerConnection({});

    // 监听 ICE 候选
    _peerConnection!.onIceCandidate = (RTCIceCandidate candidate) {
      // 发送 ICE 候选到远程端
      print('ICE 候选: $candidate');
    };

    // 监听连接状态
    _peerConnection!.onConnectionState = (RTCPeerConnectionState state) {
      print('连接状态: $state');
    };

    // 监听远程流
    _peerConnection!.onTrack = (MediaStreamTrackEvent event) {
      if (event.track.kind == 'video') {
        // 设置远程视频渲染器源
        _remoteRenderer.srcObject = event.streams[0];
      }
    };
  } catch (e) {
    print('初始化对等连接失败: $e');
  }
}

3.4 媒体协商流程

// 创建 Offer
Future<void> createOffer() async {
  if (_peerConnection == null) return;

  try {
    RTCSessionDescription offer = await _peerConnection!.createOffer();
    await _peerConnection!.setLocalDescription(offer);

    // 发送 Offer 到远程端
    print('创建 Offer: $offer');
  } catch (e) {
    print('创建 Offer 失败: $e');
  }
}

// 处理 Answer
Future<void> handleAnswer(RTCSessionDescription answer) async {
  if (_peerConnection == null) return;

  try {
    await _peerConnection!.setRemoteDescription(answer);
    print('设置远程 Answer 成功');
  } catch (e) {
    print('设置远程 Answer 失败: $e');
  }
}

// 添加 ICE 候选
Future<void> addIceCandidate(RTCIceCandidate candidate) async {
  if (_peerConnection == null) return;

  try {
    await _peerConnection!.addCandidate(candidate);
    print('添加 ICE 候选成功');
  } catch (e) {
    print('添加 ICE 候选失败: $e');
  }
}

3.5 切换音频/视频设备

// 切换音频输入设备
Future<void> switchAudioInput(String deviceId) async {
  if (_localStream == null) return;

  try {
    // 获取新的音频流
    MediaStream newStream = await navigator.mediaDevices.getUserMedia({
      'audio': {
        'optional': [{'sourceId': deviceId}],
      },
      'video': false,
    });

    // 替换音频轨道
    MediaStreamTrack newTrack = newStream.getAudioTracks().first;
    RTCRtpSender? sender = _senders.firstWhereOrNull((s) => s.track?.kind == 'audio');
    if (sender != null) {
      await sender.replaceTrack(newTrack);
    }

    print('切换音频输入设备成功');
  } catch (e) {
    print('切换音频输入设备失败: $e');
  }
}

4. 完整示例应用

插件提供了完整的示例应用,展示了各个功能模块的使用方法。主要示例模块包括:

  • 设备枚举示例:演示如何枚举和选择媒体设备
  • 媒体流获取示例:演示如何获取和显示音视频流
  • 屏幕共享示例:演示如何获取屏幕共享流
  • 数据通道示例:演示如何使用 WebRTC 数据通道

运行示例应用

cd example
flutter run

5. 注意事项与兼容性

5.1 兼容性要求

  • Flutter SDK: 3.7.12-ohos-1.0.6 或更高版本
  • 鸿蒙 SDK: 5.0.0(12) 或更高版本
  • DevEco Studio: 5.0.13.200 或更高版本
  • 鸿蒙 ROM: 5.1.0.120 SP3 或更高版本

5.2 功能限制

目前鸿蒙平台不支持以下功能:

  • 媒体录制功能
  • 部分高级音视频处理特性

6. 总结

fluttertpc_flutter_webrtc 插件为鸿蒙平台提供了完整的 WebRTC 能力支持,使开发者能够轻松构建实时音视频通信应用。通过本文的介绍,您已经了解了该插件的安装配置、核心 API 使用以及最佳实践。

该插件遵循标准的 WebRTC API 设计,与其他平台的使用方式保持一致,降低了跨平台开发的学习成本。同时,它针对鸿蒙平台进行了专门优化,确保在鸿蒙设备上获得最佳的性能和兼容性。

加入社区

欢迎加入开源鸿蒙跨平台社区,与更多开发者交流学习:

开源鸿蒙跨平台社区

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐