Как сделать jwplayer полноэкранным в react-native

Я планирую использовать jwplayer в react-native. На данный момент в Github нет работающего плагина jwplayer для реагирования, поэтому я работаю над модулем Native, который будет отображать jwplayer в режиме react-native.

Я могу рендерить видео в react-native, используя собственный модуль, а также могу воспроизводить видео и получать воспроизведение, приостанавливать другие события в react-native.

Но у меня проблема с полноэкранным режимом (он работает правильно в не полноэкранном режиме). Когда я нажимаю кнопку полноэкранного режима JwPlayer, экран приложения становится черным и возвращается после завершения видео. Во время отключения электроэнергии я слышу звук, но видео не отображается в режиме.

Вот код:

JavascriptBridgeJsFile

import React, { Component } from 'react'
import { requireNativeComponent } from 'react-native'

export default class JwPlayerWrapperView extends Component {

  setNativeProps = nativeProps => {
    if (this._root) {
      this._root.setNativeProps(nativeProps);
    }
  }

  render() {
    return <JwPlayerWrapper
      ref = {e => (this._root = e)}
      {...this.props}
      onFullScreen = {event =>
        this.props.onFullScreen && this.props.onFullScreen(event.nativeEvent)
      }
    />
  }
}

const JwPlayerWrapper = requireNativeComponent('JwPlayerWrapper', JwPlayerWrapperView)

JwPlayerWrapper.h

#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import <JWPlayer_iOS_SDK/JWPlayerController.h>
#import <React/UIView+React.h>

@class RCTEventDispatcher;

@interface JwPlayerWrapper : UIView
  // Define view properties here with @property
  @property(nonatomic, strong) JWPlayerController *player;
  @property(nonatomic, assign) NSString *playList;
  @property (nonatomic, assign) NSString *exampleProp;
  @property (nonatomic, copy) RCTDirectEventBlock onFullScreen;
  // Initializing with the event dispatcher allows us to communicate with JS
  - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
@end

JwPlayerWrapper.m

#import <Foundation/Foundation.h>
#import "JwPlayerWrapper.h"
#import <JWPlayer_iOS_SDK/JWPlayerController.h>


// import RCTEventDispatcher
#if __has_include(<React/RCTEventDispatcher.h>)
#import <React/RCTEventDispatcher.h>
#elif __has_include("RCTEventDispatcher.h")
#import "RCTEventDispatcher.h"
#else
//#import "React/RCTEventDispatcher.h" // Required when used as a Pod in a Swift project
#endif

@interface JwPlayerWrapper () <JWPlayerDelegate>
@end

@implementation JwPlayerWrapper : UIView  {

  RCTEventDispatcher *_eventDispatcher;
  JWConfig *config;  
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
  if ((self = [super init])) {
    _eventDispatcher = eventDispatcher;
    config = [[JWConfig alloc] init];
    config.file = @"https://content.jwplatform.com/manifests/yp34SRmf.m3u8";
    config.controls = YES;  //default
    config.playbackRateControls = TRUE;
    config.audioSwitchingEnabled = TRUE;
    config.stretching = TRUE;
    config.displayDescription = @"This is sample  video description";
    config.displayTitle = @"Cycling is good for health";
    self.player = [[JWPlayerController alloc] initWithConfig:config];
    self.player.delegate = self;
  }
  return self;
}

-(void)layoutSubviews
{
  [super layoutSubviews];
  self.player.forceFullScreenOnLandscape = YES;
  self.player.forceLandscapeOnFullScreen = YES;
  self.player.view.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth;
  self.player.view.frame = self.bounds;
  self.player.view.frame =  CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
  [self setAutoresizesSubviews:TRUE];
  [self addSubview:self.player.view];

}

- (void)onFullscreen:(JWEvent<JWFullscreenEvent> *)event
{
  //  NSLog(@"-=======================================ON FULLSCREEN x EVENT '%d'---------------------", event.fullscreen);
  if (self.onFullScreen)
  {
    self.onFullScreen(@{@"fullScreen":@(event.fullscreen)});
  }
}
@end

JwPlayerWrapperManager.h

// import RCTViewManager
#if __has_include(<React/RCTViewManager.h>)
#import <React/RCTViewManager.h>
#elif __has_include(“RCTViewManager.h”)
#import “RCTViewManager.h”
#else
#import “React/RCTViewManager.h” // Required when used as a Pod in a Swift project
#endif

// Subclass your view manager off the RCTViewManager
// http://facebook.github.io/react-native/docs/native-components-ios.html#ios-mapview-example
@interface JwPlayerWrapperManager : RCTViewManager 

