gpt4 book ai didi

ios - 在 ComponentKit 中播放视频

转载 作者:行者123 更新时间:2023-11-29 00:34:10 26 4
gpt4 key购买 nike

我正在尝试使用 ComponentKit 显示视频。我希望它在点击组件时播放。我找到了这个Github Issue ,所以我知道我需要使用 CKStatefulViewComponent 但我不知道处理点击事件的建议方法是使用 ComponentKit。

这是我目前的代码:

#import "CDBVideoPlayerComponent.h"
#import <ComponentKit/ComponentKit.h>

#import <ComponentKit/CKStatefulViewComponentController.h>
#import <AVFoundation/AVFoundation.h>

@interface CDBVideoPlayerComponent()
@property (nonatomic, strong) AVPlayer *player;
@end

@implementation CDBVideoPlayerComponent

+ (instancetype)newWithVideoURL:(NSURL*)url size:(const CKComponentSize &)size {

CKComponentScope scope(self, url);

CDBVideoPlayerComponent *component = [super newWithSize:size accessibility:{}];

component->_player = [[AVPlayer alloc] initWithURL:url];

return component;
}

@end

@interface CDBVideoPlayerComponentController : CKStatefulViewComponentController
- (void)handleTapForPlayer:(AVPlayer *)player;
@end

@implementation CDBVideoPlayerComponentController

+ (UIView *)newStatefulView:(id)context {

UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor darkGrayColor];

AVPlayerLayer *playerLayer = [[AVPlayerLayer alloc] init];
playerLayer.frame = view.bounds;

[view.layer addSublayer:playerLayer];

return view;
}

+ (void)configureStatefulView:(UIView *)statefulView forComponent:(CDBVideoPlayerComponent *)videoComponent {

__block AVPlayerLayer *layer = nil;

for (CALayer *currentLayer in statefulView.layer.sublayers) {

if ([[currentLayer class] isSubclassOfClass:[AVPlayerLayer class]]) {
layer = (AVPlayerLayer*)currentLayer;
break;
}
}

if (layer) {
layer.player = videoComponent.player;
} else {
layer.player = nil;
}
}

- (void)handleTapForPlayer:(AVPlayer *)player {
[player play];
}

@end

最佳答案

所以我找到了一个解决方案,它不是很干净,我不确定这是否是 Facebook 的 ComponentKit 开发人员想要的正确 处理这种情况的方法应该看起来像,但这个解决方案有效:

首先,我们需要创建一个单独的 View 来处理实际的视频演示。这是从Apple's example中提取的

#import "CDBVideoPlayerView.h"

@implementation CDBVideoPlayerView

+ (Class)layerClass {
return [AVPlayerLayer class];
}

- (AVPlayer*)player {
return [(AVPlayerLayer *)[self layer] player];
}

- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
}

@end

然后,组件和 Controller :

#import "CDBVideoPlayerComponent.h"

#import "CDBVideoPlayerView.h"

#import <ComponentKit/CKStatefulViewComponent.h>
#import <ComponentKit/CKStatefulViewComponentController.h>
#import <AVFoundation/AVFoundation.h>

@interface CDBVideoStateComponent : CKStatefulViewComponent
@property (nonatomic, strong) AVPlayer *player;

+ (instancetype)newWithVideoURL:(NSURL*)url size:(const CKComponentSize &)size;

@end

@implementation CDBVideoStateComponent

+ (instancetype)newWithVideoURL:(NSURL*)url size:(const CKComponentSize &)size {

CKComponentScope scope(self, url);

CDBVideoStateComponent *component = [super newWithSize:size accessibility:{}];

component->_player = [[AVPlayer alloc] initWithURL:url];
component->_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

return component;
}

@end

@interface CDBVideoStateComponentController : CKStatefulViewComponentController
@end

@implementation CDBVideoStateComponentController

+ (UIView *)newStatefulView:(id)context {

CDBVideoPlayerView *view = [[CDBVideoPlayerView alloc] init];
return view;
}

