视图中的 AVPlayer
AVPlayer In View
我正在尝试在视图控制器上使用视频,但不是全屏显示,只有足够的空间用于顶部的标签和底部的按钮,这可能吗?如果不是,我怎么能拥有它,所以如果用户跳过视频或它完成它会转到某个 viewController?
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *videoURL = [[NSBundle mainBundle]URLForResource:@"TTPlaneHits" withExtension:@"mp4"];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
playerLayer.frame = CGRectMake(0, 21, self.view.frame.size.width, self.view.frame.size.height - 45 - 21);
[self.view.layer addSublayer:playerLayer];
AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
controller.player = player;
[player play];
[self.view addSubview:controller.view];
controller.view.frame = self.view.frame;
如果您只使用 AVPlayerLayer
并相应地设置它的框架 属性(就像您对任何 CALayer
所做的那样),这可能是最简单的。这是一个例子:
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//labelHeight is the height of your top label
//buttonHeight is the height of your bottom button
playerLayer.frame = CGRectMake(0, labelHeight, self.view.frame.size.width, self.view.frame.size.height - labelHeight - buttonHeight);
[self.view.layer addSublayer:playerLayer];
至于在视频结束时导航到另一个 viewController,您需要注册 NSNotification
的回调。 @random 很好地解释了如何做到这一点 here.
来自 Apple 的文档:
You can display the visual content of items played by an instance of
AVPlayer in a CoreAnimation layer of class AVPlayerLayer; to
synchronize real-time playback with other CoreAnimation layers, you
can use AVSynchronizedLayer. You cannot use an instance of
AVVideoCompositionCoreAnimationTool with an AVPlayer object; for
offline rendering you should instead use AVAssetExportSession.
试试这个:
(playerView 只是放置在故事板中的 UIView 的 IBOutlet)
-(void)viewDidLoad {
[super viewDidLoad];
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"]];
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];
AVPlayer *player = [AVPlayer playerWithPlayerItem:item];
CALayer *superlayer = self.playerView.layer;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
[playerLayer setFrame:self.playerView.bounds];
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[superlayer addSublayer:playerLayer];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
[player seekToTime:kCMTimeZero];
[player play];
}
-(void)playerDidFinishPlaying:(NSNotification *)notification {
[self performSegueWithIdentifier:@"YourIdentifier" sender:self];
}
Swift版本
func addVideoPlayer(videoUrl: URL, to view: UIView) {
let player = AVPlayer(url: videoUrl)
let layer: AVPlayerLayer = AVPlayerLayer(player: player)
layer.backgroundColor = UIColor.white.cgColor
layer.frame = view.bounds
layer.videoGravity = .resizeAspectFill
view.layer.sublayers?
.filter { [=10=] is AVPlayerLayer }
.forEach { [=10=].removeFromSuperlayer() }
view.layer.addSublayer(layer)
}
我正在尝试在视图控制器上使用视频,但不是全屏显示,只有足够的空间用于顶部的标签和底部的按钮,这可能吗?如果不是,我怎么能拥有它,所以如果用户跳过视频或它完成它会转到某个 viewController?
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *videoURL = [[NSBundle mainBundle]URLForResource:@"TTPlaneHits" withExtension:@"mp4"];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
playerLayer.frame = CGRectMake(0, 21, self.view.frame.size.width, self.view.frame.size.height - 45 - 21);
[self.view.layer addSublayer:playerLayer];
AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
controller.player = player;
[player play];
[self.view addSubview:controller.view];
controller.view.frame = self.view.frame;
如果您只使用 AVPlayerLayer
并相应地设置它的框架 属性(就像您对任何 CALayer
所做的那样),这可能是最简单的。这是一个例子:
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//labelHeight is the height of your top label
//buttonHeight is the height of your bottom button
playerLayer.frame = CGRectMake(0, labelHeight, self.view.frame.size.width, self.view.frame.size.height - labelHeight - buttonHeight);
[self.view.layer addSublayer:playerLayer];
至于在视频结束时导航到另一个 viewController,您需要注册 NSNotification
的回调。 @random 很好地解释了如何做到这一点 here.
来自 Apple 的文档:
You can display the visual content of items played by an instance of AVPlayer in a CoreAnimation layer of class AVPlayerLayer; to synchronize real-time playback with other CoreAnimation layers, you can use AVSynchronizedLayer. You cannot use an instance of AVVideoCompositionCoreAnimationTool with an AVPlayer object; for offline rendering you should instead use AVAssetExportSession.
试试这个:
(playerView 只是放置在故事板中的 UIView 的 IBOutlet)
-(void)viewDidLoad {
[super viewDidLoad];
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"]];
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoURL];
AVPlayer *player = [AVPlayer playerWithPlayerItem:item];
CALayer *superlayer = self.playerView.layer;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
[playerLayer setFrame:self.playerView.bounds];
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[superlayer addSublayer:playerLayer];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
[player seekToTime:kCMTimeZero];
[player play];
}
-(void)playerDidFinishPlaying:(NSNotification *)notification {
[self performSegueWithIdentifier:@"YourIdentifier" sender:self];
}
Swift版本
func addVideoPlayer(videoUrl: URL, to view: UIView) {
let player = AVPlayer(url: videoUrl)
let layer: AVPlayerLayer = AVPlayerLayer(player: player)
layer.backgroundColor = UIColor.white.cgColor
layer.frame = view.bounds
layer.videoGravity = .resizeAspectFill
view.layer.sublayers?
.filter { [=10=] is AVPlayerLayer }
.forEach { [=10=].removeFromSuperlayer() }
view.layer.addSublayer(layer)
}