前言:
Flutter的插件分為兩種:Package和Plugin候齿。
Package是純Dart的尉桩,主要用在組件展示。類似:日歷舌涨、下拉刷新等。
Plugin是通過Flutter的channel調(diào)用原生扔字,原生來實現(xiàn)功能囊嘉;主要用在功能性上。類似:拍照革为、錄音等扭粱。
rtmp推流為功能型的,所以此文講的推流插件是Plugin類型震檩。
環(huán)境:
Mac琢蛤、AS、Xcode抛虏、Flutter1.12
項目地址:flutter_rtmp_plugin
1虐块、創(chuàng)建Plugin工程
1、AS中new flutter project 選擇plugin選項嘉蕾,按提示語一路next贺奠,此處不再贅述。
2错忱、創(chuàng)建完畢儡率,打開工程目錄如下,主要修改lib以清、ios儿普、android三個目錄。
2掷倔、Flutter端代碼書寫
class FlutterRtmpPlugin {
//1眉孩、創(chuàng)建channel
static const MethodChannel _channel =
const MethodChannel('flutter_rtmp_plugin');
//2、開始直播的api勒葱,參數(shù)為推流地址
static startLive(String url) async {
await _channel.invokeMethod('startLive', {"url" : url});
}
}
在外部的使用方法:
var url = "rtmp://192.168.101.240/rtmplive/test";
FlutterRtmpPlugin.startLive(url);
3浪汪、 iOS端代碼書寫
1、ios目錄如下
2凛虽、ios端的推流使用的是LFLiveKit
死遭,首先打開ios目錄下后綴為.podspec的文件。
添加依賴
s.dependency 'LFLiveKit'
3凯旋、FlutterRtmpPlugin.m文件
實現(xiàn)邏輯是:ios接收到名為‘ flutter_rtmp_plugin’的channel呀潭,回調(diào)‘ startLive’這個方法钉迷,參數(shù)為‘ url’;ios則調(diào)起推流頁面钠署,推流到url糠聪。
@interface FlutterRtmpPlugin ()
@property(strong, nonatomic) UIViewController *viewController;
@end
@implementation FlutterRtmpPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_rtmp_plugin"
binaryMessenger:[registrar messenger]];
UIViewController *viewController =
[UIApplication sharedApplication].delegate.window.rootViewController;
FlutterRtmpPlugin* instance = [[FlutterRtmpPlugin alloc] initWithViewController:viewController];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (instancetype)initWithViewController:(UIViewController *)viewController {
self = [super init];
if (self) {
self.viewController = viewController;
}
return self;
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([call.method isEqualToString:@"startLive"]) {
NSDictionary * dict = call.arguments;
NSLog(@"流地址是 %@",dict[@"url"]);
LFViewController *liveVC = [[LFViewController alloc] init];
liveVC.liveUrl = dict[@"url"];
liveVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self.viewController presentViewController:liveVC animated:YES completion:nil];
}
else {
result(FlutterMethodNotImplemented);
}
}
LFViewController就是純ios代碼了。你可以在Assets文件夾下添加資源文件谐鼎、也可以使用xib搭建UI舰蟆。
4、 Android端代碼書寫
1该面、android目錄如下
2夭苗、android端的推流使用的是SopCastComponent
在plugin模塊的gradle中添加依賴
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:+'
//LFLive
implementation 'com.laifeng:sopcast-sdk:1.0.4'
}
3信卡、FlutterRtmpPlugin類
注意:flutter1.12版本的回調(diào)方法如下
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
FlutterRtmpPlugin plugin = new FlutterRtmpPlugin();
plugin.context = flutterPluginBinding.getApplicationContext();
final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_rtmp_plugin");
channel.setMethodCallHandler(plugin);
}
flutter1.12版本之前則在registerWith方法中回調(diào)
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_rtmp_plugin");
channel.setMethodCallHandler(new FlutterRtmpPlugin());
}
寫的時候因為這個隔缀,總是回調(diào)不到,走了不少彎路傍菇。
拿到app的當(dāng)前context或activity之后就可以進行頁面跳轉(zhuǎn)了猾瘸,邏輯和ios一樣
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if(call.method.equals("startLive")){
Intent intent = new Intent(context,LivingActivity.class);
String url = call.argument("url");
intent.putExtra("url",url);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity(intent);
} else {
result.notImplemented();
}
}
LivingActivity 就是純android原生代碼了,在這里注意下丢习,flutter調(diào)起的頁面自帶一個導(dǎo)航欄牵触,
在LivingActivity中添加進行去除
requestWindowFeature(Window.FEATURE_NO_TITLE);