Flutter WebRTC通信插件flutter_webrtc_vconnex的使用

简介

LiveKit
LiveKit - Open source WebRTC基础设施

flutter_webrtc_vconnex 是一个用于 Flutter 的 WebRTC 插件,支持在移动设备、桌面和 Web 平台上进行音频、视频和数据通道通信。它旨在为开发者提供一个简单而强大的方式来构建实时通信应用。


功能支持

以下表格展示了 flutter_webrtc_vconnex 在不同平台上的功能支持情况:

特性 Android iOS Web macOS Windows Linux Embedded Fuchsia
音频/视频传输 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ [WIP]
数据通道 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ [WIP]
屏幕共享 ✔️ ✔️(*) ✔️ ✔️ ✔️ ✔️ [WIP]
Unified-Plan ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ [WIP]
Simulcast ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ [WIP]
MediaRecorder ⚠️ ⚠️ ✔️
Insertable Streams

使用方法

1. 添加依赖

在你的 pubspec.yaml 文件中添加 flutter_webrtc_vconnex 作为依赖:

dependencies:
  flutter_webrtc_vconnex: ^版本号

然后运行以下命令安装依赖:

flutter pub get

2. iOS 配置

ios/Runner/Info.plist 文件中添加以下权限声明:

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) Camera Usage!</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) Microphone Usage!</string>

对于 iOS M1 芯片设备,需要在 ios/Podfile 中添加以下配置:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      # Workaround for https://github.com/flutter/flutter/issues/64502
      config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES'
    end
  end
end

3. Android 配置

确保在 android/app/src/main/AndroidManifest.xml 文件中添加以下权限:

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

<!-- 如果需要蓝牙支持 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

同时,在 android/app/build.gradle 中设置 Java 编译版本为 1.8:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

如果需要更高的兼容性,可以将 minSdkVersion 提升到 23。


4. 示例代码

以下是一个完整的示例代码,展示如何使用 flutter_webrtc_vconnex 实现点对点通信。

文件结构

example/
├── lib/
   ├── main.dart
   ├── src/
      ├── get_user_media_sample.dart
      ├── get_display_media_sample.dart
      ├── loopback_sample.dart
      ├── loopback_sample_unified_tracks.dart
      └── route_item.dart

main.dart

import 'dart:core';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc_vconnex/flutter_webrtc_vconnex.dart';

import 'src/get_user_media_sample.dart';
import 'src/get_display_media_sample.dart';
import 'src/loopback_sample.dart';
import 'src/loopback_sample_unified_tracks.dart';
import 'src/route_item.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  if (WebRTC.platformIsDesktop) {
    debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
  }
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late List<RouteItem> items;

  [@override](/user/override)
  void initState() {
    super.initState();
    _initItems();
  }

  ListBody _buildRow(BuildContext context, RouteItem item) {
    return ListBody(children: [
      ListTile(
        title: Text(item.title),
        onTap: () => item.push(context),
        trailing: Icon(Icons.arrow_right),
      ),
      Divider(),
    ]);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter-WebRTC 示例'),
        ),
        body: ListView.builder(
          shrinkWrap: true,
          padding: const EdgeInsets.all(0.0),
          itemCount: items.length,
          itemBuilder: (context, index) {
            return _buildRow(context, items[index]);
          },
        ),
      ),
    );
  }

  void _initItems() {
    items = [
      RouteItem(
        title: '获取用户媒体 (GetUserMedia)',
        push: (BuildContext context) {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) => GetUserMediaSample()),
          );
        },
      ),
      RouteItem(
        title: '屏幕共享 (GetDisplayMedia)',
        push: (BuildContext context) {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) => GetDisplayMediaSample()),
          );
        },
      ),
      RouteItem(
        title: '回环测试 (LoopBack Sample)',
        push: (BuildContext context) {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) => LoopBackSample()),
          );
        },
      ),
      RouteItem(
        title: '统一轨道回环测试 (LoopBack Sample Unified Tracks)',
        push: (BuildContext context) {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) => LoopBackSampleUnifiedTracks()),
          );
        },
      ),
    ];
  }
}

