uni-app原生插件(2)--录屏
2023-12-15 本文已影响0人
哈酒拎壶冲
上一篇文章记录了截图插件,这篇文章记录以下录屏插件,这两个功能都是最近工作上遇到的,在这里做个记录。
创建录屏拓展Extension File->New->target 搜索broadcast Setup UI Extension
1.png.png3335bc2c7152ff367f08a36074969b6.png
创建拓展成功后生成两个文件如图所示
d0dccd9fb2a36fba64811c9d0daea72.pngb0cc013531167f05bacd73733448930.png录屏插件录屏后保存到本地,通过APP Group共享空间与工程代码交互 设置APPGroup过程,苹果开发者网站boundID绑定APPGroup,主程序与录屏拓展全部选择target->添加capabili AppGroup,然后选择appgroupID
![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.png1d3df14adc921fd5ae338979d619a51.png
最后附上运行效果图
3c0c71a342dafd715ad698f3abe1895.pngc81aac249a2b645282cc5f1ddd7776d.png
dd949969a1fc0dd0be66c94d67f7bf9.png