#import "IosTexturePlugin.h" #import #import "OralCavityManager.h" #define WeakSelf __weak typeof(self) weakSelf = self; //FlutterTexture @interface MyTexture : NSObject @property(nonatomic, assign) CVPixelBufferRef pixelBuffer; @end @implementation MyTexture // Flutter 会调用此方法来获取 CVPixelBuffer - (CVPixelBufferRef)copyPixelBuffer { //3. if (_pixelBuffer) { // CVPixelBufferRetain(_pixelBuffer); return _pixelBuffer; } return NULL; } // 你需要在不再需要 pixelBuffer 时释放它 - (void)dealloc { if (_pixelBuffer) { CVPixelBufferRelease(_pixelBuffer); } } @end //FlutterPlatformView @interface MyCustomView : NSObject - (instancetype)initWithFrame:(CGRect)frame view:(CALayer *)view; @end @implementation MyCustomView { UIView *_view; } - (instancetype)initWithFrame:(CGRect)frame view:(CALayer *)view { self = [super init]; if (self) { _view = [[UIView alloc] initWithFrame:frame]; [_view.layer addSublayer:view]; } return self; } - (UIView*)view { return _view; } @end //FlutterPlatformViewFactory @interface MyCustomViewFactory : NSObject @property(nonatomic, strong) CALayer * videoView; @end @implementation MyCustomViewFactory - (nonnull NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args { return [[MyCustomView alloc] initWithFrame:frame view:_videoView]; } @end @interface IosTexturePlugin () @property(nonatomic, strong) MyTexture *myTexture; @property(nonatomic, strong) NSObject *textureRegistry; @property(nonatomic, assign) int64_t textureId; @property (nonatomic, strong) FlutterMethodChannel *videoControlChannel; @end @implementation IosTexturePlugin + (void)registerWithRegistrar:(NSObject*)registrar { //视频控制 FlutterMethodChannel* videoControlChannel = [FlutterMethodChannel methodChannelWithName:@"videoControl" binaryMessenger:[registrar messenger]]; //文件控制 FlutterMethodChannel* fileControlChannel = [FlutterMethodChannel methodChannelWithName:@"fileControl" binaryMessenger:[registrar messenger]]; IosTexturePlugin* instance = [[IosTexturePlugin alloc] initWithRegistrar:registrar Channel:videoControlChannel]; [registrar addMethodCallDelegate:instance channel:videoControlChannel]; [registrar addMethodCallDelegate:instance channel:fileControlChannel]; //视频流 [OralCavityManager sharedInstance].getVideoView = ^(CALayer *view) { MyCustomViewFactory* factory = [[MyCustomViewFactory alloc] init]; factory.videoView = view; [registrar registerViewFactory:factory withId:@"VideoView"]; }; //设备拍照 [OralCavityManager sharedInstance].onDeviceTakePhoto = ^{ //sendToflutter NSLog(@"===onDeviceTakePhoto"); [videoControlChannel invokeMethod:@"onDeviceTakePhoto" arguments:nil]; }; } - (instancetype)initWithRegistrar:(NSObject*)registrar Channel:(FlutterMethodChannel *)videoControlChannel { self = [super init]; if (self) { _textureRegistry = [registrar textures]; _myTexture = [[MyTexture alloc] init]; // 注册纹理并获取纹理ID _textureId = [_textureRegistry registerTexture:_myTexture]; //设置回调channel _videoControlChannel = videoControlChannel; } return self; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { WeakSelf; //获取设备连接状态 if ([@"getConnectStatus" isEqualToString:call.method]) { // NSLog(@"获取状态 === %d", [[OralCavityManager sharedInstance] connectToServer]); result(@([[OralCavityManager sharedInstance] connectToServer])); } //开始视频 else if ([@"startVideo" isEqualToString:call.method]) { NSLog(@"开始视频textureId === %lld",self.textureId); result(@(self.textureId)); [[OralCavityManager sharedInstance] startVideo]; // [OralCavityManager sharedInstance].getPixelBuffer = ^(CVPixelBufferRef pixelBuffer) { // // if (pixelBuffer) { // // 在赋值之前释放旧的 pixel buffer,避免内存泄漏 // if (weakSelf.myTexture.pixelBuffer != NULL) { // CVPixelBufferRelease(weakSelf.myTexture.pixelBuffer); // } // // // 保留新获取的 pixel buffer,确保它不会被释放 // CVPixelBufferRetain(pixelBuffer); // weakSelf.myTexture.pixelBuffer = pixelBuffer; // // // 通知 Flutter 有新帧可以显示 // [weakSelf.textureRegistry textureFrameAvailable:weakSelf.textureId]; // } // // }; } //停止视频 else if ([@"stopVideo" isEqualToString:call.method]) { NSLog(@"===停止视频"); [[OralCavityManager sharedInstance] stopVideo]; } //拍照 else if ([@"takePhoto" isEqualToString:call.method]) { NSLog(@"===拍照 %@",call.arguments); [[OralCavityManager sharedInstance] takePhoto:call.arguments]; [OralCavityManager sharedInstance].getPhotoPath = ^(NSString *path) { if ([path containsString:@"jpg"]) { result(path); }else { result([FlutterError errorWithCode:call.method message:path details:@"appId"]); } NSLog(@"拍照结果photoPath ===%@",path); }; } //savePhoto else if([@"savePhoto" isEqualToString:call.method]) { NSLog(@"savePhoto ===arguments %@",call.arguments); [[OralCavityManager sharedInstance] savePhoto:call.arguments]; [OralCavityManager sharedInstance].getSavePhotoPath = ^(NSString *path) { if ([path containsString:@"error"]) { result([FlutterError errorWithCode:call.method message:path details:@"appId"]); }else { result(path); } NSLog(@"savePhoto ===%@",path); }; } //开始录像 else if ([@"startRecord" isEqualToString:call.method]) { NSLog(@"===开始录像 %@",call.arguments); [[OralCavityManager sharedInstance] startRecord:call.arguments]; result(@"startRecord"); } //停止录像 else if ([@"stopRecord" isEqualToString:call.method]) { [[OralCavityManager sharedInstance] stopRecord]; [OralCavityManager sharedInstance].getVideoPath = ^(NSString *path) { if ([path containsString:@"Documents"]) { result(path); }else { result([FlutterError errorWithCode:call.method message:path details:@"appId"]); } NSLog(@"停止录像VideoPath ===%@",path); }; } //saveRecord else if([@"saveRecord" isEqualToString:call.method]) { NSLog(@"saveRecord ===arguments %@",call.arguments); [[OralCavityManager sharedInstance] saveRecord:call.arguments]; [OralCavityManager sharedInstance].getSaveRecordPath = ^(NSString *path) { if ([path containsString:@"error"]) { result([FlutterError errorWithCode:call.method message:path details:@"appId"]); }else { result(path); } NSLog(@"saveRecord ===%@",path); }; } //获取图片列表 else if ([@"getPhotoList" isEqualToString:call.method]) { NSArray * arr = [[OralCavityManager sharedInstance] getPhotoList]; // if (arr.count > 0) { result(arr); // }else { // result([FlutterError errorWithCode:call.method message:@"获取图片列表失败" details:@"appId"]); // } NSLog(@"===photolist = %@",arr); } //获取视频列表 else if ([@"getVideoList" isEqualToString:call.method]) { NSArray *arr = [[OralCavityManager sharedInstance] getVideoList]; // if (arr.count > 0) { result(arr); // }else { // result([FlutterError errorWithCode:call.method message:@"获取视频列表失败" details:@"appId"]); // } NSLog(@"===videoList = %@",arr); } //删除指定文件 else if ([@"deleteFile" isEqualToString:call.method]) { NSLog(@"===deleteFile = %@",call.arguments); int success = [[OralCavityManager sharedInstance] deleteFile:call.arguments]; result(@(success)); } //横屏 else if ([@"getLandscapeView" isEqualToString:call.method]) { NSArray *arr = call.arguments; NSLog(@"===fullScreen %@",arr); [[OralCavityManager sharedInstance] getLandscapeView:arr]; } //竖屏 else if ([@"getPortraitView" isEqualToString:call.method]) { NSLog(@"===smallScreen"); [[OralCavityManager sharedInstance] getPortraitView]; } else { result(FlutterMethodNotImplemented); } } @end