#Flutter介绍
不介绍百度泛滥的,能搜到的,flutter对个人而言,易上手,业余人士也能迅速开发出一款跨平台APP,多么神奇啊。用的dart语言,scaffold 脚手架迅速对app布局,路由功能,更好管理页面。还有动画。小白能做到的极限就是到UI的设计,要更深入还得用dio库,学习get post使用,混编估计有点难,毕竟我连Java都没去了解过。
#Flutter安装
千篇一律,不多介绍,我用的是Android studio的安卓模拟器+vscode敲代码(vscode插件里面加几个插件扩展(extensions),使dart语言敲起来更省时间。插件如下)
Awesome Flutter Snippets//能省去大量时间写架子
Dart
Flutter
#注意事项
在敲代码的时候很多括号会让自己写晕,所以要保持一个良好的习惯,该换行的换行,写注释的写注释。
小白应该多记笔记。
#在写Flutter之前你应该了解的一些操作:
flutter doctor//检查flutter整个功能是否正常
flutter create 文件夹名//创建一个包含demo的工作文档
flutter run//在编程无错误的情况下在设备上编译,安装,并调试程序
r//在调试中更新代码,热更新
flutter build apk //在你调试完后生成apk 我的莫名其妙不能生成,各位看着办吧,iOS改成flutter build iOS
-flutter项目文档结构
如图所示,小白一般就用到几个,pubspec.yaml lib文档下创建几个dart文件。
pubspec.yaml 用来装插件的,电视直播相关的信息名词各位可以先了解一下:
直播源、m3u8、投屏、DLNA、p2p、切片、ts
有些这个程序用不到,如果不太想弄懂的话可以只了解直播源、m3u8
直播源是一个地址,一般的是http://xxxxxxxxxxxxxxxx.m3u8
这就需要一个载体打开,播放器打开,有的播放器不支持,有的支持,首先国内有QQ浏览器X5内核sdk
这个可以,但操作麻烦,x86框架还得改文件里面东西,麻烦,demo运行也会出错,所以换一个来弄
此时我找到了chewie package GitHub里面有example,测试几个链接正常,所以就选它了
下载demo,经过chewie的介绍和代码的分析,发现chewie的example不仅仅用到了自家的player,还有
video player库,其他的chewie和chewie_player 的区别,我母鸡啊,某书的文章应该有,
打开chewie的example/lib/main.dart 然后自己写几个:
import 'package:chewie/chewie.dart';//导入chewie依赖
import 'package:chewie/src/chewie_player.dart';//导入chewie播放器依赖
import 'package:flutter/cupertino.dart';//导入iOS风格依赖
import 'package:flutter/material.dart';//flutter默认的一套UI
import 'package:video_player/video_player.dart';//一个video播放器
import 'package:url_launcher/url_launcher.dart';//这个是便于写加群功能的一个依赖 从某文章看到的
////首先,出现了没有homepage怪,app启动对应ChewieDemo这个类,由它控制,flutter自带的demo可以简写,不要那么多麻烦的括号
void main() {
runApp(
ChewieDemo(),
);
}
//出现了!套路格式 class xxxx extends StatefulWidget ChewieDemo 继承于statefulwidget 状态管理,对应的有StatelessWidget 二者区别总是记住了又忘了,有会的给俺普及一下。
class ChewieDemo extends StatefulWidget {
ChewieDemo({this.title = '脉冲电视直播-基于chewie'});
final String title;//flutter的 final功能可以参考csdn的 FreeAndWake给出的介绍
@override//覆写 某书有介绍,百度一下你就知道
State createState() {
return _ChewieDemoState();//返回 _ChewieDemoState()
}
}
//出现了!套娃怪,此时又出现了继承,
class _ChewieDemoState extends State {
TargetPlatform _platform;////目标平台,emmmm不懂
VideoPlayerController _videoPlayerController1;//武汉直播 //控制实例化下同
VideoPlayerController _videoPlayerController2;//CCTV13
VideoPlayerController _videoPlayerController3;//CCTV1
VideoPlayerController _videoPlayerController4;//CCTV6
VideoPlayerController _videoPlayerController5;//CCTV5
VideoPlayerController _videoPlayerController6;//虎牙电影
ChewieController _chewieController;
@override
void initState() {
super.initState();//下面network就是直播源的地址。
_videoPlayerController1 = VideoPlayerController.network(
'https://pl.live.weibo.com/alicdn/e48f83034f3e60014767e7e1574d7df3_wb720.m3u8');//武汉直播http://pl.live.weibo.com/alicdn/459a245fed4473430925dc5189427df6_6M.m3u8
_videoPlayerController2 = VideoPlayerController.network(
'http://liveali.ifeng.com/live/CCTV.m3u8');//CCTV13http://liveali.ifeng.com/live/CCTV.m3u8
_videoPlayerController3 = VideoPlayerController.network(
'http://cctvalih5ca.v.myalicdn.com/live/cctv1_2/index.m3u8');//CCTV1http://cctvalih5ca.v.myalicdn.com/live/cctv1_2/index.m3u8
_videoPlayerController4 = VideoPlayerController.network(
'http://cctvalih5ca.v.myalicdn.com/live/cctv6_2/index.m3u8');//CCTV6http://cctvalih5ca.v.myalicdn.com/live/cctv6_2/index.m3u8
_videoPlayerController5 = VideoPlayerController.network(
'http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8');//CCTV5+http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8
_videoPlayerController6 = VideoPlayerController.network(
'http://aldirect.hls.huya.com/huyalive/28466698-2689656864-11551988268341919744-2847699194-10057-A-0-1_1200.m3u8');//电影
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
aspectRatio: 3 / 2, //横宽比
autoPlay: false,//自动播放
looping: true,//循环 如果播放完
// // Try playing around with some of these other options:
showControls: false, //显示控制 下面的colors感觉没x用
materialProgressColors: ChewieProgressColors(
playedColor: Colors.red,
handleColor: Colors.blue,
backgroundColor: Colors.grey,
bufferedColor: Colors.lightGreen,
),
placeholder: Container(
color: Colors.grey,
),
autoInitialize: true, //自动初始化 emmmmmmm
);
}
@override//下面是播放功能的控制
void dispose() {
_videoPlayerController1.dispose();
_videoPlayerController2.dispose();
_videoPlayerController3.dispose();
_videoPlayerController4.dispose();
_videoPlayerController5.dispose();
_videoPlayerController6.dispose();
_chewieController.dispose();
super.dispose();
}
@override//渲染
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title, //标题
theme: ThemeData.light().copyWith(
platform: _platform ?? Theme.of(context).platform,
),//主题 下面是脚手架 不多bibi
home: Scaffold(
appBar: AppBar(
actions: [
IconButton(icon: Icon(Icons.group_add),//这是个图标按钮
onPressed: (){
callQQ();//按下事件。转到加群功能在本代码末尾
}),
],
title: Text(widget.title),
),
body: Column(
children: [
Expanded(
child: Center(
child: Chewie(
controller: _chewieController,
),
),
),
FlatButton(//这是个flat按钮
onPressed: () {
_chewieController.enterFullScreen();
},
child: Text('Fullscreen'),
),
Row(//Row flutter的一个布局,对应的还有Column
children: [//children child 傻傻分不清,不过,children里面可以有child
Expanded(
child: FlatButton(
onPressed: () {
setState(() {//状态
_chewieController.dispose();
_videoPlayerController2.pause();//第2个播放功能暂停
_videoPlayerController2.seekTo(Duration(seconds: 0)); //进度条置0
_videoPlayerController3.pause();
_videoPlayerController3.seekTo(Duration(seconds: 0));
_videoPlayerController4.pause();
_videoPlayerController4.seekTo(Duration(seconds: 0));
_videoPlayerController5.pause();
_videoPlayerController5.seekTo(Duration(seconds: 0));
_videoPlayerController6.pause();
_videoPlayerController6.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1, //控制第1个播放控制
aspectRatio: 3/2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
child: Text("武汉云监工"),
padding: EdgeInsets.symmetric(vertical: 16.0),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_videoPlayerController3.pause();
_videoPlayerController3.seekTo(Duration(seconds: 0));
_videoPlayerController4.pause();
_videoPlayerController4.seekTo(Duration(seconds: 0));
_videoPlayerController5.pause();
_videoPlayerController5.seekTo(Duration(seconds: 0));
_videoPlayerController6.pause();
_videoPlayerController6.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController2,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("CCTV13新闻"),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_videoPlayerController4.pause();
_videoPlayerController4.seekTo(Duration(seconds: 0));
_videoPlayerController5.pause();
_videoPlayerController5.seekTo(Duration(seconds: 0));
_videoPlayerController6.pause();
_videoPlayerController6.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController3,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("CCTV1综合"),
),
),
)
],
),
Row(
children: [
// Expanded(
// child: FlatButton(
// onPressed: () {
// setState(() {
// _platform = TargetPlatform.android;
// });
// },
// child: Padding(
// child: Text("Android controls"),
// padding: EdgeInsets.symmetric(vertical: 16.0),
// ),
// ),
// ),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_videoPlayerController3.pause();
_videoPlayerController3.seekTo(Duration(seconds: 0));
_videoPlayerController5.pause();
_videoPlayerController5.seekTo(Duration(seconds: 0));
_videoPlayerController6.pause();
_videoPlayerController6.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController4,
aspectRatio: 3/2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("CCTV6电影"),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_videoPlayerController3.pause();
_videoPlayerController3.seekTo(Duration(seconds: 0));
_videoPlayerController4.pause();
_videoPlayerController4.seekTo(Duration(seconds: 0));
_videoPlayerController6.pause();
_videoPlayerController6.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController5,
aspectRatio: 3 / 2,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("CCTV5体育"),
),
),
),
Expanded(
child: FlatButton(
onPressed: () {
setState(() {
_chewieController.dispose();
_videoPlayerController1.pause();
_videoPlayerController1.seekTo(Duration(seconds: 0));
_videoPlayerController2.pause();
_videoPlayerController2.seekTo(Duration(seconds: 0));
_videoPlayerController3.pause();
_videoPlayerController3.seekTo(Duration(seconds: 0));
_videoPlayerController4.pause();
_videoPlayerController4.seekTo(Duration(seconds: 0));
_videoPlayerController5.pause();
_videoPlayerController5.seekTo(Duration(seconds: 0));
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController6,
aspectRatio: 16/9,
autoPlay: true,
looping: true,
);
});
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text("虎牙电影"),
),
),
),
],
)
],
),
),
);
}
}
//这是加QQ或QQ群的 ?? ?:是干嘛的可以自己搜下
void callQQ({int number = 365700128, bool isGroup = true}) async {
String url = isGroup
? 'mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${number ?? 0}&card_type=group&source=qrcode'
: 'mqqwpa://im/chat?chat_type=wpa&uin=${number ?? 0}&version=1&src_type=web&web_src=oicqzone.com';
if (await canLaunch(url)) {
await launch(url);
} else {
print('不能访问');
}
}
到此写完了,如果会dio,可以做成别的,至此,一个app诞生。
见证下界面:
必看:源码因为大小限制,分为3部分,我发两部分,另一部分需要下载,见谅
资源如下:example.part1.rar 和example.part2.rar
链接:https://pan.baidu.com/s/1xl4kQlq8VKKJUf7GgsLXXw
提取码:az35
example.part3.rar链接:https://download.csdn.net/download/qq_21520773/12152776
或者你可以在这个资源直接获取源码这个链接是前面未切割的压缩包:
https://download.csdn.net/download/qq_21520773/12152723