+ (void)configureStatefulView:(CDBVideoPlayerView *)statefulView forComponent:(CDBVideoStateComponent *)videoComponent {

statefulView.player = videoComponent.player;
}

@end

@interface CDBVideoPlayerComponent ()
@property (nonatomic, strong) AVPlayer *player;
@end

@implementation CDBVideoPlayerComponent

+ (instancetype)newWithVideoURL:(NSURL*)url size:(const CKComponentSize &)size {

CKComponentScope scope(self, url);

CDBVideoStateComponent *component = [CDBVideoStateComponent newWithVideoURL:url size:size];

CDBVideoPlayerComponent *playerComponent = [super newWithComponent:component
overlay:
[CKButtonComponent
newWithTitles:{}
titleColors:{}
images:{}
backgroundImages:{}
titleFont:{}
selected:NO
enabled:YES
action:@selector(handleButtonPress:)
size:{}
attributes:{}
accessibilityConfiguration:{}
]
];

playerComponent->_player = component.player;

return playerComponent;
}

- (void)handleButtonPress:(id)sender {

if (self.player.status == AVPlayerStatusReadyToPlay) {

if (self.player.timeControlStatus == AVPlayerTimeControlStatusPaused || self.player.timeControlStatus == AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate) {
[self.player play];
} else {
[self.player pause];
}

}
}

@end

编辑

我还发现,我认为这是一个更干净的解决方案,将大部分代码移至 VideoPlayerView

@implementation VideoPlayerView

- (instancetype)init {

if (self = [super init]) {
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]];
}

return self;
}

- (instancetype)initWithFrame:(CGRect)frame {

if (self = [super initWithFrame:frame]) {
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]];
}

return self;
}

- (void)dealloc {
[self removeObserversForPlayer:self.player];
}

+ (Class)layerClass {
return [AVPlayerLayer class];
}

- (AVPlayer*)player {
return [(AVPlayerLayer *)[self layer] player];
}

- (void)setPlayer:(AVPlayer *)player {

[self removeObserversForPlayer:self.player];

[(AVPlayerLayer *)[self layer] setPlayer:player];

[self addObserverForPlayer:player];
}

- (void)addObserverForPlayer:(AVPlayer *)player {
if (player) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
}
}

- (void)removeObserversForPlayer:(AVPlayer *)player {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
}

- (void)itemDidFinishPlaying:(NSNotification *)notification {
[self.player seekToTime:kCMTimeZero];
[self.player pause];
}

- (void)handleTap:(id)sender {

if (self.player.status == AVPlayerStatusReadyToPlay) {

if (self.player.timeControlStatus == AVPlayerTimeControlStatusPaused || self.player.timeControlStatus == AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate) {
[self.player play];
} else {
[self.player pause];
}

}
}

@end

更新的组件:

#import "VideoPlayerComponent.h"

#import "VideoPlayerView.h"

#import <ComponentKit/CKStatefulViewComponentController.h>
#import <AVFoundation/AVFoundation.h>
#import <ComponentKit/ComponentKit.h>

@interface VideoPlayerComponent ()
@property (nonatomic, strong) AVPlayer *player;

@end

@implementation VideoPlayerComponent

+ (instancetype)newWithVideoURL:(NSURL*)url size:(const CKComponentSize &)size {

CKComponentScope scope(self, url);

VideoPlayerComponent *component = [super newWithSize:size accessibility:{}];

component->_player = [[AVPlayer alloc] initWithURL:url];
component->_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

return component;
}

@end

@interface VideoPlayerComponentController : CKStatefulViewComponentController
@end

@implementation VideoPlayerComponentController

+ (UIView *)newStatefulView:(id)context {

VideoPlayerView *view = [[VideoPlayerView alloc] init];
view.backgroundColor = [UIColor grayColor];
return view;
}

+ (void)configureStatefulView:(VideoPlayerView *)statefulView forComponent:(VideoPlayerComponent *)videoComponent {

statefulView.player = videoComponent.player;
}

@end

关于ios - 在 ComponentKit 中播放视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41030305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com