Flutter多媒体通信插件millicast_flutter_sdk的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter多媒体通信插件millicast_flutter_sdk的使用

安装

要将Millicast Flutter SDK添加到您的依赖项中,请运行以下命令:

flutter pub add millicast_flutter_sdk

然后运行以下命令以下载依赖项:

flutter pub get

这样,您就可以在项目中使用SDK的所有功能了。

iOS 和 MacOS

在您的Info.plist文件中添加以下条目(位于<project root>/ios/Runner/Info.plist<project root>/macos/Runner/Info.plist):

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

这些条目允许您的应用程序访问摄像头和麦克风。

MacOS

为了在您的macOS应用程序中添加特定的功能或服务(如访问互联网、从集成的摄像头和麦克风设备捕获媒体),您必须设置特定的权限到您的DebugProfile.entitlements(用于调试和配置构建)和Runner.entitlements(用于发布构建)文件。

<project root>/macos/Runner/DebugProfile.entitlements<project root>/macos/Runner/Release.entitlements文件中添加以下条目:

<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.network.client</key>

此外,确保您的应用程序可以访问摄像头和麦克风。转到Apple菜单 > 系统偏好设置 > 隐私与安全性 > 隐私。解锁左下角的锁形图标以允许您更改首选项。然后,对于摄像头和麦克风,选择相应的图标,并启用开关以允许您的应用程序访问设备。

Android

确保在您的Android清单文件中(位于<project root>/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" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Flutter项目模板可能已经添加了这些权限。

您还需要将构建设置更改为Java 8,因为官方WebRTC jar现在使用静态方法在EglBase接口中。只需在您的app级别的build.gradle文件中添加以下内容:

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

如果需要,在同一个build.gradle文件中,您需要将defaultConfig中的minSdkVersion增加到23(目前默认Flutter生成器将其设置为16)。

基本使用

这是一个简单的最小化版本的项目,以展示发布或订阅的功能。您需要将以下三个代码片段分别放在相应的main.dartpublisher.dartviewer.dart文件中,并根据需要设置您的Millicast流媒体凭证以进行测试。

主应用

import 'publisher.dart';
import 'viewer.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter/material.dart';

const type = String.fromEnvironment('type');
void main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // 这个小部件是你的应用的根。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Millicast SDK Demo',
      theme: ThemeData(
        primarySwatch: Colors.purple,
      ),
      home: const MyHomePage(title: 'Millicast SDK Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final RTCVideoRenderer _localRenderer = RTCVideoRenderer();

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

  @override
  void initState() {
    initRenderers();
    // 运行应用程序时通过--dart-define type标志来选择是否发布或订阅:
    // flutter run --dart-define=type="subscribe||publish"
    switch (type) {
      case 'subscribe':
        subscribeExample();
        break;
      case 'publish':
        publishExample();
        break;
      default:
        publishExample();
    }
    super.initState();
  }

  void publishExample() async {
    await publishConnect(_localRenderer);
    setState(() {});
  }

  void subscribeExample() async {
    await viewConnect(_localRenderer);
    setState(() {});
  }

  void initRenderers() async {
    await _localRenderer.initialize();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: OrientationBuilder(
        builder: (context, orientation) {
          return RotatedBox(
              quarterTurns: 1,
              child: Center(
                child: Container(
                  margin: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
                  width: MediaQuery.of(context).size.width,
                  height: MediaQuery.of(context).size.height,
                  child: RTCVideoView(_localRenderer, mirror: true),
                  decoration: const BoxDecoration(color: Colors.black54),
                ),
              ));
        },
      ),
    );
  }
}

发布者应用

import 'dart:io';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:millicast_flutter_sdk/millicast_flutter_sdk.dart';

Future publishConnect(RTCVideoRenderer localRenderer) async {
  // 设置发布者选项
  DirectorPublisherOptions directorPublisherOptions = DirectorPublisherOptions(
      token: 'my-publishing-token', streamName: 'my-stream-name');

  /// 定义生成新令牌的回调函数
  tokenGenerator() => Director.getPublisher(directorPublisherOptions);

  /// 创建一个新的实例
  Publish publish =
      Publish(streamName: 'my-streamname', tokenGenerator: tokenGenerator);

  final Map<String, dynamic> constraints = {'audio': true, 'video': true};

  MediaStream stream = await navigator.mediaDevices.getUserMedia(constraints);
  localRenderer.srcObject = stream;

  // 发布选项
  Map<String, dynamic> broadcastOptions = {'mediaStream': stream};
  // 某些Android设备不支持h264编解码器
  if (Platform.isAndroid) {
    broadcastOptions['codec'] = 'vp8';
  }

  /// 开始连接到发布者
  try {
    await publish.connect(options: broadcastOptions);
    return publish.webRTCPeer;
  } catch (e) {
    throw Exception(e);
  }
}