route_item.dart

class RouteItem {
  final String title;
  final Function(BuildContext) push;

  RouteItem({required this.title, required this.push});
}

get_user_media_sample.dart

import 'package:flutter/material.dart';
import 'package:flutter_webrtc_vconnex/flutter_webrtc_vconnex.dart';

class GetUserMediaSample extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('获取用户媒体 (GetUserMedia)'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            var stream = await navigator.mediaDevices.getUserMedia({
              "video": true,
              "audio": true,
            });
            print("已获取媒体流: $stream");
          },
          child: Text('开始获取媒体流'),
        ),
      ),
    );
  }
}
1 回复

更多关于Flutter WebRTC通信插件flutter_webrtc_vconnex的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_webrtc_vconnex 是一个基于 flutter_webrtc 的 Flutter 插件,用于在 Flutter 应用中实现 WebRTC 通信。它提供了对 WebRTC 功能的封装,使得开发者可以更容易地在 Flutter 应用中实现音视频通话、数据传输等功能。

以下是如何使用 flutter_webrtc_vconnex 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 flutter_webrtc_vconnex 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_webrtc_vconnex: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 初始化插件

在你的 Dart 代码中,首先需要初始化 flutter_webrtc_vconnex 插件。

import 'package:flutter_webrtc_vconnex/flutter_webrtc_vconnex.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await FlutterWebRTCVconnex.initialize();
  runApp(MyApp());
}

3. 创建 WebRTC 连接

接下来,你可以使用 flutter_webrtc_vconnex 提供的 API 来创建和管理 WebRTC 连接。

import 'package:flutter_webrtc_vconnex/flutter_webrtc_vconnex.dart';

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  RTCVideoRenderer _localRenderer = RTCVideoRenderer();
  RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
  WebRTCVconnex _webrtc = WebRTCVconnex();

  @override
  void initState() {
    super.initState();
    _initRenderers();
    _initWebRTC();
  }

  void _initRenderers() async {
    await _localRenderer.initialize();
    await _remoteRenderer.initialize();
  }

  void _initWebRTC() async {
    await _webrtc.initialize();
    _webrtc.onLocalStream = (stream) {
      _localRenderer.srcObject = stream;
    };
    _webrtc.onRemoteStream = (stream) {
      _remoteRenderer.srcObject = stream;
    };
  }

  void _startCall() async {
    await _webrtc.createOffer();
  }

  void _answerCall() async {
    await _webrtc.createAnswer();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('WebRTC Demo'),
        ),
        body: Column(
          children: [
            Expanded(
              child: RTCVideoView(_localRenderer),
            ),
            Expanded(
              child: RTCVideoView(_remoteRenderer),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                  onPressed: _startCall,
                  child: Text('Start Call'),
                ),
                ElevatedButton(
                  onPressed: _answerCall,
                  child: Text('Answer Call'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _localRenderer.dispose();
    _remoteRenderer.dispose();
    _webrtc.dispose();
    super.dispose();
  }
}

4. 处理信令

WebRTC 需要信令服务器来交换 SDP 和 ICE 候选者。你可以使用任何信令服务器(如 Socket.IO、WebSocket 等)来实现这一点。在 flutter_webrtc_vconnex 中,你可以通过 _webrtc.createOffer()_webrtc.createAnswer() 来生成 SDP,并通过信令服务器发送给对方。

5. 处理 ICE 候选者

WebRTC 需要交换 ICE 候选者以建立连接。你可以通过 _webrtc.onIceCandidate 回调来获取本地的 ICE 候选者,并通过信令服务器发送给对方。

_webrtc.onIceCandidate = (candidate) {
  // 通过信令服务器发送 candidate 给对方
};

6. 处理远程 SDP 和 ICE 候选者

当你收到对方的 SDP 或 ICE 候选者时,你需要将其传递给 flutter_webrtc_vconnex

void _handleRemoteSdp(String sdp) async {
  await _webrtc.setRemoteDescription(sdp);
}

void _handleRemoteIceCandidate(RTCIceCandidate candidate) async {
  await _webrtc.addIceCandidate(candidate);
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!