Flutter iOS PlatformView嵌入AVPlayer报override错误及黑屏问题
问题原因
编译错误触发原因
'override' can only be specified on class members 报错根源有两个:
- 你把
viewDidLoad()方法写在了createNativeView函数内部,属于嵌套函数,不属于类的成员方法,无法使用override标记 - 你的
VideoView类继承自NSObject、实现FlutterPlatformView协议,本身不是UIViewController或者UIView的子类,根本不存在viewDidLoad这个可重写的生命周期方法。
黑屏触发原因
你在初始化AVPlayerLayer时直接取self._view.bounds赋值,此时_view刚被创建,还没完成Flutter端传入的布局约束适配,bounds默认是.zero,导致播放器图层尺寸为0,无法正常渲染。另外你没有持有AVPlayer实例,局部变量出作用域后会被系统回收,也会导致播放失败。
修复后的可运行代码
import UIKit import Flutter import AVKit import AVFoundation public class VideoView: NSObject, FlutterPlatformView { // 持有播放器实例,避免被提前释放 private var player: AVPlayer? private var playerLayer: AVPlayerLayer? private let _view: UIView init( frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?, binaryMessenger messenger: FlutterBinaryMessenger? ) { _view = UIView() _view.backgroundColor = .black super.init() createNativeView() } public func view() -> UIView { return _view } // 视图布局更新时自动调整播放器图层尺寸,解决黑屏问题 public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "bounds", let view = object as? UIView, view == _view { playerLayer?.frame = view.bounds } } private func createNativeView(){ // 替换成你的真实视频地址 guard let url = URL(string: "替换为实际可访问的视频直链") else { return } let player = AVPlayer(url: url) let playerLayer = AVPlayerLayer(player: player) playerLayer.videoGravity = .resizeAspect // 初始化先给个初始frame,后续布局更新会自动调整 playerLayer.frame = _view.bounds _view.layer.addSublayer(playerLayer) // 监听_view的bounds变化,实时更新播放器图层尺寸 _view.addObserver(self, forKeyPath: "bounds", options: .new, context: nil) self.player = player self.playerLayer = playerLayer player.play() } deinit { // 移除监听、暂停播放,避免内存泄漏 _view.removeObserver(self, forKeyPath: "bounds") player?.pause() playerLayer?.removeFromSuperlayer() } }
额外注意点
- 不要使用示例里的
"link"占位字符串,必须传入可直接访问的视频直链,HTTP链接需要在iOS的Info.plist里配置ATS权限 - 如果是播放本地视频,需要正确拼接本地文件路径,远程视频要确保设备网络可访问
- 模拟器播放部分编码的视频可能存在兼容问题,建议用真机做最终验证
内容的提问来源于stack exchange,提问作者userName
相关产品推荐
相关产品推荐

