Я ищу способ потоковой передачи моего iPhone экрана на локальный nodejs сервер.
Сначала я исследую функцию Screen Mirroring
, но кажется, что эта технология не является открытым исходным кодом. Я не могу найти поддержки для создания сервера трансляции с использованием nodejs или любой другой технологии. Единственный проект с открытым исходным кодом, который я нашел, это https://github.com/FD-/RPiPlay, но для меня будет действительно трудно преобразовать его в nodejs
Затем я попытался сделать это, создав react-native
приложение и создание собственного модуля
#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
Это работает в приложении, но не вне приложения