嵌入其他ViewController的AVPlayerViewController控件不显示问题(Swift/OC)
问题描述
我尝试在iOS App中实现无需单独启动AVPlayerViewController的简单播放/暂停/停止音频功能。根据资料,使用Apple的AVPlayerViewController是获取预制控件的唯一方式,Apple推荐将其嵌入其他ViewController的视图中。目前音频可正常播放,但控件无法显示。
Objective-C代码
#import <AVFoundation/AVFoundation.h> #import <UIKit/UIKit.h> #import <AVKit/AVKit.h> /*in header file: @property (nonatomic, strong) IBOutlet AVPlayerViewController *pVC; */ NSString* audiosurl = @"https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Sevish_-__nbsp_.mp3"; NSURL * audioURL = [NSURL URLWithString:audiosurl]; self.pVC = [AVPlayerViewController new]; self.pVC.view.bounds= self.videoView.bounds; AVPlayer *avplayer = [AVPlayer playerWithURL:audioURL]; // AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:avplayer]; // playerLayer.frame = self.videoView.bounds; // [self.videoView.layer addSublayer:playerLayer]; self.pVC.player = avplayer; self.pVC.showsPlaybackControls = YES; self.pVC.videoGravity = AVLayerVideoGravityResizeAspectFill; self.pVC.view.backgroundColor = [UIColor clearColor]; [self.videoView addSubview:self.pVC.view]; [avplayer play];
Swift代码
let videoURL = URL(string: "https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Sevish_-__nbsp_.mp3") let player = AVPlayer(url: videoUrl) let playerViewController: AVPlayerViewController! playerViewController = AVPlayerViewController() playerViewController.view.frame = YOUR_FRAME_OR_EMBED_IN_STORYBOARD playerViewController.player = player playerViewController.showsPlaybackControls = true playerViewController.videoGravity = .resizeAspectFill self.videoView.addSubview(playerViewController.view) playerViewController.player!.play()
我怀疑问题可能出在背景颜色、视图层级顺序、是否应该使用图层等方面,请问是什么原因导致控件无法显示?
补充:当前显示效果为一片空白
问题原因与解决方案
核心原因:AVPlayerViewController的预制控件仅适配视频场景
AVPlayerViewController的原生播放控件是为视频播放设计的,当播放纯音频资源时,系统默认不会加载任何控件——因为没有视频画面作为控件的承载容器,即使手动设置showsPlaybackControls = YES也不会生效。
可行解决方案
你有两种明确的解决方向:
自定义音频播放控件
放弃依赖AVPlayerViewController的预制控件,直接基于AVPlayer实现基础播放控件:- 在你的
videoView上添加自定义的UIButton(播放/暂停/停止) - 通过AVPlayer的
play()、pause()方法控制播放状态 - 监听AVPlayer的
rate属性或AVPlayerItemDidPlayToEndTimeNotification通知,实时更新控件的显示状态
- 在你的
给音频添加空白视频轨道(曲线适配)
如果一定要用AVPlayerViewController的预制控件,可以给音频文件合成一个空白视频轨道,让系统识别为视频资源,从而触发控件显示:- 使用AVFoundation的AVAssetExportSession,将空白视频片段与目标音频合并
- 或者提前准备一个1px×1px的空白视频文件,和音频合并后再传入AVPlayer播放
额外注意点
- 你代码中直接将AVPlayerViewController的view添加为子视图的方式是正确的,但要确保
videoView的frame设置正确,且没有被其他视图遮挡 - 不要用AVPlayerLayer替代AVPlayerViewController的view,这种方式仅能显示视频画面(纯音频场景下为黑屏),同样不会加载播放控件
内容的提问来源于stack exchange,提问作者user6631314
相关产品推荐
相关产品推荐

