реагировать на собственный поток ios экран на локальный сервер - PullRequest
6 голосов
/ 25 мая 2020

Я создаю приложение 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 локальном сервере, но я не могу найти никакой документации, только документация или модуль, которые я получаю, устарели и не работали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...