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

免费网站空间有什么用软件开发工程师

免费网站空间有什么用,软件开发工程师,专门做问卷调查的一个网站,wordpress 菜单 移动端flutter开发实战-ijkplayer视频播放器功能 使用better_player播放器进行播放视频时候#xff0c;在Android上会出现解码失败的问题#xff0c;better_player使用的是video_player#xff0c;video_player很多视频无法解码。最终采用ijkplayer播放器插件#xff0c;在flutt…flutter开发实战-ijkplayer视频播放器功能 使用better_player播放器进行播放视频时候在Android上会出现解码失败的问题better_player使用的是video_playervideo_player很多视频无法解码。最终采用ijkplayer播放器插件在flutter上使用fijkplayer插件。 一、引入fijkplayer 在使用fijkplayer前可以先看下https://fijkplayer.befovy.com/docs/zh/fijkplayer-api.html 在工程的pubspec.yaml中引入插件 fijkplayer: ^0.11.0 fijkPlayer 就是对 native C 层 ijkplayer 的一个 dart 包装接口都保持一致。 FijkPlayer 处理所有播放相关的工作实际工作都是由 native C 层 ijkplayer 完成包含检查 dataSource 中的媒体信息打开解码器和解码线程、打开音频输出设备、将解码后数据输出给音频设备或显示设备。 二、使用fijkplayer 2.1、IJKVideoPlayerController控制常用操作 使用fijkplayer这里创建了IJKVideoPlayer来嵌套一下FijkView使用IJKVideoPlayerController来控制常用功能操作 IJKVideoPlayerController如下 import dart:async;class IJKVideoPlayerController {FutureOr Function()? stop;FutureOr Function()? pause;FutureOr Function()? play;FutureOr Function(int msec)? seekTo;FutureOr Function(double volume)? setVolume;FutureOr Function(double speed)? setSpeed;FutureOr Function(int loopCount)? setLoop;FutureOr Function()? isPlaying; } IJKVideoPlayerController来控制停止、暂停、播放、seek、设置音量、设置播放速率、设置循环次数、获取是否在播放中等。 播放视频 void play() {if (videoPlayerController.play ! null) {videoPlayerController.play!.call();}} 暂停视频播放 void pause() {if (videoPlayerController.pause ! null) {videoPlayerController.pause!.call();}} 停止视频播放 void stop() {if (videoPlayerController.stop ! null) {videoPlayerController.stop!.call();}} seek指定位置 void seekTo(int msec) {if (videoPlayerController.seekTo ! null) {videoPlayerController.seekTo!.call(msec);}} 设置音量 void setVolume(double volume) {if (videoPlayerController.setVolume ! null) {videoPlayerController.setVolume!.call(volume);}} 设置播放速率 void setSpeed(double speed) {if (videoPlayerController.setSpeed ! null) {videoPlayerController.setSpeed!.call(speed);}} 设置循环次数 void setLoop(int loopCount) {if (videoPlayerController.setLoop ! null) {videoPlayerController.setLoop!.call(loopCount);}} 获取是否播放中 Futurebool? isPlaying() async {if (videoPlayerController.isPlaying ! null) {bool videoIsPlaying await videoPlayerController.isPlaying!.call();return videoIsPlaying;}return Future.value(null);} 2.2、在ijkplayer设置source使用FijkPlayer 在设置播放器的时候需要设置source类型。fijkplayer提供了两种方式一种是本地工程文件、一种是网络视频地址。 设置网络视频源 /// usage/// autoPlay 为 true 时等同于连续调用 setDataSource、prepareAsync、startfplayer.setDataSource(http://samplevideo.com/sample.flv, autoPlay: true); 设置本地资源作为播放源 /// pubspec.yml 中需要指定assets 内容/// assets:/// - assets/butterfly.mp4////// scheme 是 asset, :// 是 scheme 分隔符 / 是路径起始符号fplayer.setDataSource(asset:///assets/butterfly.mp4, autoPlay: true); 在setDataSource还有autoPlay自动播放showCover是否显示视频封面视频默认获取第一帧作为视频封面 2.3、FijkView显示视频的控件Widget 在fijkplayer中使用FijkView来显示视频。 FijkView({required this.player,this.width,this.height,this.fit FijkFit.contain,this.fsFit FijkFit.contain,this.panelBuilder defaultFijkPanelBuilder,this.color const Color(0xFF607D8B),this.cover,this.fs true,this.onDispose,}); 可以设置显示fit、全屏的fit、背景颜色color、封面图设置之后会显示在视频播放的上面、是否全屏等。 在这里我们如果需要自定义样式可以替换掉panelBuilder。 2.4、自定义控件IJKVideoPanel 在这里我们如果需要自定义样式可以替换掉panelBuilder。我们自定义一个IJKVideoPanel这个大部分代码来源default这里调整了部分样式。 IJKVideoPanel完整代码如下 import dart:async; import dart:math;import package:fijkplayer/fijkplayer.dart; import package:flutter/material.dart;class IJKVideoPanel extends StatefulWidget {const IJKVideoPanel({super.key,required this.player,required this.buildContext,required this.viewSize,required this.texturePos,});final FijkPlayer player;final BuildContext buildContext;final Size viewSize;final Rect texturePos;overrideStateIJKVideoPanel createState() _IJKVideoPanelState(); }class _IJKVideoPanelState extends StateIJKVideoPanel {FijkPlayer get player widget.player;Duration _duration Duration();Duration _currentPos Duration();Duration _bufferPos Duration();bool _playing false;bool _prepared false;String? _exception;// bool _buffering false;double _seekPos -1.0;StreamSubscription? _currentPosSubs;StreamSubscription? _bufferPosSubs;//StreamSubscription _bufferingSubs;Timer? _hideTimer;bool _hideStuff true;double _volume 1.0;final barHeight 40.0;overridevoid initState() {super.initState();_duration player.value.duration;_currentPos player.currentPos;_bufferPos player.bufferPos;_prepared player.state.index FijkState.prepared.index;_playing player.state FijkState.started;_exception player.value.exception.message;// _buffering player.isBuffering;player.addListener(_playerValueChanged);_currentPosSubs player.onCurrentPosUpdate.listen((v) {setState(() {_currentPos v;});});_bufferPosSubs player.onBufferPosUpdate.listen((v) {setState(() {_bufferPos v;});});}void _playerValueChanged() {FijkValue value player.value;if (value.duration ! _duration) {setState(() {_duration value.duration;});}bool playing (value.state FijkState.started);bool prepared value.prepared;String? exception value.exception.message;if (playing ! _playing ||prepared ! _prepared ||exception ! _exception) {setState(() {_playing playing;_prepared prepared;_exception exception;});}}void _playOrPause() {if (_playing true) {player.pause();} else {player.start();}}overridevoid dispose() {super.dispose();_hideTimer?.cancel();player.removeListener(_playerValueChanged);_currentPosSubs?.cancel();_bufferPosSubs?.cancel();}void _startHideTimer() {_hideTimer?.cancel();_hideTimer Timer(const Duration(seconds: 3), () {setState(() {_hideStuff true;});});}void _cancelAndRestartTimer() {if (_hideStuff true) {_startHideTimer();}setState(() {_hideStuff !_hideStuff;});}Widget _buildVolumeButton() {IconData iconData;if (_volume 0) {iconData Icons.volume_off;} else {iconData Icons.volume_up;}return IconButton(icon: Icon(iconData, color: Colors.white),padding: EdgeInsets.only(left: 10.0, right: 10.0),onPressed: () {setState(() {_volume _volume 0 ? 0.0 : 1.0;player.setVolume(_volume);});},);}AnimatedOpacity _buildBottomBar(BuildContext context) {double duration _duration.inMilliseconds.toDouble();double currentValue _seekPos 0 ? _seekPos : _currentPos.inMilliseconds.toDouble();currentValue min(currentValue, duration);currentValue max(currentValue, 0);return AnimatedOpacity(opacity: _hideStuff ? 0.0 : 0.8,duration: Duration(milliseconds: 400),child: Container(height: barHeight,decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.transparent, Colors.black45],begin: Alignment.topCenter,end: Alignment.bottomCenter,),),child: Row(children: Widget[_buildVolumeButton(),Padding(padding: EdgeInsets.only(right: 5.0, left: 5),child: Text(${_duration2String(_currentPos)},style: TextStyle(fontSize: 14.0, color: Colors.white),),),_duration.inMilliseconds 0? Expanded(child: Center()): Expanded(child: Padding(padding: EdgeInsets.only(right: 0, left: 0),child: FijkSlider(value: currentValue,cacheValue: _bufferPos.inMilliseconds.toDouble(),min: 0.0,max: duration,onChanged: (v) {_startHideTimer();setState(() {_seekPos v;});},onChangeEnd: (v) {setState(() {player.seekTo(v.toInt());print(seek to $v);_currentPos Duration(milliseconds: _seekPos.toInt());_seekPos -1;});},),),),// duration / position_duration.inMilliseconds 0? Container(child: const Text(LIVE)): Padding(padding: EdgeInsets.only(right: 5.0, left: 5),child: Text(${_duration2String(_duration)},style: TextStyle(fontSize: 14.0, color: Colors.white),),),// IconButton( // icon: Icon(widget.player.value.fullScreen // ? Icons.fullscreen_exit // : Icons.fullscreen), // padding: EdgeInsets.only(left: 10.0, right: 10.0), // // color: Colors.transparent, // onPressed: () { // widget.player.value.fullScreen // ? player.exitFullScreen() // : player.enterFullScreen(); // }, // )//],),),);}overrideWidget build(BuildContext context) {// Rect rect player.value.fullScreen// ? Rect.fromLTWH(0, 0, widget.viewSize.width, widget.viewSize.height)// : Rect.fromLTRB(// max(0.0, widget.texturePos.left),// max(0.0, widget.texturePos.top),// min(widget.viewSize.width, widget.texturePos.right),// min(widget.viewSize.height, widget.texturePos.bottom));Rect rect Rect.fromLTWH(0, 0, widget.viewSize.width, widget.viewSize.height);return Positioned.fromRect(rect: rect,child: GestureDetector(onTap: _cancelAndRestartTimer,child: AbsorbPointer(absorbing: _hideStuff,child: Column(children: Widget[Container(height: barHeight),Expanded(child: GestureDetector(onTap: () {_cancelAndRestartTimer();},child: Container(color: Colors.transparent,height: double.infinity,width: double.infinity,child: Center(child: _exception ! null? Text(_exception!,style: TextStyle(color: Colors.white,fontSize: 25,),): (_prepared ||player.state FijkState.initialized)? AnimatedOpacity(opacity: _hideStuff ? 0.0 : 0.85,duration: Duration(milliseconds: 400),child: IconButton(iconSize: barHeight * 2,icon: Icon(_playing? Icons.pause: Icons.play_arrow,color: Colors.white,size: 44,),padding: EdgeInsets.only(left: 10.0, right: 10.0),onPressed: _playOrPause)): SizedBox(width: barHeight * 1.5,height: barHeight * 1.5,child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.white)),)),),),),_buildBottomBar(context),],),),),);} }String _duration2String(Duration duration) {if (duration.inMilliseconds 0) return -: negtive;String twoDigits(int n) {if (n 10) return $n;return 0$n;}String twoDigitMinutes twoDigits(duration.inMinutes.remainder(60));String twoDigitSeconds twoDigits(duration.inSeconds.remainder(60));int inHours duration.inHours;return inHours 0? $inHours:$twoDigitMinutes:$twoDigitSeconds: $twoDigitMinutes:$twoDigitSeconds; } 2.5、嵌套FijkView的IJKVideoPlayer 在使用时候使用了IJKVideoPlayer来封装了一层FijkView。 在IJKVideoPlayer中设置了videoPlayerController控制播放的操作 如停止、暂停、播放、seek、设置音量、设置播放速率、设置循环次数、获取是否在播放中。 IJKVideoPlayer完整代码如下 import package:fijkplayer/fijkplayer.dart; import package:flutter/material.dart; import package:flutter_app_demolab/ijk_player/ijk_video_panel.dart;import ijk_video_player_controller.dart;/// usage /// autoPlay 为 true 时等同于连续调用 setDataSource、prepareAsync、start /// fplayer.setDataSource(http://samplevideo.com/sample.flv, autoPlay: true); /// /// 设置本地资源作为播放源 /// pubspec.yml 中需要指定assets 内容 /// assets: /// - assets/butterfly.mp4 /// /// scheme 是 asset, :// 是 scheme 分隔符 / 是路径起始符号 /// fplayer.setDataSource(asset:///assets/butterfly.mp4, autoPlay: true);class IJKVideoPlayer extends StatefulWidget {const IJKVideoPlayer({super.key,required this.path,this.autoPlay false,this.showCover true,this.fit FijkFit.contain,this.cover,this.color Colors.black,this.width,this.height,this.videoPlayerController,});final double? width;final double? height;final String path;final bool autoPlay;final bool showCover;final FijkFit fit;final Widget? cover;final Color color;final IJKVideoPlayerController? videoPlayerController;overrideStateIJKVideoPlayer createState() _IJKVideoPlayerState(); }class _IJKVideoPlayerState extends StateIJKVideoPlayer {final FijkPlayer player FijkPlayer();overridevoid initState() {super.initState();player.setDataSource(widget.path,autoPlay: widget.autoPlay,showCover: widget.showCover,);addVideoPlayerFun();}void addVideoPlayerFun() {if (widget.videoPlayerController ! null) {widget.videoPlayerController!.play () {// 触发播放player.start();};widget.videoPlayerController!.stop () {// 触发停止player.stop();};widget.videoPlayerController!.pause () {// 触发暂停player.pause();};widget.videoPlayerController!.setLoop (int loopCount) {// 触发setLoopif (loopCount 0) {loopCount 1;}player.setLoop(loopCount);};widget.videoPlayerController!.seekTo (int msec) {// 触发seekif (msec 0) {msec 0;}player.seekTo(msec);};widget.videoPlayerController!.setVolume (double volume) {// 触发setVolumeif (volume 0.0) {volume 0.0;}player.setVolume(volume);};widget.videoPlayerController!.setSpeed (double speed) {// 触发setSpeedif (speed 0.0) {speed 1.0;}player.setSpeed(speed);};widget.videoPlayerController!.isPlaying () {// 触发setVolumeif (FijkState.started player.state) {return true;} else {return false;}};}}overridevoid dispose() {super.dispose();player.release();}void onIJKDispose(FijkData fijkData) {}overrideWidget build(BuildContext context) {return Container(alignment: Alignment.center,child: Stack(alignment: Alignment.center,children: [widget.cover ! null ? widget.cover! : Container(),FijkView(width: widget.width,height: widget.height,player: player,fit: widget.fit,fsFit: widget.fit,color: widget.color,onDispose: onIJKDispose,panelBuilder: (FijkPlayer player, FijkData data,BuildContext context, Size viewSize, Rect texturePos) {return IJKVideoPanel(player: player,buildContext: context,viewSize: viewSize,texturePos: texturePos,);},),],),);} } 三、最后使用IJKVideoPlayer的IJKVideoPage页面 这里我创建了一个IJKVideoPage来使用IJKVideoPlayer视频播放IJKVideoPlayer中需要path与videoPlayerController IJKVideoPage完整代码如下 import dart:async;import package:flutter/material.dart;import ijk_player/ijk_video_player.dart; import ijk_player/ijk_video_player_controller.dart;class IJKVideoPage extends StatefulWidget {const IJKVideoPage({super.key,required this.url,});final String url;overrideStateIJKVideoPage createState() _IJKVideoPageState(); }class _IJKVideoPageState extends StateIJKVideoPage {final IJKVideoPlayerController videoPlayerController IJKVideoPlayerController();overridevoid initState() {super.initState();}overrideWidget build(BuildContext context) {Size size MediaQuery.of(context).size;return Scaffold(appBar: AppBar(title: Text(Fijkplayer Example)),body: Center(child: Container(width: size.width,height: size.width * 9.0 / 16.0,alignment: Alignment.center,child: IJKVideoPlayer(path: widget.url,videoPlayerController: videoPlayerController,color: Colors.black,),),),);}overridevoid dispose() {super.dispose();} } 如果外面的页面跳转到播放页面需要设置url void testIJKVideoPage(BuildContext context) {Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return IJKVideoPage(url: https://vd2.bdstatic.com/mda-maif0tt1rirqp27q/540p/h264_cae/1611052585/mda-maif0tt1rirqp27q.mp4);}));} https://brucegwo.blog.csdn.net/article/details/136024588 四、小结 flutter开发实战-ijkplayer视频播放器功能 学习记录每天不停进步。
http://www.zqtcl.cn/news/224648/

