美文网首页
uni-app原生插件(2)--录屏

uni-app原生插件(2)--录屏

作者: 哈酒拎壶冲 | 来源:发表于2023-12-15 10:51 被阅读0次

    上一篇文章记录了截图插件,这篇文章记录以下录屏插件,这两个功能都是最近工作上遇到的,在这里做个记录。

    创建录屏拓展Extension File->New->target 搜索broadcast Setup UI Extension

    1.png.png
    3335bc2c7152ff367f08a36074969b6.png

    创建拓展成功后生成两个文件如图所示

    d0dccd9fb2a36fba64811c9d0daea72.png

    录屏插件录屏后保存到本地,通过APP Group共享空间与工程代码交互 设置APPGroup过程,苹果开发者网站boundID绑定APPGroup,主程序与录屏拓展全部选择target->添加capabili AppGroup,然后选择appgroupID

    b0cc013531167f05bacd73733448930.png
    ![99d1ccf336404d7236eb04d8b5c03dd.png](https://img.haomeiwen.com/i1421910/d7c4cebfb8c86021.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    f4a0dc65b5d310ba82eefc0a8e9d849.jpg
    99d1ccf336404d7236eb04d8b5c03dd.png

    接下来主要是录屏代码

     - (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo {
         // User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
         NSLog(@"开始录屏");
         [self sendNotificationForMessageWithIdentifier:@"start" userInfo:nil];
         [self initData];
     }
    
     - (void)broadcastPaused {
         // User has requested to pause the broadcast. Samples will stop being delivered.
     }
    
     - (void)broadcastResumed {
         // User has requested to resume the broadcast. Samples delivery will resume.
     }
    
     - (void)broadcastFinished {
         // User has requested to finish the broadcast.
         NSLog(@"结束录屏");
         [self.assetWriter finishWritingWithCompletionHandler:^{
             NSLog(@"结束写入数据");
         }];
         //获取到对应的空间路径就可以在该路径下读写文件
         NSString *time = @"output";
         NSString *fileName = [time stringByAppendingPathExtension:@"mp4"];
         NSString *fullPath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
         NSURL *pathURL = [[NSFileManager alloc] containerURLForSecurityApplicationGroupIdentifier:@"group.com.iallchain.replaykit-demo"];
         pathURL = [pathURL URLByAppendingPathComponent:@"Library/Documents/output.mp4"];
         NSLog(@"%@==",pathURL);
         [self sendNotificationForMessageWithIdentifier:@"broadcastFinished" userInfo:nil];
     }
     //录屏状态
     - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {
         
         switch (sampleBufferType) {
             case RPSampleBufferTypeVideo:
                 // Handle video sample buffer
                 NSLog(@"视频流");
                 AVAssetWriterStatus status = self.assetWriter.status;
                 if (status == AVAssetWriterStatusFailed || status == AVAssetWriterStatusCompleted || status == AVAssetWriterStatusCancelled) {
                     return;
                 }
                 if (status == AVAssetWriterStatusUnknown) {
                     [self.assetWriter startWriting];
                     CMTime time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
                     [self.assetWriter startSessionAtSourceTime:time];
                     NSLog(@"写入视频");
                 }
                 if (status == AVAssetWriterStatusWriting ) {
                     if (self.videoInput.isReadyForMoreMediaData) {
                         BOOL success = [self.videoInput appendSampleBuffer:sampleBuffer];
                         if (!success) {
                             [self stopRecording];
                         }
                     }
                 }
                 break;
             case RPSampleBufferTypeAudioApp:
                 // Handle audio sample buffer for app audio
                 break;
             case RPSampleBufferTypeAudioMic:
                 // Handle audio sample buffer for mic audio
                 if (self.audioInput.isReadyForMoreMediaData) {
                     BOOL success = [self.audioInput appendSampleBuffer:sampleBuffer];
                     if (!success) {
                         [self stopRecording];
                     }
                 }
                 break;
                 
             default:
                 break;
         }
     }
     
     - (void)sendNotificationForMessageWithIdentifier:(nullable NSString *)identifier userInfo:(NSDictionary *)info {
         CFNotificationCenterRef const center = CFNotificationCenterGetDarwinNotifyCenter();
         CFDictionaryRef userInfo = (__bridge CFDictionaryRef)info;
         BOOL const deliverImmediately = YES;
         CFStringRef identifierRef = (__bridge CFStringRef)identifier;
         CFNotificationCenterPostNotification(center, identifierRef, NULL, userInfo, deliverImmediately);
     }
    
     - (AVAssetWriter *)assetWriter{
         if (!_assetWriter) {
             NSError *error = nil;
             NSArray *pathDocuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
             NSString *outputURL = pathDocuments[0];
             self.videoOutPath = [[outputURL stringByAppendingPathComponent:@"demo"] stringByAppendingPathExtension:@"mp4"];
             NSLog(@"self.videoOutPath=%@",self.videoOutPath);
             _assetWriter = [[AVAssetWriter alloc] initWithURL:[self getFilePathUrl] fileType:(AVFileTypeMPEG4) error:&error];
             NSLog(@"%@",_assetWriter);
             NSAssert(!error, @"_assetWriter 初始化失败");
         }
         return _assetWriter;
     }
    
     -(AVAssetWriterInput *)audioInput{
         if (!_audioInput) {
             // 音频参数
             NSDictionary *audioCompressionSettings = @{
                 AVEncoderBitRatePerChannelKey:@(28000),
                 AVFormatIDKey:@(kAudioFormatMPEG4AAC),
                 AVNumberOfChannelsKey:@(1),
                 AVSampleRateKey:@(22050)
             };
             _audioInput  = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioCompressionSettings];
         }
         return _audioInput;
     }
    
     -(AVAssetWriterInput *)videoInput{
         if (!_videoInput) {
    
             CGSize size = [UIScreen mainScreen].bounds.size;
             // 视频大小
             NSInteger numPixels = size.width * size.height;
             // 像素比
             CGFloat bitsPerPixel = 7.5;
             NSInteger bitsPerSecond = numPixels * bitsPerPixel;
             // 码率和帧率设置
             NSDictionary *videoCompressionSettings = @{
                 AVVideoAverageBitRateKey:@(bitsPerSecond),//码率
                 AVVideoExpectedSourceFrameRateKey:@(25),// 帧率
                 AVVideoMaxKeyFrameIntervalKey:@(15),// 关键帧最大间隔
                 AVVideoProfileLevelKey:AVVideoProfileLevelH264BaselineAutoLevel,
                 AVVideoPixelAspectRatioKey:@{
                         AVVideoPixelAspectRatioVerticalSpacingKey:@(1),
                         AVVideoPixelAspectRatioHorizontalSpacingKey:@(1)
                 }
             };
             CGFloat scale = [UIScreen mainScreen].scale;
    
             // 视频参数
             NSDictionary *videoOutputSettings = @{
                 AVVideoCodecKey:AVVideoCodecTypeH264,
                 AVVideoScalingModeKey:AVVideoScalingModeResizeAspectFill,
                 AVVideoWidthKey:@(size.width*scale),
                 AVVideoHeightKey:@(size.height*scale),
                 AVVideoCompressionPropertiesKey:videoCompressionSettings
             };
    
             _videoInput  = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoOutputSettings];
             _videoInput.expectsMediaDataInRealTime = true;
         }
         return _videoInput;
     }
    
     - (void)stopRecording {
         [self.assetWriter finishWritingWithCompletionHandler:^{
             NSLog(@"结束写入数据");
         }];
     }
    
     - (NSURL *)getFilePathUrl {
         //NSString *time = [NSDate timestamp];
         //NSString *time = @"replays";
         NSString *time = @"output";
         NSString *fileName = [time stringByAppendingPathExtension:@"mp4"];
         NSString *fullPath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
         NSLog(@"初始化本地路径%@",fullPath);
         return [NSURL fileURLWithPath:fullPath];
     }
    
     //这个方法是重点 保存的路径名字要确定好,Library/Documents 后期主程序获取appGroup空间的内容需要用到,关于APPGroup共享空间的使用,可以使用NSFileManager或者NSUserDefaults,这里使用的NSFileManager,关于NSUserDefaults之后再单独写一篇文章记录
     - (NSString *)getDocumentPath {
    
         static NSString *replaysPath;
         if (!replaysPath) {
             NSFileManager *fileManager = [NSFileManager defaultManager];
             NSURL *documentRootPath = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.com.iallchain.replaykit-demo"];
             //replaysPath = [documentRootPath.path stringByAppendingPathComponent:@"Replays"];
             replaysPath = [documentRootPath.path stringByAppendingPathComponent:@"Library/Documents"];
             if (![fileManager fileExistsAtPath:replaysPath]) {
                 NSError *error_createPath = nil;
                 BOOL success_createPath = [fileManager createDirectoryAtPath:replaysPath withIntermediateDirectories:true attributes:@{} error:&error_createPath];
                 if (success_createPath && !error_createPath) {
                     NSLog(@"%@路径创建成功!", replaysPath);
                 } else {
                     NSLog(@"%@路径创建失败:%@", replaysPath, error_createPath);
                 }
             }else{
                 BOOL blDele= [fileManager removeItemAtPath:replaysPath error:nil];
                 if (blDele) {
                 NSLog(@"dele success");
                 }else {
                 NSLog(@"dele fail");
                 }
                 NSLog(@"%@路径已存在!", replaysPath);
                 NSError *error_createPath = nil;
                 BOOL success_createPath = [fileManager createDirectoryAtPath:replaysPath withIntermediateDirectories:true attributes:@{} error:&error_createPath];
                 if (success_createPath && !error_createPath) {
                     NSLog(@"%@路径创建成功!", replaysPath);
                 } else {
                     NSLog(@"%@路径创建失败:%@", replaysPath, error_createPath);
                 }
             }
             
         }
         return replaysPath;
     }
    
     - (NSArray <NSURL *> *)fetechAllResource {
         NSFileManager *fileManager = [NSFileManager defaultManager];
    
         NSString *documentPath = [self getDocumentPath];
         NSURL *documentURL = [NSURL fileURLWithPath:documentPath];
         NSError *error = nil;
         NSArray<NSURL *> *allResource  =  [fileManager contentsOfDirectoryAtURL:documentURL includingPropertiesForKeys:@[] options:(NSDirectoryEnumerationSkipsSubdirectoryDescendants) error:&error];
         return allResource;
    
     }
     - (void)initData {
         if ([self.assetWriter canAddInput:self.videoInput]) {
             [self.assetWriter addInput:self.videoInput];
         }else{
             NSLog(@"添加input失败");
         }
     }
    
     - (NSString *) folderSizeAtPath:(NSString*) folderPath{
    
         NSLog(@"视频路径%@",folderPath);
         NSFileManager* manager = [NSFileManager defaultManager];
         if (![manager fileExistsAtPath:folderPath]) return 0;
         NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
         NSString* fileName;
         long long folderSize = 0;
         NSLog(@"%@==%@",[childFilesEnumerator allObjects],folderPath);
         while ((fileName = [childFilesEnumerator nextObject]) != nil){
             NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
             NSLog(@"+++%@++++",fileAbsolutePath);
             folderSize += [self fileSizeAtPath:fileAbsolutePath];
         }
         NSLog(@"文件大小%lld",folderSize);
         if (folderSize < 1024.0) {
             return  [NSString stringWithFormat:@"%.2fB",folderSize * 1.0];
         }else if (folderSize >= 1024.0 && folderSize < (1024.0*1024.0)){
             return  [NSString stringWithFormat:@"%.2fKB",folderSize/1024.0];
         }if (folderSize >= (1024.0*1024.0) && folderSize < (1024.0*1024.0*1024.0)) {
             return [NSString stringWithFormat:@"%.2fMB", folderSize/(1024.0*1024.0)];
         }else{
             return [NSString stringWithFormat:@"%.2fGB", folderSize/(1024.0*1024.0*1024.0)];
         }
     }
    
     - (long long) fileSizeAtPath:(NSString*) filePath{
         NSFileManager* manager = [NSFileManager defaultManager];
         if ([manager fileExistsAtPath:filePath]){
             return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
         }
         return 0;
     }
    

    接下来是主插件获取录屏插件保存在共享空间内部的视频,并与uni-app进行交互,创建插件上一篇文章具体讲解过,这里就不再详细描述,直接上获取APPGroup空间内容并传给uni-app代码

    iOS12以上 使用RPSystemBroadcastPickerView调用系统的录屏功能

     //创建拉起系统录屏分类
     - (instancetype)initWithFrame:(CGRect)frame
     {
         self = [super initWithFrame:frame];
         if (self) {
             if (@available(iOS 12.0, *)) {
                 self.broadcastPickerView = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
                 self.broadcastPickerView.preferredExtension = @"com.iallchain.platform.replay.1";
                 self.broadcastPickerView.showsMicrophoneButton = YES;
                 [self addSubview:self.broadcastPickerView];
             }
         }
         return self;
     }
     //uni-app使用本地按钮执行拉起操作
     //UNI_EXPORT_METHOD方法为与uni-app交互方法,这里不具体描述
     UNI_EXPORT_METHOD(@selector(screenRecording:))
     - (void)screenRecording:(NSDictionary *)options {
         for (UIView *subView in [self getReplayView].broadcastPickerView.subviews) {
             if ([subView isMemberOfClass:[UIButton class]]) {
                 UIButton *button = (UIButton *)subView;
                 [button sendActionsForControlEvents:UIControlEventAllEvents];
             }
         }
     }
    
     - (ReplayView *)getReplayView {
         return (ReplayView *)self.view;
     }
     
     #pragma mark - 宿主与extension之间的通知
     - (void)registerForNotificationsWithIdentifier:(nullable NSString *)identifier {
         [self unregisterForNotificationsWithIdentifier:identifier];
         CFNotificationCenterRef const center = CFNotificationCenterGetDarwinNotifyCenter();
         CFStringRef str = (__bridge CFStringRef)identifier;
         CFNotificationCenterAddObserver(center,
                                         (__bridge const void *)(self),
                                         MyHoleNotificationCallback,
                                         str,
                                         NULL,
                                         CFNotificationSuspensionBehaviorDeliverImmediately);
     }
    
     - (void)unregisterForNotificationsWithIdentifier:(nullable NSString *)identifier {
         CFNotificationCenterRef const center = CFNotificationCenterGetDarwinNotifyCenter();
         CFStringRef str = (__bridge CFStringRef)identifier;
         CFNotificationCenterRemoveObserver(center,
                                            (__bridge const void *)(self),
                                            str,
                                            NULL);
     }
     
     #pragma mark - 接收来自extension的消息
     - (void)addUploaderEventMonitor {
         
         [self registerForNotificationsWithIdentifier:@"broadcastFinished"];
         [self registerForNotificationsWithIdentifier:@"start"];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(broadcastInfo:) name:ScreenHoleNotificationName object:nil];
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(broadcastInfo:) name:@"start" object:nil];
     }
     
     #pragma mark - 移除Observer
     - (void)removeUploaderEventMonitor {
         
         [self unregisterForNotificationsWithIdentifier:@"broadcastFinished"];
         [self unregisterForNotificationsWithIdentifier:@"start"];
         [[NSNotificationCenter defaultCenter] removeObserver:self name:ScreenHoleNotificationName object:nil];
    
     }
     
    

    附上uni-app方法

     <view class="container">
             //这个是与插件录屏交互方法声明
             <view class="top-view">
                 <dc-replay class="page-container" ref='mycomponent'
                 @startVideo="startVideo" @finishVideo="finishVideo" @loadHTMLURL="loadHTMLURL"></dc-replay>
             </view>
             <view class="bottom-view">
                 <view class="button-group">
                     <button class="button-view" @click="onScreenRecording">开始录制11111</button>
                     <button class="button-view" @click="getVideoURL">获取视频URL</button>
                     <button class="button-view" @click="deleteVideoFromURL">删除视频</button>
                     <button class="button-view" @click="onGetFile">获取视频文件2222</button>
                     <button class="button-view" @click="playVideo">播放</button>
                 </view>
             </view>
             <!-- <video class="videoView"  width="100%" height="200px" :src="fileurl" show-play-btn="true"></video> -->
         </view>
     
     <script>
     import { computed } from "vue";
         export default {
             data() {
                 return {
                 fileurl: '',
                 }
             },
             methods: {
                 loadHTMLURL(e) {
                     console.log("loadHTMLURL网页地址传值====",e);
                 },
                 //这里screenRecording为交互方法
                 onScreenRecording: function() {
                     console.log('点击了 开始录制 按钮');
                     this.$refs.mycomponent.screenRecording({});
                 }
                 
             }
         }
     </script>
    

    接下来是获取appGroup共享空间内容代码

     //获取录屏监听信息
     static NSString * const ScreenHoleNotificationName = @"ScreenHoleNotificationName";
    
     void MyHoleNotificationCallback(CFNotificationCenterRef center,
                                        void * observer,
                                        CFStringRef name,
                                        void const * object,
                                        CFDictionaryRef userInfo) {
         NSString *identifier = (__bridge NSString *)name;
         NSObject *sender = (__bridge NSObject *)observer;
         //NSDictionary *info = (__bridge NSDictionary *)userInfo;
         NSDictionary *info = CFBridgingRelease(userInfo);
         
         NSLog(@"userInfo %@  %@",userInfo,info);
    
         NSDictionary *notiUserInfo = @{@"identifier":identifier};
         
         if ([identifier isEqualToString:@"broadcastFinished"]) {
             [[NSNotificationCenter defaultCenter] postNotificationName:ScreenHoleNotificationName
                                                                 object:sender
                                                               userInfo:notiUserInfo];
         } else {
             [[NSNotificationCenter defaultCenter] postNotificationName:@"start"
                                                                 object:sender
                                                               userInfo:notiUserInfo];
         }
     }
     
     //通过监听录屏状态获取共享空间录屏内容
     - (void)broadcastInfo:(NSNotification *)noti {
         
         NSDictionary *userInfo = noti.userInfo;
         NSString *identifier = userInfo[@"identifier"];
         
         if ([identifier isEqualToString:@"broadcastFinished"]) {
             //reload数据
             NSFileManager *fileManager = [NSFileManager defaultManager];
             NSURL *pathURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.com.iallchain.replaykit-demo"];
             NSString *databasePath =  [pathURL URLByAppendingPathComponent:@"Library/Documents/output.mp4"].path;
             NSData *data = [NSData dataWithContentsOfFile:databasePath];
             _iscopySuccess = @"1";
             if(data.length != 0){
                 [self writeFile2:databasePath];
                 _iscopySuccess = @"2";
                 //这是模拟播放器,测试录屏视频保存本地后是否可以正常播放,self.videoPath为保存本地路径
                 AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:self.videoPath]];
                 self.moviePlayer.player = avPlayer;
                 [avPlayer play];
             }
             _videoDic = [[NSMutableDictionary alloc] init];
             //这里做了贡献空间视频保存本地相册操作
             if (self.videoPath.length > 0) {
                 [self saveVideoWithUrl:[NSURL fileURLWithPath:self.videoPath]];
             } else {
                 [self saveVideoWithUrl:pathURL];
             }
             
             NSLog(@"文件大小%@",[self folderSizeAtPath:pathURL.path]);
             
         } else if ([identifier isEqualToString:@"start"])  {
             //与uni-app交互方法 给uni-app传递开始录屏状态
             [self fireEvent:@"startVideo" params:@{} domChanges:nil];
         }
         
     }
     //保存相册操作
     - (void)saveVideoWithUrl:(NSURL *)url {
         PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary];
         [photoLibrary performChanges:^{
             [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
    
         } completionHandler:^(BOOL success, NSError * _Nullable error) {
             if (success) {
                 NSLog(@"已将视频保存至相册");
                 self->_photoalbum = @"2";
             } else {
                 NSLog(@"未能保存视频到相册%@",error);
                 self->_photoalbum = @"1";
             }
             [self->_videoDic setValue:self->_photoalbum forKey:@"photoalbum"];
             //这个测试使用 给uni-app传值验证是否保存成功
             if ([error isEqual:[NSNull null]] || error == nil) {} else {
                 [self->_videoDic setValue:error forKey:@"error"];
             }
             NSLog(@"%@",self->_videoDic);
             //与uni-app交互方法 给uni-app传递结束录屏状态
             [self fireEvent:@"finishVideo" params:@{@"detail":@{@"mapLoaded":self->_videoDic}} domChanges:nil];
         }];
     }
     
     //从共享空间写入本地沙盒文件,这里有个问题,与uni-app交互 选用temp目录保存文件,其他目录不是到是什么原因,获取不到视频文件
     - (void)writeFile2:(NSString* )d {
         //1.初始化一个NSFileManager对象(使用单例)
         NSFileManager *manager = [NSFileManager defaultManager];
         //2.获取根路径
         NSString *rootPath = NSTemporaryDirectory();
         //3.创建文件
         rootPath = [rootPath stringByAppendingPathComponent:@"/Pandora/documents"];
         //4.创建目录
         //createDirectoryAtPath:文件路径
         //********withIntermediateDirectories:是否在当前路径下创建/text/myApp
         [manager createDirectoryAtPath:rootPath withIntermediateDirectories:YES attributes:nil error:nil];
         //添加并写入
         rootPath = [rootPath stringByAppendingPathComponent:@"/output.mp4"];
         NSString *error;
         BOOL isSuccess = [d writeToFile:rootPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
         if (isSuccess) {
             NSLog(@"write success%@",rootPath);
             _writeSuccess = @"1";
         } else {
             NSLog(@"write fail,please record first%@",error);
             _writeSuccess = @"2";
         }
     }
    
     - (BOOL)clearCacheWithFilePath:(NSString *)path{
         //拿到path路径的下一级目录的子文件夹
         NSArray *subPathArr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
         NSLog(@"%@",subPathArr);
         NSString *filePath = nil;
         NSError *error = nil;
         for (NSString *subPath in subPathArr)
         {
             filePath = [path stringByAppendingPathComponent:subPath];
             //删除子文件夹
             [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
             if (error) {
                 return NO;
             }
         }
         return YES;
     }
     //获取本地沙盒路径
     -(NSString* )videoPath{
         if (!_videoPath) {
             NSString *documentsDirectory = NSTemporaryDirectory();
             NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"/Pandora/documents/output.mp4"];
             NSData *data = [NSData dataWithContentsOfFile:filePath];
             _videoPath = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
             NSLog(@"视频播放地址====%@==",_videoPath);
         }
         return _videoPath;
     }
     
     //测试录屏视频播放
     -(AVPlayerViewController *)moviePlayer{
    
        if (!_moviePlayer) {
            AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:@""]];
            _moviePlayer=[[AVPlayerViewController alloc]init];
            _moviePlayer.player = avPlayer;
            _moviePlayer.view.frame=CGRectMake(0, 100, self.view.frame.size.width, 200);
            _moviePlayer.view.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
            _moviePlayer.showsPlaybackControls = YES;
        }
         return _moviePlayer;
         
     }
    

    接下来是uni-app获取沙盒文件视频代码

     finishVideo: function(e) {
                     console.log('完成录屏');
                     // 原生端传递的数据保存在 e.detail 中
                     console.log(e)
                     console.log(e.detail['mapLoaded']['videopath'])
                     var copyPath = plus.io.convertLocalFileSystemURL("_doc/vv-work");
                     var copyPathName = copyPath + "/output.mp4";
                     const p = this.copyPathToSandboxPath(copyPath, copyPathName, e.detail.mapLoaded.videopath);
                     uni.showModal({
                         title: '提示',
                         content: "完成录屏",
                         showCancel: false
                     })
                 },
                 //直接获取的路径不能使用,需要uin-app转换一下可以使用的路径
                 copyPathToSandboxPath(copyPath, copyPathName, filePath) {
                         return new Promise((resolve, reject) => {
                             console.log("copy -> copyPath:" + copyPath);
                             console.log("copy -> copyPathName:" + copyPathName);
                             console.log("copy -> filePath:" + filePath);
                             filePath = filePath.replace("file://", "");
                             console.log("filePath-->" + filePath);
                 
                             var NSFileManager = plus.ios.importClass("NSFileManager");
                             var fileManager = NSFileManager.defaultManager();
                 
                             var isFileExist_Path = plus.ios.invoke(fileManager, "fileExistsAtPath:", copyPath);
                             console.log("isFileExist_Path:" + isFileExist_Path);
                             if (isFileExist_Path == false) {
                                 var isCreateDirectory = plus.ios.invoke(fileManager,
                                     "createDirectoryAtPath:withIntermediateDirectories:attributes:error:", copyPath,
                                     true, null, null);
                                 console.log("isCreateDirectory:" + isCreateDirectory);
                             }
                 
                             var isFileExist_PathName = plus.ios.invoke(fileManager, "fileExistsAtPath:", copyPathName);
                             console.log("isFileExist_PathName:" + isFileExist_PathName);
                             if (isFileExist_PathName == true) {
                                 // 如果存在 删除
                                 var isRemove = plus.ios.invoke(fileManager, "removeItemAtPath:error:", copyPathName, null);
                                 console.log("isRemove:" + isRemove);
                             }
                 
                             var isCopy = plus.ios.invoke(fileManager, "copyItemAtPath:toPath:error:", filePath,
                                 copyPathName, null);
                             if (isCopy) {
                                 console.log("FFFFFF isCopy true :" + copyPathName);
                                 this.fileurl = copyPathName
                                 // resolve("success")
                             } else {
                                 console.log("FFFFFF copyItem failed")
                                 reject("failed")
                             }
                         })
                     },
                 
                 startVideo: function(e) {
                     console.log('开始录屏');
                     uni.showModal({
                         title: '提示',
                         content: "开始录屏",
                         showCancel: false
                     })
                 },
    

    录屏插件打包 导入uni-app对应的文件夹 如下图 然后commond+b

    88a2413c8e32b662e8993e794b0a967.png

    然后选择products 选择录屏插件show in finder找到.appex结尾的文件 拖入到uni-app文件夹中

    357c254ecb1f2040da7f594ae36ce5f.png

    然后在uni-app配置文件写一下录屏配置信息,这些内容官网都有具体,这里附上测试代码截图

    15c4001828fb1e93d8251aecc30a937.png
    1d3df14adc921fd5ae338979d619a51.png

    最后附上运行效果图

    3c0c71a342dafd715ad698f3abe1895.png
    c81aac249a2b645282cc5f1ddd7776d.png
    dd949969a1fc0dd0be66c94d67f7bf9.png

    关于录屏的文章就记录到这里了

    相关文章

      网友评论

          本文标题:uni-app原生插件(2)--录屏

          本文链接:https://www.haomeiwen.com/subject/efqdgdtx.html