Я создаю приложение React Native, чтобы иметь возможность передавать содержимое моего телефона на локальный NodeJS сервер.
На android он отлично работает с MediaProjectionManager
, но на iOS это более сложный.
Я пытался сделать это с помощью RPScreenRecorder
, это мой код
#import "ScreenShare.h"
@implementation ScreenShare
RCT_EXPORT_MODULE();
- (NSString *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [temporaryContext
createCGImage:ciImage
fromRect:CGRectMake(0, 0,
CVPixelBufferGetWidth(imageBuffer),
CVPixelBufferGetHeight(imageBuffer))];
UIImage *image = [[UIImage alloc] initWithCGImage:videoImage];
NSString *base64String = [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
CGImageRelease(videoImage);
return (base64String);
}
- (NSArray<NSString *> *)supportedEvents
{
return @[@"ImageCaptured"];
}
RCT_REMAP_METHOD(start,
startWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
[result setObject:@true forKey:@"success"];
if (@available(iOS 11.0, *)) {
if([RPScreenRecorder.sharedRecorder isRecording]) {
return resolve(result);
}
[RPScreenRecorder.sharedRecorder startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {
dispatch_sync(dispatch_get_main_queue(), ^{
if(bufferType == RPSampleBufferTypeVideo) {
NSString *strEncoded = [self imageFromSampleBuffer:sampleBuffer];
[self sendEventWithName:@"ImageCaptured" body:@{@"image": strEncoded}];
}
});
} completionHandler:^(NSError * _Nullable error) {
if(error == NULL) return resolve(result);
// The user declined application recording
if([error code] == -5801) {
return reject(@"401", [error localizedDescription], error);
}
reject([NSString stringWithFormat:@"%ld", [error code]], [error localizedDescription], error);
}];
} else {
NSError * error = [NSError errorWithDomain:@"com.xxx.ConnectApp" code:426 userInfo:nil];
reject([NSString stringWithFormat:@"%ld", [error code]], @"Failed to start screen capture", error);
};
}
RCT_REMAP_METHOD(stop,
stopWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
[result setObject:@true forKey:@"success"];
if (@available(iOS 11.0, *)) {
[RPScreenRecorder.sharedRecorder stopCaptureWithHandler:^(NSError * _Nullable error) {
if(error == NULL) return resolve(result);
reject([NSString stringWithFormat:@"%ld", [error code]], [error localizedDescription], error);
}];
} else {
NSError * error = [NSError errorWithDomain:@"com.xxx.ConnectApp" code:426 userInfo:nil];
reject([NSString stringWithFormat:@"%ld", [error code]], @"Failed to stop screen capture", error);
}
}
@end
Качество видео не очень хорошее, и оно останавливается, когда я выхожу за пределы приложения. Цель приложения - обеспечить возможность потоковой передачи вне приложения, а не приложения.
Я исследую другое решение для создания сервера трансляции на моем NodeJS локальном сервере, но я не могу найти никакой документации, только документация или модуль, которые я получаю, устарели и не работали.