当前位置: 首页 > news >正文

福州建设厅官方网站敬请期待图片

福州建设厅官方网站,敬请期待图片,十个app制作网站,想做个网站推广前言由于Flutter项目中需要使用到播放器功能#xff0c;因此对flutter中各种播放器解决方案进行了一番研究和比对#xff0c;最后决定还是自己通过Plugin的方法去引用原生播放器符合自己的需求#xff0c;本篇文章会对各种解决方案做一个简单的比较#xff0c;以及讲解一下… 前言由于Flutter项目中需要使用到播放器功能因此对flutter中各种播放器解决方案进行了一番研究和比对最后决定还是自己通过Plugin的方法去引用原生播放器符合自己的需求本篇文章会对各种解决方案做一个简单的比较以及讲解一下发Flutter3.0中ios引用原生view的步骤和逻辑方便大家遇到相同问题时可以进行一个参考。 video_playervideo_playerflutter官方出品。 优点集成速度快易上手使用简单同时支持Androidiosweb 缺点ui丑功能简单可定制化差不支持rtmp等协议直播 适用对播放器要求不高不需要直播只要视频能播放出来就可以的用户 better_playerbetter_player国外大神在video_player的基础之上二次开发而来对video_player进行了各种优化并添加了非常多的实用功能。 优点同video_player且比video_player更强大一点 缺点依然是可定制化差不支持rtmp等直播格式 适用对视频播放器稍微有要求比如视频格式播放速度缓存等功能又不想自己动手去写原生插件对ui定制化要求也不高的用户 fijkplayerfijkplayer基于ijkplayer是对 ijkplayer 的 Flutter 封装支持安卓和ios 优缺点做过安卓和ios原生的对ijk应该都非常熟悉了这里就不做过多说明了 fijkplayer支持各种视频格式包括rtmp等协议直播支持各种常用功能支持定制化UI具体可以去它的官网查看文档说明 适用对播放器要求稍高需要简单定制化播放器ui需要支持直播的用户 这里说一些个人的使用体验因为我的项目需要支持rtmp直播并且对ui定制化要求较高所以放弃了官方的video_player优先选择了fijkplayer但实际体验上不太尽如人意。虽然支持ui定制但想要达到自己产品的ui设计还需要费上很大一番功夫。并且该项目作者有一年多未更新维护了后续是否会继续更新维护解决bug不得而知。另外我在播放rtmp时播放失败不知何故不过我并没深究原因因为此时我已经动了自己动手引用双端原生播放器的念头了 IOS制作并引用原生View步骤1使用Xcode运行项目 双击flutter项目/ios目录下的Runner.xcworkspaceXcode会自动打开项目 2检验项目 直接运行查看是否有报错信息 如果你已经在pubspec.yaml中使用了大量的第三方插件此时运行可能会报错xxx Module not Found那么你需要在打开终端并cd到ios目录执行 pod install 一般情况下都可以解决问题 3创建VideoViewPlugin实现FlutterPlugin协议 import Flutter import UIKitclass VideoViewPlugin: NSObject, FlutterPlugin {objc static func register(with registrar: FlutterPluginRegistrar) {registrar.register(VideoViewFactory(registrar: registrar), withId: plugins.my_video_player/view)}}由于FlutterPlugin是OC写的所以在Swift中实现OC协议前面需要加上NSObject。通过FlutterPluginRegistrar的registrar注册PlatformViewFactory。 plugins.my_video_player/view即为该插件的id在flutter中引用原生view时需要写入并且安卓ios和flutter三方都要保持一致 4创建VideoViewFactory实现FlutterPlatformViewFactory协议 import UIKit import Flutterclass VideoViewFactory:NSObject, FlutterPlatformViewFactory {private var registrar:FlutterPluginRegistrarinit(registrar: FlutterPluginRegistrar) {self.registrarregistrarsuper.init()}//create方法是在flutter中该widget加载显示出来时才执行//所以自定flutter中使用原生View时传递的参数在create执行后且获取到参数后再创建channelfunc create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) - FlutterPlatformView {let idargs as! Intreturn VideoViewPlayer(id: id, registrar: registrar)}//这个方法一定要写否则接受不到flutter的传参func createArgsCodec() - FlutterMessageCodec NSObjectProtocol {return FlutterStandardMessageCodec.sharedInstance()} }注意createArgsCodec()一定要重写否则无法接收到flutter在使用view时传过来的参数create方法中的arguments即为传递的参数create方法返回PlatformViewUIView 5创建VideoViewPlayer实现FlutterPlatformView协议 import UIKit import Flutterclass VideoViewPlayer: NSObject,FlutterPlatformView {//懒加载private var videoView:UIView{let videoViewUIView()return videoView}()//主要就是在这里返回原生viewfunc view() - UIView {return videoView}}6在AppDelegate.swift中注册插件 import UIKit import FlutterUIApplicationMain objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) - Bool {GeneratedPluginRegistrant.register(with: self)//插件名自定义if let registerself.registrar(forPlugin: VideoViewPlugin){VideoViewPlugin.register(with: register)}return super.application(application, didFinishLaunchingWithOptions: launchOptions)} } 这里其实需要两步 let registerself.registrar(forPlugin: VideoViewPlugin) VideoViewPlugin.register(with: register)注意registrar和register是不一样的 7在flutter中引用VideoView 自定义WidgetMyVideoPlayer import package:flutter/foundation.dart; import package:flutter/material.dart; import package:flutter/services.dart;class MyVideoPlayer extends StatefulWidget {final int id;const MyVideoPlayer({super.key,required this.id,});overrideStateStatefulWidget createState() _VideoPlayerState(); }class _VideoPlayerState extends StateMyVideoPlayer {overridevoid initState() {super.initState();}overrideWidget build(BuildContext context) {if (defaultTargetPlatform TargetPlatform.android) {return AndroidView(viewType: plugins.my_video_player/view,creationParams: widget.id, //传递到原生插件的参数任意类型creationParamsCodec: const StandardMessageCodec(),);} else {return UiKitView(viewType: plugins.my_video_player/view,creationParams: widget.id, //传递到原生插件的参数任意类型creationParamsCodec: const StandardMessageCodec(),);}}} viewType即上面VideoViewPlugin类中注册的插件idplugins.my_video_player/view安卓ios和flutter保持一致 引用MyVideoPlayer SizedBox(height: 200,child: MyVideoPlayer(id: 0))这里可以看到我给原生View传了一个id需要唯一我用的是时间戳的参数这个是为了后面在创建MethodChannel时加以区分在同时使用了多个MyVideoPlayer时不会相互影响 此时我们就可以来测试一下引用是否成功了为了效果明显我们可以在VideoViewPlayer.swift中为UIView添加一个背景色 private var videoView:UIView{let videoViewUIView()videoView.backgroundColorUIColor.redreturn videoView}()运行效果 如上图说明原生View已经引用成功了不过本篇文章的目的不只是讲解如何引用原生View我们的目标是如何引用原生播放器 如果你本身是ios开发者或者开发过ios项目并且在所开发的项目中使用过第三方的播放器那么你其实可以直接将你所使用的播放器库引入到本项目中直接使用无非就是在VideoViewPlayer.swift中初始化并配置一些参数最后封装进返回的videoView中 如果你未开发过ios项目或者没使用过第三方的播放器那么你就可以在github上自行搜索star数量高的ios开源播放器项目了。由于我使用的是Swift语言所以我优先查找了用Swift写的播放器但查找后发现star量都太低了而且还必须要支持rtmp播放最后还是选择了OC写的star量最高的ZFPlayer 引入开源播放器ZFPlayer1安装Podfile中添加 pod ZFPlayer, ~ 4.0pod ZFPlayer/ControlView, ~ 4.0pod ZFPlayer/AVPlayer, ~ 4.0pod ZFPlayer/ijkplayer, ~ 4.0由于AVPlayer本身不支持直播所以还需要引入ZFPlayer/ijkplayer来支持直播功能 执行pod intall由于github总是间歇性无法访问如果提示SSL超时等问题可以多试几遍 2参考ZFPlayer文档将ZFPlayer封装进UIViewviewPlayer返回给Flutter VideoViewPlayer中 //zfplayer控制器private var player:ZFPlayerController ZFPlayerController()//播放器进度控制条UIViewprivate var playerControlViewZFPlayerControlView()//AVPlayer管理器private var avPlayerManager:ZFAVPlayerManager?//IjkPlayer管理器private var ijkPlayerManager:ZFIJKPlayerManager?init(id:Int,registrar:FlutterPluginRegistrar) {super.init()//为player设置进度控制条player.controlViewplayerControlView//为player设置containerViewplayer.containerViewvideoView}此时其实就可以播放视频了传入视频Url //可以根据视频类型选择使用AVPlayer还是IjkPlayer播放 //我这里点播使用AVPlayer直播使用IjkPlayer自己可以根据自身项目情况选择 if url.starts(with: http){avPlayerManagerZFAVPlayerManager()avPlayerManager!.assetURLURL(string: url)player.currentPlayerManageravPlayerManager!playerControlView.portraitControlView.slider.isHiddenfalseplayerControlView.portraitControlView.currentTimeLabel.isHiddenfalseplayerControlView.portraitControlView.totalTimeLabel.isHiddenfalse}if url.starts(with: rtmp){ijkPlayerManagerZFIJKPlayerManager()ijkPlayerManager!.assetURLURL(string: url)player.currentPlayerManagerijkPlayerManager!playerControlView.portraitControlView.slider.isHiddentrueplayerControlView.portraitControlView.currentTimeLabel.isHiddentrueplayerControlView.portraitControlView.totalTimeLabel.isHiddentrue}if avPlayerManager ! nil {avPlayerManager!.play()}if ijkPlayerManager ! nil {ijkPlayerManager!.play()}但这样无法动态从flutter传入url啊所以我们还需要flutter和ios通信即使用MethodChannel 3IOS端创建FlutterMethodChannel //这里就用到了从flutter传入的idfunc initMethodChannel(id:Int,registrar:FlutterPluginRegistrar) {let channel FlutterMethodChannel(name: my_video_player_\(id), binaryMessenger: registrar.messenger())channel.setMethodCallHandler(handleMethod)}//接收flutter发来的消息func handleMethod(call: FlutterMethodCall, result: FlutterResult){switch call.method {case setUrl:let url: Stringcall.arguments as! StringinitPlayer(url: url)breakcase start:play()breakcase pause:pause()breakcase release:stop()breakdefault:result(FlutterMethodNotImplemented)break}}VideoViewPlayer完整代码如下 import UIKit import Flutter import ZFPlayerclass VideoViewPlayer: NSObject,FlutterPlatformView {private var videoView:UIView{let videoViewUIView()return videoView}()private var player:ZFPlayerController ZFPlayerController()private var playerControlViewZFPlayerControlView()private var avPlayerManager:ZFAVPlayerManager?private var ijkPlayerManager:ZFIJKPlayerManager?init(id:Int,registrar:FlutterPluginRegistrar) {super.init()player.controlViewplayerControlViewinitMethodChannel(id: id, registrar: registrar)}func view() - UIView {return videoView}}// MARK:- 播放器初始化及控制 extension VideoViewPlayer{//初始化播放器func initPlayer(url:String){player.containerViewvideoViewif avPlayerManager ! nil {avPlayerManager!.pause()avPlayerManagernil}if ijkPlayerManager ! nil {ijkPlayerManager!.pause()ijkPlayerManagernil}if url.starts(with: http){avPlayerManagerZFAVPlayerManager()avPlayerManager!.assetURLURL(string: url)player.currentPlayerManageravPlayerManager!playerControlView.portraitControlView.slider.isHiddenfalseplayerControlView.portraitControlView.currentTimeLabel.isHiddenfalseplayerControlView.portraitControlView.totalTimeLabel.isHiddenfalse}if url.starts(with: rtmp){ijkPlayerManagerZFIJKPlayerManager()ijkPlayerManager!.assetURLURL(string: url)player.currentPlayerManagerijkPlayerManager!playerControlView.portraitControlView.slider.isHiddentrueplayerControlView.portraitControlView.currentTimeLabel.isHiddentrueplayerControlView.portraitControlView.totalTimeLabel.isHiddentrue}}func play(){if avPlayerManager ! nil {avPlayerManager!.play()}if ijkPlayerManager ! nil {ijkPlayerManager!.play()}}func pause(){if avPlayerManager ! nil {avPlayerManager!.pause()}if ijkPlayerManager ! nil {ijkPlayerManager!.pause()}}func stop(){pause()player.stop()} }// MARK:- flutter消息通道处理 extension VideoViewPlayer{func initMethodChannel(id:Int,registrar:FlutterPluginRegistrar) {let channel FlutterMethodChannel(name: my_video_player_\(id), binaryMessenger: registrar.messenger())channel.setMethodCallHandler(handleMethod)}//接收flutter发来的消息func handleMethod(call: FlutterMethodCall, result: FlutterResult){switch call.method {case setUrl:let url: Stringcall.arguments as! StringinitPlayer(url: url)breakcase start:play()breakcase pause:pause()breakcase release:stop()breakdefault:result(FlutterMethodNotImplemented)break}} }4flutter端创建MethodChannel init() {methodChannel MethodChannel(my_video_player_$id);methodChannel.setMethodCallHandler((call) flutterMethod(call));}Futurevoid setUrl(String url) async {return methodChannel.invokeMethod(setUrl, url);}Futurevoid start() async {return methodChannel.invokeMethod(start);}...flutter中调用setUrl后再调用start方法即可播放了 我这里给flutter端的MethodChanel封装为了一个Controller import package:flutter/services.dart; import package:kjjl_flutter/components/loading.dart; import package:kjjl_flutter/utils/log_util.dart;class VideoViewController {late MethodChannel methodChannel;int id;VideoViewController({required this.id});init() {methodChannel MethodChannel(my_video_player_$id);methodChannel.setMethodCallHandler((call) flutterMethod(call));}Futurevoid setUrl(String url) async {return methodChannel.invokeMethod(setUrl, url);}Futurevoid start() async {return methodChannel.invokeMethod(start);}Futurevoid pause() async {return methodChannel.invokeMethod(pause);}Futurevoid release() async {return methodChannel.invokeMethod(release);}Futurevoid stopFullScreen() async {return methodChannel.invokeMethod(stopFullScreen);}Futuredynamic flutterMethod(MethodCall methodCall) async {switch (methodCall.method) {}} } 在State中使用时的部分代码 SizedBox(height: videoHeight,child: currentVideo ! null videoViewController ! null? MyVideoPlayer(id: videoViewController!.id): SizedBox(),)...VideoModel? currentVideo; VideoViewController? videoViewController;//页面销毁时释放播放器 override void dispose() {if (videoViewController ! null) videoViewController!.release();super.dispose(); }//点击播放时执行 play(VideoModel video) {if (videoViewController ! null) {if (currentVideo ! null currentVideo!.id video.id) return;setState(() {currentVideo video;videoViewController!.release();startPlay(video);});} else {setState(() {currentVideo video;videoViewController VideoViewController(id: DateTime.now().millisecondsSinceEpoch);videoViewController!.init();//延时500ms执行是为了防止播放器还未初始化完成就调用了播放导致首次播放失败Future.delayed(const Duration(milliseconds: 500), () {startPlay(video);});});}}startPlay(VideoModel video){videoViewController!.setUrl(video.mobileUrl);videoViewController!.start(); }效果图 直播 录播 下一篇Flutter3引用原生播放器-Android篇
http://www.hkea.cn/news/14572709/

