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



我是swift和移动开发的新手。我正在为tvOS编写一个React Native应用程序,我需要在swift中实现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;

欢迎您的任何建议。我来自一个web开发背景,所以也许我在这里误解了一些原则。非常感谢您的帮助!

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

首先,我不知道你如何(或在哪里)使用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世界中正确处理视图控制器的方法:

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在容器视图的目标是什么?

第三件事:我建议总是在您在JWPlayerViewController.swift中覆盖的方法中调用super方法。

请告诉我这些建议是否解决了你的问题,如果没有,我们可以进一步调查。

最新更新