观众应用

import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:millicast_flutter_sdk/millicast_flutter_sdk.dart';

Future viewConnect(RTCVideoRenderer localRenderer) async {
  // 设置订阅者选项
  DirectorSubscriberOptions directorSubscriberOptions =
      DirectorSubscriberOptions(
          streamAccountId: 'my-account-id', streamName: 'my-stream-name');

  /// 定义生成新令牌的回调函数
  tokenGenerator() => Director.getSubscriber(directorSubscriberOptions);

  /// 创建一个新的实例
  View view = View(
      streamName: 'my-stream-name',
      tokenGenerator: tokenGenerator,
      mediaElement: localRenderer);

  /// 开始连接到发布者
  try {
    await view.connect();
    return view.webRTCPeer;
  } catch (e) {
    rethrow;
  }
}

运行应用程序

设置type环境变量为publishsubscribe来决定您想要运行发布者还是观众应用。

flutter run --dart-define=type='publish'

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

1 回复

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


当然,以下是一个关于如何使用 millicast_flutter_sdk 进行多媒体通信的示例代码。请注意,由于 millicast_flutter_sdk 是一个第三方库,具体的API和实现可能会随着库的更新而变化。因此,以下代码基于假设的API设计,你需要参考最新的官方文档来确保代码的正确性。

首先,确保你已经在 pubspec.yaml 文件中添加了 millicast_flutter_sdk 依赖:

dependencies:
  flutter:
    sdk: flutter
  millicast_flutter_sdk: ^最新版本号

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

接下来,你可以按照以下步骤在 Flutter 应用中使用 millicast_flutter_sdk 进行多媒体通信:

1. 初始化 SDK

在你的 Flutter 应用的主入口文件(通常是 main.dart)中初始化 SDK。

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化 SDK
  await Millicast.initialize('你的API_KEY');
  
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Multimedia Communication',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

2. 实现多媒体通信功能

接下来,在你的 HomeScreen 或其他页面中实现具体的多媒体通信功能,比如加入房间、发送视频/音频流等。

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

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  MillicastRoom? _room;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Millicast Flutter SDK Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextButton(
              onPressed: () async {
                // 加入房间
                _room = await Millicast.joinRoom('房间名或房间ID');
                
                // 设置本地视频/音频流(假设 SDK 提供了这样的方法)
                // _room!.setLocalStream(yourLocalMediaStream);
                
                // 监听远端视频/音频流(假设 SDK 提供了事件监听)
                _room!.onRemoteStreamReceived.listen((MediaStream stream) {
                  // 处理远端流,比如显示在 UI 上
                });
              },
              child: Text('加入房间'),
            ),
            SizedBox(height: 20),
            TextButton(
              onPressed: () async {
                if (_room != null) {
                  // 离开房间
                  await _room!.leave();
                  _room = null;
                }
              },
              child: Text('离开房间'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 清理资源,比如离开房间(如果尚未离开)
    if (_room != null) {
      _room!.leave();
    }
    super.dispose();
  }
}

注意事项

  1. API Key:确保你已经从 millicast 服务平台获取了有效的 API Key,并将其替换到初始化 SDK 的代码中。
  2. 权限:多媒体通信通常需要访问设备的摄像头和麦克风,因此你需要在 AndroidManifest.xmlInfo.plist 中添加相应的权限声明。
  3. 错误处理:在实际应用中,你需要添加错误处理逻辑来处理可能出现的异常情况,比如网络错误、设备权限被拒绝等。
  4. UI 更新:在接收到远端流时,你可能需要更新 UI 来显示视频/音频内容。这通常涉及到使用 VideoPlayer 或类似的 Flutter 插件来播放视频流。

由于 millicast_flutter_sdk 的具体 API 和实现细节可能有所不同,以上代码仅供参考。在实际开发中,请务必参考最新的官方文档和示例代码。

回到顶部