@end

JwPlayerWrapperManager.m

#import <Foundation/Foundation.h>
#import "JwPlayerWrapper.h"
#import "JwPlayerWrapperManager.h"
#import <React/RCTUIManager.h>

// import RCTBridge
#if __has_include(<React/RCTBridge.h>)
#import <React/RCTBridge.h>
#elif __has_include(“RCTBridge.h”)
#import “RCTBridge.h”
#else
#import “React/RCTBridge.h” // Required when used as a Pod in a Swift project
#endif

@implementation JwPlayerWrapperManager

@synthesize bridge = _bridge;

// Export a native module
// https://facebook.github.io/react-native/docs/native-modules-ios.html
RCT_EXPORT_MODULE();

// Return the native view that represents your React component
- (UIView *)view
{
  return [[JwPlayerWrapper alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
}

- (dispatch_queue_t)methodQueue {
  return _bridge.uiManager.methodQueue;
}

RCT_EXPORT_VIEW_PROPERTY(exampleProp, NSString)
RCT_EXPORT_VIEW_PROPERTY(onFullScreen, RCTDirectEventBlock);


// Export constants
// https://facebook.github.io/react-native/releases/next/docs/native-modules-ios.html#exporting-constants
- (NSDictionary *)constantsToExport
{
  return @{
           @"EXAMPLE": @"example"
         };
}
@end

AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"JwPlayerDemo"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
//  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
  rootView.backgroundColor = [UIColor colorWithRed:0.00 green:0.00 blue:0.00 alpha:1.0];


  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

@end

app.js

import React, { Component } from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import JwPlayerWrapperView from './JwPlayerWrapper/JwPlayerWrapperNativeView'


let {
  width,
  height
} = Dimensions.get("window");


const videoWidth = width
const videoHeight = width / (16 / 9)


export default class App extends Component {
  state = {
    widthX: videoWidth,
    heightX: videoHeight,
    fullScreen: false
  }

  onFullScreen = (event) => {
    console.info('onFullScreen: ', event.fullScreen)
    this.setState({ fullScreen: event.fullScreen })
    if (event.fullScreen) {
      this.setState({
        heightX: width,
        widthX: height,
        fullScreen: true
      })
    } else {
      this.setState({
        heightX: videoHeight,
        widthX: videoWidth,
        fullScreen: false
      })
    }
  }

  render() {
    const { heightX, widthX } = this.state
    return (
      <View style = {styles.container}>
        <JwPlayerWrapperView
          ref = {ref => (this.player = ref)}
          style = {{ height: heightX, width: widthX }}
          onFullScreen = {this.onFullScreen}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Когда приложение находится в портретном режиме, и если вы нажмете полноэкранную кнопку проигрывателя, он отключит экран. Я не знаю, что нужно сделать, чтобы сделать полноэкранный режим. У меня нет собственного опыта разработки для iOS.

Детали версии

реагировать-родной: 0.55.1

ПОДУШКИ: - JWPlayer-SDK (3.1.4)

Вот ссылка на видео, которая показывает, что происходит:ССЫЛКА

Заранее спасибо.

В этом плане есть похожие проблемы: Может, это вам поможет

Donny Motta 11.11.2018 06:06

@DonnyMotta: Спасибо за ссылку, он устранил мою проблему с Android, но я не могу найти решение для ios

Bhavesh Jariwala 12.11.2018 06:22

@ Джордж: вот проблема, которую я описал здесь для моей проблемы с полноэкранным режимом ios.

Bhavesh Jariwala 28.12.2018 07:31

@BhaveshJariwala Отметьте здесь github.com/jwplayer/jwplayer-sdk-ios-demo/blob/master/…

MAhipal Singh 28.12.2018 09:17

Итак, в JwPlayerWrapper.m добавьте эту строку, попробуйте self.player. полноэкранный режим = ИСТИНА;

MAhipal Singh 28.12.2018 09:18

@MAhipalSingh: Он был там, не работал, поэтому я удалил его. Это только для отправки полноэкранного статуса в javascript

Bhavesh Jariwala 28.12.2018 11:10

В onFullscreen зачем ставить heightX: width, widthX: height,?

Georgios 11.01.2019 00:28

@George: Чтобы изменить размер макета для видео, эта вещь отлично работает в Android. В ios не работает. Используете ли вы какой-либо другой подход для перехода в полноэкранный режим?

Bhavesh Jariwala 11.01.2019 06:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
1 327
0

Другие вопросы по теме