相关文章:

  • 汕头免费建设网站制作阆中市网站建设
  • 怎样做网站表白墙网站设计的一般流程是什么
  • 河北手机网站制作企业网页设计的基本步骤和流程
  • 企业网站内容如何更新软件开发公司网站模板
  • 北京网站建设收费长沙有哪个学校可以学网站建设
  • 南江网站建设中国最好的app开发公司
  • 简单旅游网站开发建立网站的三种方式
  • 大连网站的优化网站设计 优帮云
  • 梧州网站seo表白网站在线生成免费
  • 网站制作体会php网站开发答案
  • 南阳响应式网站淘宝上成都网站建设
  • 深圳做手机网站设计wordpress禁用wp-cron
  • 如何自己建公司网站搜索引擎排名2020
  • 济南建站商业网站开发入门选课
  • 济南网络免费推广网站四川建设厅官方网站查询
  • 中国建设银行网站首页wordpress安装多个
  • 中国住建厅网站官网怎么建立网站快捷方式
  • 天津协会网站建设怎么用dw做带登陆的网站
  • 南宁做网站服务商苏州网站建设品牌
  • 做平台销售网站上海市普陀区建设规划局网站
  • 网站的积分系统怎么做电影在线观看
  • 成都网站建设方案服务旅游网站建设报价单
  • 京东网址seo排名查询工具
  • 南京制作网站速成班外贸营销信模板
  • 简单网站建设规划方案物联网网站设计
  • 做360网站官网还是百度四川平台网站建设方案
  • 做网站的主题有哪些精品课程网站建设情况
  • 帝国网站开发电商平台搭建
  • 建设工程网站tcwordpress 标题入库
  • 网站开发简直广州网站制作后缀