如何在 Swift 中实现 JWPlayerTVKit SDK 的同时保持进程运行

问题描述 投票:0回答:1

我是快速和移动开发的新手。我正在为 tvOS 编写一个 React Native 应用程序,我需要快速实现 JWPlayerTVKit SDK,因为react-native-jw-media-player 不支持 tvOS,我已经构建了它的 react native iOS 版本。

我已经设法播放了视频,但是感觉处理播放器的过程停止了,而视频仍在播放。基本上,播放器应该有不出现的控件(播放、暂停、时间滚动等)并且事件 jwplayerIsReady 不会被触发。

我假设在配置播放器后添加 20 秒的延迟后,与视频播放器交互的线程死亡。在 20 秒内,播放器控件可见并且播放器事件按预期响应。 20 秒后,视频继续播放,有声音,但控件变得不可用。

这是我的代码:

bridging-header.h

#import "React/RCTBridgeModule.h"
#import "React/RCTViewManager.h"

JWPlayerViewManager.m

#import "React/RCTViewManager.h"
@interface RCT_EXTERN_MODULE(JWPlayerViewManager, RCTViewManager)
@end

JWPlayerViewManager.swift

import Foundation
import React

@objc(JWPlayerViewManager)
class JWPlayerViewManager: RCTViewManager {
  override func view() -> UIView! {
      let viewController = JWPlayerViewController()
      let containerView = UIViewController()
      containerView.addChild(viewController)
      containerView.view.addSubview(viewController.view)
      return viewController.view
  }
  
  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
}

JWPlayerViewController.swift

import UIKit
import JWPlayerTVKit

class JWPlayerViewController: JWCinematicViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    do {
      JWPlayerKitLicense.setLicenseKey("123123123");
    
      // Last, configure the player
      player.configurePlayer(with: try setUpPlayer())

      // I have managed to see the controls and the ready, visible events to fire after I have added this piece of code
      // note: without self.player.play() the controls and the events do not work either
      DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
        self.player.play()
        print("play")
      }
    } catch {
        // Handle builder failure
        print(error)
    }
  }
  
  /**
   Set up the player with a simple configuration.
   */
  private func setUpPlayer() throws -> JWPlayerConfiguration {
          let videoSource1 = try JWVideoSourceBuilder()
            .file(URL(string:"https://cdn.jwplayer.com/videos/123.mp4")!)
            .label("270p")
            .defaultVideo(false)
            .build()
          
          let videoSource2 = try JWVideoSourceBuilder()
            .file(URL(string:"https://cdn.jwplayer.com/videos/456.mp4")!)
            .label("720p")
            .defaultVideo(true)
            .build()
          
          let mediaTrack = try JWCaptionTrackBuilder()
            .file(URL(string:"https://cdn.jwplayer.com/tracks/123.srt")!)
            .label("eng")
            .defaultTrack(true)
            .build()
          
          // First, build a player item with the stream URL
          let item = try JWPlayerItemBuilder()
              .title("My Title")
              .description("My description.")
              .videoSources([videoSource1, videoSource2])
              .mediaTracks([mediaTrack])
              .build()

          // Second, build a player configuration using the player item
          return try JWPlayerConfigurationBuilder()
              .playlist([item])
              .autostart(false)
              .build()
    }
  
  override func controlBarVisibilityChanged(isVisible: Bool) {
    print("control bar")
    print((isVisible) ? "visible" : "not visible")
  }
  
  override func jwplayer(_ player: JWPlayer, isVisible: Bool) {
      print("isVisible")
  }
  
  // Player is ready
  override func jwplayerIsReady(_ player: JWPlayer) {
      super.jwplayerIsReady(player)
    print("player is ready")
  }

App.tsx

import { Dimensions, requireNativeComponent, View } from 'react-native';

const JWPlayerView = requireNativeComponent('JWPlayerView', null);

const App = () => {
  return (
    <View style={{ flex: 1 }}>
      <JWPlayerView
        style={{
          flex: 1,
          backgroundColor: '#ff0000',
          height: Dimensions.get('window').width,
        }}
      />
    </View>
  );
};

export default App;

非常欢迎任何建议。我来自网络开发背景,所以我可能误解了这里的一些原则。非常感谢您的帮助!

swift xcode react-native jwplayer tvos
1个回答
0
投票

有几件事引起了我的注意。

首先,我不知道您如何(或在哪里)使用

JWPlayerViewController.swift
。在
App.tsx
中我只看到了一个
JWPlayerView
的使用。为了能够进行更多调试,我需要查看视图控制器是如何呈现的。

引起我注意的第二件事是视图控制器包含:

override func view() -> UIView! {
      let viewController = JWPlayerViewController()
      let containerView = UIViewController()
      containerView.addChild(viewController)
      containerView.view.addSubview(viewController.view)
      return viewController.view
}

在上面的方法中,您将

viewController
添加为
containerView
的子视图控制器。在 Apple 世界中,我们称之为“视图控制器包含”。这可能会或可能不会解决您的问题,但这是您在 Apple 世界中正确查看控制器包含的方式:

override func view() -> UIView! {
      let playerViewController = JWPlayerViewController()
      let containerViewController = UIViewController()
      containerViewController.addChild(playerViewController)
      playerViewController.view.frame = containerViewController.frame
      containerView.view.addSubview(playerViewController.view)
      playerViewController.didMove(toParent: containerV)
      return playerViewController.view
}

我将

containerView
重命名为
containerViewController
,因此我们不会将其误解为视图。 我想知道将
playerViewController
放在容器视图中的目的是什么?

第三件事:我建议始终在您在

super
.
中重写的方法中调用
JWPlayerViewController.swift

方法

如果有任何建议解决了您的问题,请告诉我,如果没有,我们可以进一步调查。

© www.soinside.com 2019 - 2024. All rights reserved.