相关文章:

  • 做自己的游戏网站做初中题赚钱的网站
  • wordpress vue网站自建网站 好处
  • 南宁网站建设怎么样义乌小程序装修公司
  • 食品网站建设策划书淘宝网站c 设计怎么做的
  • 模块化网站建设 局域网移动前端开发需要学什么
  • 手机测评做视频网站cosy WordPress
  • 苏州网站的建设wordpress js加载慢
  • 网站底部备案代码你买域名我送网站
  • 网站jianshe津南区网络推广公司
  • 做玩具订制网站好处专门设计的网站
  • 做网站搞流量企业站点
  • 外贸网站推软件wap网站
  • 上海哪个网站专门做宝宝宴的WordPress页首
  • 石家庄电商网站排名wordpress文章存在哪个数据库中
  • 丝绸之路网站建设意义河北省水利建设市场网站
  • 哪家公司设计网站好php做网站会遇到的问题
  • 网上做衣服的网站有哪些wordpress关键字回复
  • 网站设计好 如何将本地网站发布wordpress会员多语言
  • 用例图在线制作网站建设电子商务网站的规划书
  • 手机怎么做网站免费的中国建设银行网上银行个人登录官方网站
  • 济南定制网站建设公司企业网站备案是什么意思
  • 网站开发和软件开发工作网站开发定制企业
  • 网站建站代理wordpress百度云伪静态
  • 做旅游宣传图的网站有哪些centos 安装 wordpress
  • 模板型网站建设有关做洁净工程的企业网站
  • 做淘宝的网站有哪些焊枪公司网站怎么做
  • 怎么可以做网站的网站福州 网站备案
  • 企业建设营销型网站步骤足彩网站怎样做推广
  • 手机网站页面设计wordpress 编辑index
  • 自己做的网站网站搜索免费 wordpress