You need to enable JavaScript to run this app.
导航

Flutter 平台高级功能使用说明

最近更新时间2023.12.06 17:08:30

首次发布时间2023.12.06 17:08:30

当你使用 RTC 实现实时音视频通信时,采集、编解码、前后处理、渲染等通信链路各环节中的音视频数据默认使用 RTC SDK 内部的对应模块进行处理。若你在应用中已自行实现了部分音视频处理逻辑,也可以对数据进行自定义处理,并交由 RTC 进行传输。

在使用 Flutter 跨平台框架进行应用开发时,受平台性能限制,自定义音视频处理相关功能未在 Flutter 层提供接口。但 RTC Flutter SDK 提供从 Native 层获取原生 RTC 引擎实例的能力,你可以将相关功能放在 Native 层实现,再通过自定义 MethodChannel 进行调用。

详情参看撰写双端平台代码(插件编写实现),了解 Flutter 应用如何借助原生平台能力实现所需功能。

本文以自定义音频处理功能为例,详细介绍原生平台接口的调用方法。

API 调用时序图

alt

注意:

  1. 调用 Native 端相关接口前,请先从 Flutter 端创建好 RTCVideo 实例。

  2. 请勿在 Native 端调用 destroy接口,否则会引起功能异常。

方法实现

Native 层

iOS 端

  1. 自定义 MethodChannel,并调用需要使用的 Native 接口

    #import <Flutter/FlutterPlugin.h>
    #import <volc_engine_rtc/ByteRTCVideoManager.h>
    #import <VolcEngineRTC/VolcEngineRTC.h>
    
    @interface RTCEngineFlutterPlugin : NSObject <FlutterPlugin>
    
    @end
    
    @implementation RTCEngineFlutterPlugin
    
    // FlutterPlugin
    
    + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
        RTCEngineFlutterPlugin *instance = [[RTCEngineFlutterPlugin alloc] init];
        // “MethodChannelName” 字段可自行定义,但注意需与 Flutter 侧保持一致
        FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"MethodChannelName"
                                                                          binaryMessenger:registrar.messenger];
        [registrar addMethodCallDelegate:instance channel:methodChannel];
    }
    
    - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
        // 转发消息
        // method 字段可自行定义,但注意需与 Flutter 侧保持一致。建议直接使用 Native 接口名,此处以 registerAudioProcessor 为例
        if ([call.method isEqualToString:@"registerAudioProcessor"]) {
            [self registerAudioProcessor:call.arguments result:result];
            return;
        }
        result(FlutterMethodNotImplemented);
    }
    
    // custom method
    
    - (void)registerAudioProcessor:(NSDictionary *)arguments result:(FlutterResult)result {
        // 获取 ByteRTCVideo 实例
        ByteRTCVideo *rtcVideo = [ByteRTCVideoManager getVideo];
        if (rtcVideo == nil) {
            result(@(-1));
            return;
        }
        // 注册自定义音频处理器
        int res = [rtcVideo registerAudioProcessor:processor];
        result(@(res));
    }
    
    @end
    
  2. 将自定义 MethodChannel 注册进 Flutter 引擎

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [GeneratedPluginRegistrant registerWithRegistry:self];
        // Override point for customization after application launch.
        [RTCEngineFlutterPlugin registerWithRegistrar:[self registrarForPlugin:@"RTCEngineFlutterPlugin"]];
        return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    

Android 端

  1. 在 Android 项目工程中的 build.gradle 文件中添加依赖

    dependencies {
        // 版本号请与 Flutter SDK 中依赖的 Android SDK 版本号保持一致
        // 从 SDK 根目录/android/build.gradle 文件中查看
        implementation 'com.volcengine:VolcEngineRTC:X.X.X'
    }
    
  2. 自定义MethodChannel,并调用需要使用的 Native 接口

    import androidx.annotation.NonNull;
    
    import com.ss.bytertc.engine.RTCVideo;
    import com.ss.bytertc.engine.flutter.base.RTCVideoManager;
    
    import java.util.Objects;
    
    import io.flutter.embedding.engine.plugins.FlutterPlugin;
    import io.flutter.plugin.common.BinaryMessenger;
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugin.common.StandardMethodCodec;
    
    public class RTCEngineFlutterPlugin implements FlutterPlugin, MethodChannel.MethodCallHandler {
    
        private MethodChannel channel;
    
        @Override
        public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
            BinaryMessenger binaryMessenger = binding.getBinaryMessenger();
            // “MethodChannelName” 字段可自行定义,但注意需与 Flutter 侧保持一致
            channel = new MethodChannel(binaryMessenger, "MethodChannelName", StandardMethodCodec.INSTANCE);
            channel.setMethodCallHandler(this);
        }
    
        @Override
        public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
            channel.setMethodCallHandler(null);
        }
    
        @Override
        public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
            // 转发消息
            // method 字段可自行定义,但注意需与 Flutter 侧保持一致。建议直接使用 Native 接口名,此处以 registerAudioProcessor 为例
            if (Objects.equals(call.method, "registerAudioProcessor")) {
                registerAudioProcessor(call, result);
                return;
            }
            result.notImplemented();
        }
    
        void registerAudioProcessor(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
            RTCVideo rtcVideo = null;
            try {
                // 获取 RTCVideo 实例
                rtcVideo = RTCVideoManager.getRTCVideo();
            } catch (Exception e) {
                result.success(-1);
                return;
            }
            // 注册自定义音频处理器
            int res = rtcVideo.registerAudioProcessor(processor);
            result.success(res);
        }
    }
    
  3. 将自定义 MethodChannel 注册进 Flutter 引擎

    public class MainActivity extends FlutterActivity {
    
        @Override
        public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
            super.configureFlutterEngine(flutterEngine);
            flutterEngine.getPlugins().add(new RTCEngineFlutterPlugin());
        }
    }
    

Flutter 层

实现自定义 MethodChannel

class RTCEngineExtension {
  // “MethodChannelName” 字段可自行定义,但注意需与 Native 侧保持一致
  static const MethodChannel _staticChannel = MethodChannel('MethodChannelName');

  static Future<int?> registerAudioProcessor() {
    // method 字段可自行定义,但注意需与 Native 侧保持一致。建议直接使用 Native 接口名,此处以 registerAudioProcessor 为例
    return _staticChannel.invokeMethod<int>("registerAudioProcessor");
  }
}
更多教程

参考本文完成接口调用后,继续参看自定义音频处理完成功能实现。
你也可以结合本文完成更多 RTC 高级功能的实现。