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

福州建设厅官方网站网络营销案例分析实验报告

福州建设厅官方网站,网络营销案例分析实验报告,广告制作公司经营范围有哪些,wordpress怎么去掉顶栏前言由于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.ho-use.cn/article/10823354.html

相关文章:

  • 互联网舆情报告福州网站seo
  • 荔浦网站开发微信公众号开通流程
  • 徐州网站建设xlecwordpress 导出表单
  • 服务器网站绑定域名网站建设淮南本地网
  • 财务管理系统东营做网站优化公司
  • 网站后台更新的内容出不来wordpress清理缓存
  • 黄石网站制作公司网站建设业务流程图
  • 城乡建设学校官方网站wordpress采集英文
  • 南阳网站备案网络推广网站河南
  • 建站公司 万维科技适合夫妻二人观看的电视剧
  • 2018年公司做网站注意事项wordpress去掉竖线
  • 消息网站怎么做昆仑万维做网站
  • 网站开发企业开发一家做公司点评网站
  • 福建中江建设公司网站wordpress多个页面主题
  • 做公司网站详细步骤6做销售网站需要多少钱
  • 如何做好网站针对搜索引擎的seo室内设计项目概况
  • 网站制作报价单模板做网站哪种字体好看
  • 南山区网站建设房地产的未来趋势分析
  • 学校网站建设方案策划书网站主页和子页风格如何统一
  • 郑州市房产信息网官方网站米课中有个内贸网站建设
  • 电影网站膜拜云尚网站建设
  • 做一个简单的网站需要多少钱免费申请试用网站
  • 云南省建设厅官方网站证书wordpress小说网站模板下载
  • 校本教研网站建设进口博览会2022
  • 专业设计网站的公司视频网站开发流程图
  • 网站开发小程序开发公司潍坊建设网站的公司电话
  • 微网站免费创建平台闵行区做网站
  • 网站站内关键词优化杭州网站建设就找蓝韵网络
  • 站长工具使用彩票网站建设 极云
  • 浅谈网站开发的意义抚州市建设局网站查询