Commit b7ea698e6f6e543d6cc894171cef22c58cce751d

Authored by wdn127929
1 parent 3539d361

视频图片混合上传显示

... ... @@ -57,6 +57,8 @@ PODS:
- TPNS-iOS (= 1.2.7.2)
- url_launcher (0.0.1):
- Flutter
- video_compress (0.3.0):
- Flutter
- video_player (0.0.1):
- Flutter
- wakelock (0.0.1):
... ... @@ -89,6 +91,7 @@ DEPENDENCIES:
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- tpns_flutter_plugin (from `.symlinks/plugins/tpns_flutter_plugin/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
- video_compress (from `.symlinks/plugins/video_compress/ios`)
- video_player (from `.symlinks/plugins/video_player/ios`)
- wakelock (from `.symlinks/plugins/wakelock/ios`)
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
... ... @@ -149,6 +152,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/tpns_flutter_plugin/ios"
url_launcher:
:path: ".symlinks/plugins/url_launcher/ios"
video_compress:
:path: ".symlinks/plugins/video_compress/ios"
video_player:
:path: ".symlinks/plugins/video_player/ios"
wakelock:
... ... @@ -185,6 +190,7 @@ SPEC CHECKSUMS:
TPNS-iOS: 9b35473a4a0d07f2c2730ea1e66c6749c2b98095
tpns_flutter_plugin: 8dbbee157aab91a878f64d056c1383726a6c5c4d
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
video_compress: fce97e4fb1dfd88175aa07d2ffc8a2f297f87fbe
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e
wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
... ...
... ... @@ -298,6 +298,7 @@
"${BUILT_PRODUCTS_DIR}/sign_in_with_apple/sign_in_with_apple.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
"${BUILT_PRODUCTS_DIR}/video_compress/video_compress.framework",
"${BUILT_PRODUCTS_DIR}/video_player/video_player.framework",
"${BUILT_PRODUCTS_DIR}/wakelock/wakelock.framework",
"${BUILT_PRODUCTS_DIR}/webview_flutter/webview_flutter.framework",
... ... @@ -324,6 +325,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sign_in_with_apple.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_compress.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/webview_flutter.framework",
... ...
... ... @@ -67,9 +67,9 @@ Future<void> main() async {
ChangeNotifierProvider<CouponProvider>(
create: (_) => CouponProvider(),
),
ChangeNotifierProvider<UploadImageProvider>(
create: (_) => UploadImageProvider(),
),
// ChangeNotifierProvider<UploadImageProvider>(
// create: (_) => UploadImageProvider(),
// ),
ChangeNotifierProvider<BaseIndoProvider>(
create: (_) => BaseIndoProvider(),
),
... ...
... ... @@ -6,4 +6,12 @@ class UploadImgModel {
File file; //本地图片地址
String qiniuUrl; //七牛云地址
double process; //图片上传进度
FileType fileType;
File thumbnailPath; // 视频封面
String duration; //视频时长
}
enum FileType {
image,
video,
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:one_key/pages/create_store/video_widget.dart';
import 'package:one_key/provider/upload_img_provider.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/navigator_util.dart';
import 'package:one_key/widgets/round_button.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:one_key/widgets/v_empty_view.dart';
import 'package:provider/provider.dart';
class CreateStorePage extends StatefulWidget {
CreateStorePage({Key key}) : super(key: key);
... ... @@ -100,7 +102,10 @@ class _CreateStorePageState extends State<CreateStorePage> {
style: TextStyle(
fontSize: ScreenUtil().setSp(30), fontWeight: FontWeight.bold)),
VEmptyView(30),
VideoPickerWidget(maxImageNumber: 1)
Consumer<UploadImageProvider>(builder: (context, model, _) {
return VideoPickerWidget(
maxImageNumber: 9, model: model, scrollController: _controller);
})
],
);
}
... ...
// import 'dart:convert';
// import 'dart:io';
// import 'dart:async';
// import 'package:cached_network_image/cached_network_image.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
// import 'package:one_key/models/upload_img_model.dart';
// import 'package:one_key/pages/online_check/photo_view_wiget.dart';
// import 'package:one_key/pages/online_check/progress.dart';
// import 'package:one_key/provider/online_check_edit_provider.dart';
// import 'package:one_key/provider/upload_img_provider.dart';
// import 'package:one_key/res/colors.dart';
// import 'package:one_key/utils/dialog_util.dart';
// import 'package:one_key/utils/misc.dart';
// import 'package:one_key/utils/navigator_util.dart';
// import 'package:one_key/utils/upload_image_util.dart';
// import 'package:one_key/utils/utils.dart';
// import 'package:one_key/widgets/MyDivider.dart';
// import 'package:one_key/widgets/v_empty_view.dart';
// import 'package:permission_handler/permission_handler.dart';
// import 'package:photo/photo.dart';
// import 'package:provider/provider.dart';
// import 'package:image_picker/image_picker.dart';
// import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
// import 'package:video_player/video_player.dart';
// import '../online_check/dispose.dart';
// import 'package:photo_manager/photo_manager.dart';
// // import 'package:video_thumbnail/video_thumbnail.dart';
// import 'package:chewie/chewie.dart';
// typedef void OnPickImageCallback(
// double maxWidth, double maxHeight, int quality);
// class VideoPickerWidget extends StatefulWidget {
// final ScrollController scrollController;
// final Color borderColor;
// final ValueChanged onChange;
// final int maxImageNumber;
// VideoPickerWidget(
// {Key key,
// this.scrollController,
// this.borderColor = Colors.blue,
// this.onChange,
// this.maxImageNumber = 5})
// : super(key: key);
// @override
// _VideoPickerWidgetState createState() => _VideoPickerWidgetState();
// }
// class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
// final picker = ImagePicker();
// // OnlineCheckEditProvider _onlineCheckEditProvider;
// UploadImageProvider _uploadImageProvider;
// // 用户输入的文件名
// String key;
// // 用户输入的 partSize
// int partSize = 4;
// // 用户输入的 token
// String token;
// /// storage 实例
// final Storage storage = Storage();
// // 控制器,可以用于取消任务、获取上述的状态,进度等信息
// // PutController putController = PutController();
// // 当前的任务状态
// // String thumbnailPath;
// VideoPlayerController _controller;
// Future _initializeVideoPlayerFuture;
// // 声明控制器(两个)
// VideoPlayerController videoPlayerController;
// ChewieController chewieController;
// IjkMediaController ijkMediaController = IjkMediaController();
// @override
// void initState() {
// // storage = Storage();
// // putController = PutController();
// super.initState();
// // _controller.setLooping(false);
// // 生成控制器(两个)
// }
// @override
// void dispose() {
// super.dispose();
// // 销毁播放器的控制器
// _controller.dispose();
// chewieController.dispose();
// }
// ///#相机拍照,单图选择
// Future _getFromPictureOrCamera(imageSource) async {
// final pickedFile = await picker.getVideo(
// source: imageSource, maxDuration: const Duration(seconds: 15));
// // thumbnailPath = await VideoThumbnail.thumbnailFile(
// // video: pickedFile.path,
// // imageFormat: ImageFormat.PNG,
// // maxWidth: 128,
// // quality: 25);
// // print(thumbnailPath);
// _controller = VideoPlayerController.file(File(pickedFile.path));
// _initializeVideoPlayerFuture = _controller.initialize();
// setState(() {
// if (pickedFile != null) {
// UploadImgModel imgModel = UploadImgModel();
// imgModel.file = File(pickedFile.path);
// imgModel.process = 0.01;
// _uploadImageProvider.imageList.add(imgModel);
// } else {
// print('No image selected.');
// }
// });
// if (pickedFile != null) {
// UploadImageUtil().startUpload(
// context,
// File(pickedFile.path),
// _uploadImageProvider.imageList.length - 1,
// true,
// _uploadImageProvider);
// }
// }
// ///多图片选择
// void pickAsset(PickType type, {List<AssetPathEntity> pathList}) async {
// /// context is required, other params is optional.
// List<AssetEntity> imgList = await PhotoPicker.pickAsset(
// // BuildContext required
// context: context,
// /// The following are optional parameters.
// themeColor: MyColours.color_199095,
// // the title color and bottom color
// textColor: Colors.white,
// // text color
// padding: 1.0,
// // item padding
// dividerColor: Colors.grey,
// // divider color
// disableColor: Colors.grey.shade300,
// // the check box disable color
// itemRadio: 0.88,
// // the content item radio
// maxSelected:
// widget.maxImageNumber - _uploadImageProvider.imageList.length,
// // max picker image count
// // provider: I18nProvider.english,
// provider: I18nProvider.chinese,
// // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
// rowCount: 3,
// // item row count
// thumbSize: 150,
// // preview thumb size , default is 64
// sortDelegate: SortDelegate.common,
// // default is common ,or you make custom delegate to sort your gallery
// checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
// activeColor: MyColours.color_353535,
// unselectedColor: Colors.white,
// checkColor: MyColours.color_199095,
// ),
// // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
// // loadingDelegate: this,
// // if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart]
// badgeDelegate: const DurationBadgeDelegate(),
// // badgeDelegate to show badge widget
// pickType: type,
// photoPathList: pathList,
// );
// if (imgList == null || imgList.isEmpty) {
// print("No pick item.");
// return;
// } else {
// for (int i = 0; i < imgList.length; i++) {
// var file = await imgList[i].file;
// setState(() {
// UploadImgModel imgModel = UploadImgModel();
// imgModel.file = File(file.absolute.path);
// imgModel.process = 0.01;
// _uploadImageProvider.imageList.add(imgModel);
// });
// UploadImageUtil().startUpload(
// context,
// File(file.absolute.path),
// _uploadImageProvider.imageList.length - 1,
// false,
// _uploadImageProvider);
// // startUpload(File(file.absolute.path),
// // _uploadImageProvider.imageList.length - 1, false);
// }
// }
// }
// ///添加图片UI弹出
// Future _openModalBottomSheet(context) async {
// final option = await showModalBottomSheet(
// context: context,
// backgroundColor: Colors.transparent,
// isDismissible: false,
// builder: (BuildContext context) {
// return Container(
// // height: ScreenUtil().setWidth(180 * 2),
// decoration: BoxDecoration(
// color: MyColours.color_ffffff,
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(ScreenUtil().setWidth(24)),
// topRight: Radius.circular(ScreenUtil().setWidth(24)))),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// InkWell(
// onTap: () {
// Utils.getPickPermission(context, () {
// _getFromPictureOrCamera(ImageSource.camera);
// Navigator.pop(context);
// }, PermissionGroup.camera);
// },
// child: Container(
// width: double.infinity,
// height: ScreenUtil().setWidth(58 * 2),
// child: Center(
// child: Text(
// '拍摄',
// style: TextStyle(
// fontSize: ScreenUtil().setSp(32),
// color: MyColours.color_353535,
// fontWeight: FontWeight.bold),
// ),
// )),
// ),
// MyDivider(
// double.infinity,
// ScreenUtil().setWidth(2),
// color: MyColours.color_EEEEEE,
// ),
// InkWell(
// onTap: () {
// Utils.getPickPermission(context, () {
// // pickAsset(PickType.onlyVideo);
// _getFromPictureOrCamera(ImageSource.gallery);
// Navigator.pop(context);
// }, PermissionGroup.photos);
// },
// child: Container(
// width: double.infinity,
// height: ScreenUtil().setWidth(58 * 2),
// child: Center(
// child: Text(
// '从相册选择',
// style: TextStyle(
// fontSize: ScreenUtil().setSp(32),
// color: MyColours.color_353535,
// fontWeight: FontWeight.bold),
// ),
// )),
// ),
// MyDivider(
// double.infinity,
// ScreenUtil().setWidth(10),
// color: MyColours.color_EEEEEE,
// ),
// InkWell(
// onTap: () {
// Navigator.pop(context, '取消');
// },
// child: Container(
// width: double.infinity,
// height: ScreenUtil().setWidth(58 * 2),
// child: Center(
// child: Text(
// '取消',
// style: TextStyle(
// fontSize: ScreenUtil().setSp(32),
// color: MyColours.color_353535,
// fontWeight: FontWeight.bold),
// ),
// )))
// ],
// ),
// );
// });
// }
// //查看大图
// _showPhotoView(BuildContext context, int index, List imgs,
// {isShow = false, List dashName}) async {
// // if (imgs.length == 1 &&
// // imgs[0] ==
// // 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {
// // imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';
// // }
// // _controller = VideoPlayerController.network(imgs[index]);
// // chewieController = ChewieController(
// // videoPlayerController: _controller,
// // // 比例
// // // aspectRatio: 16 / 9,
// // // 自动播放
// // autoPlay: true,
// // // 循环
// // looping: true,
// // );
// ijkMediaController.setNetworkDataSource(
// imgs[index],
// autoPlay: true,
// );
// Utils.setBarStatus(false, color: Colors.black);
// dynamic result = await showGeneralDialog(
// context: context,
// barrierDismissible: false,
// barrierColor: Colors.black,
// barrierLabel:
// MaterialLocalizations.of(context).modalBarrierDismissLabel,
// transitionDuration: const Duration(milliseconds: 150),
// pageBuilder: (BuildContext context, Animation animation,
// Animation secondaryAnimation) {
// return Column(
// children: [
// Container(
// height: ScreenUtil().setWidth(100),
// color: Colors.black,
// child: Row(
// children: [
// Material(
// child: InkWell(
// onTap: () {
// Navigator.pop(context);
// },
// child: Image.asset(Utils.getImgPath('invication_back')),
// )),
// ],
// ),
// ),
// // Chewie(
// // controller: chewieController,
// // ),
// IjkPlayer(mediaController: ijkMediaController),
// ],
// );
// });
// // Utils.setBarStatus(true, color: Colors.white);
// }
// @override
// Widget build(BuildContext context) {
// _uploadImageProvider =
// Provider.of<UploadImageProvider>(context, listen: true);
// return _getGridImg(
// _uploadImageProvider.imageList.length < widget.maxImageNumber
// ? _uploadImageProvider.imageList.length + 1
// : _uploadImageProvider.imageList.length,
// context,
// _uploadImageProvider.imageList.length == widget.maxImageNumber
// ? true
// : false);
// }
// /// 九宫格
// Widget _getGridImg(count, context, isLinjie) {
// // return
// // GridView.builder(
// // controller: widget.scrollController,
// // // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
// // shrinkWrap: true,
// // itemCount: count,
// // //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
// // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// // //横轴元素个数
// // crossAxisCount: 1,
// // //纵轴间距
// // mainAxisSpacing: ScreenUtil().setWidth(30),
// // //横轴间距
// // crossAxisSpacing: ScreenUtil().setWidth(30),
// // //子组件宽高长度比例
// // // childAspectRatio: 1.0
// // ),
// // itemBuilder: (BuildContext context, int index) {
// //Widget Function(BuildContext context, int index)
// var linjie = widget.maxImageNumber;
// if (isLinjie) {
// linjie = widget.maxImageNumber - 1;
// }
// if (0 == count - 1 && 0 < linjie) {
// return InkWell(
// onTap: () {
// // 触摸收起键盘
// FocusScope.of(context).requestFocus(FocusNode());
// _openModalBottomSheet(context);
// },
// child: Container(
// width: ScreenUtil().setWidth(90 * 2),
// height: ScreenUtil().setWidth(90 * 2),
// decoration: BoxDecoration(
// border: Border.all(
// color: MyColours.color_E0E0E0,
// width: ScreenUtil().setWidth(2)),
// ),
// child: Column(
// children: [
// VEmptyView(74),
// Image.asset(
// Utils.getImgPath('add_image'),
// width: ScreenUtil().setWidth(32),
// height: ScreenUtil().setWidth(32),
// ),
// VEmptyView(10),
// Text(
// '添加视频',
// style: TextStyle(
// fontSize: ScreenUtil().setSp(24),
// color: MyColours.color_999999),
// )
// ],
// )),
// );
// }
// return _uploadImageProvider.imageList.length < 1
// ? Text('')
// : InkWell(
// onTap: () {
// if (_uploadImageProvider.imageList[0].process == 1) {
// _uploadImageProvider.imageQiniuUrlList = [];
// if (_uploadImageProvider.imageList[0].qiniuUrl != null) {
// for (int i = 0;
// i < _uploadImageProvider.imageList.length;
// i++) {
// _uploadImageProvider.imageQiniuUrlList
// .add(_uploadImageProvider.imageList[i].qiniuUrl);
// }
// ///没有上传完成的不可以点击
// // _showPhotoView(
// // context, 0, _uploadImageProvider.imageQiniuUrlList);
// NavigatorUtil.goPlayVideoPage(context,
// urlStr: _uploadImageProvider.imageQiniuUrlList[0]);
// }
// }
// },
// child: Stack(
// children: [
// Stack(
// alignment: Alignment.topRight,
// children: [
// // Image.file(
// // // _uploadImageProvider.imageList[index].file,
// // File(thumbnailPath),
// // fit: BoxFit.cover,
// // width: ScreenUtil().setWidth(100 * 2),
// // height: ScreenUtil().setWidth(100 * 2),
// // ),
// FutureBuilder(
// //显示缩略图
// future: _initializeVideoPlayerFuture,
// builder: (context, snapshot) {
// print(snapshot.connectionState);
// if (snapshot.hasError) print(snapshot.error);
// if (snapshot.connectionState == ConnectionState.done) {
// return Container(
// width: ScreenUtil().setWidth(225),
// child: AspectRatio(
// // aspectRatio: 1 / 1,
// aspectRatio: _controller.value.aspectRatio,
// child: VideoPlayer(_controller),
// ),
// );
// } else {
// return Center(
// child: CircularProgressIndicator(),
// );
// }
// },
// ),
// Offstage(
// offstage: _uploadImageProvider.imageList[0].process < 1,
// child: GestureDetector(
// child: Image.asset(
// Utils.getImgPath("delete"),
// width: ScreenUtil().setWidth(40),
// height: ScreenUtil().setWidth(40),
// ),
// onTap: () {
// //点击删除按钮
// setState(() {
// _uploadImageProvider.imageList.removeWhere(
// (element) =>
// element ==
// _uploadImageProvider.imageList[0]);
// _uploadImageProvider.imageQiniuUrlList.removeWhere(
// (element) =>
// element ==
// _uploadImageProvider.imageQiniuUrlList[0]);
// });
// },
// ),
// ),
// ],
// ),
// Offstage(
// offstage: _uploadImageProvider.imageList[0].process == 1,
// child: Progress(_uploadImageProvider.imageList[0].process),
// )
// ],
// ));
// // });
// }
// }
... ...
import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:one_key/pages/online_check/progress.dart';
import 'package:one_key/utils/navigator_util.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:video_player/video_player.dart';
class PlayVideoPage extends StatefulWidget {
final String url;
... ... @@ -12,28 +14,51 @@ class PlayVideoPage extends StatefulWidget {
}
class _PlayVideoPageState extends State<PlayVideoPage> {
IjkMediaController ijkMediaController = IjkMediaController();
// IjkMediaController ijkMediaController = IjkMediaController();
VideoPlayerController _controller;
@override
void initState() {
// TODO: implement initState
super.initState();
ijkMediaController.setNetworkDataSource(
widget.url,
autoPlay: true,
);
// ijkMediaController.setNetworkDataSource(
// widget.url,
// autoPlay: true,
// );
_controller = VideoPlayerController.network(widget.url)
..initialize().then((_) {
setState(() {});
});
_controller.play();
_controller.setLooping(true);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: SystemAppBar(
'cannnn',
onTap: () {
Navigator.pop(context);
},
),
body: IjkPlayer(mediaController: ijkMediaController),
);
appBar: SystemAppBar(
'',
onTap: () {
Navigator.pop(context);
},
),
// body: IjkPlayer(mediaController: ijkMediaController),
body: Container(
color: Colors.black,
child: Center(
child: _controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: CircularProgressIndicator(),
),
));
}
}
... ...
import 'dart:convert';
import 'dart:io';
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
... ... @@ -11,11 +8,9 @@ import 'package:one_key/models/upload_img_model.dart';
import 'package:one_key/pages/online_check/photo_view_wiget.dart';
import 'package:one_key/pages/online_check/progress.dart';
import 'package:one_key/provider/online_check_edit_provider.dart';
import 'package:one_key/provider/upload_img_provider.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/dialog_util.dart';
import 'package:one_key/utils/misc.dart';
import 'package:one_key/utils/navigator_util.dart';
import 'package:one_key/utils/upload_image_util.dart';
import 'package:one_key/utils/utils.dart';
... ... @@ -23,15 +18,12 @@ import 'package:one_key/widgets/MyDivider.dart';
import 'package:one_key/widgets/v_empty_view.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:photo/photo.dart';
import 'package:provider/provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
import 'package:video_player/video_player.dart';
import '../online_check/dispose.dart';
import 'package:photo_manager/photo_manager.dart';
// import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:chewie/chewie.dart';
import 'package:video_compress/video_compress.dart';
typedef void OnPickImageCallback(
double maxWidth, double maxHeight, int quality);
... ... @@ -41,12 +33,14 @@ class VideoPickerWidget extends StatefulWidget {
final Color borderColor;
final ValueChanged onChange;
final int maxImageNumber;
final UploadImageProvider model;
VideoPickerWidget(
{Key key,
this.scrollController,
this.borderColor = Colors.blue,
this.onChange,
this.maxImageNumber = 5})
this.maxImageNumber = 5,
this.model})
: super(key: key);
@override
... ... @@ -55,8 +49,6 @@ class VideoPickerWidget extends StatefulWidget {
class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
final picker = ImagePicker();
// OnlineCheckEditProvider _onlineCheckEditProvider;
UploadImageProvider _uploadImageProvider;
// 用户输入的文件名
String key;
... ... @@ -71,63 +63,65 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
// PutController putController = PutController();
// 当前的任务状态
// String thumbnailPath;
VideoPlayerController _controller;
Future _initializeVideoPlayerFuture;
// 声明控制器(两个)
VideoPlayerController videoPlayerController;
ChewieController chewieController;
IjkMediaController ijkMediaController = IjkMediaController();
@override
void initState() {
// storage = Storage();
// putController = PutController();
super.initState();
// _controller.setLooping(false);
// 生成控制器(两个)
}
@override
void dispose() {
super.dispose();
// 销毁播放器的控制器
_controller.dispose();
chewieController.dispose();
}
///#相机拍照,单图选择
Future _getFromPictureOrCamera(imageSource) async {
final pickedFile = await picker.getVideo(
source: imageSource, maxDuration: const Duration(seconds: 15));
// thumbnailPath = await VideoThumbnail.thumbnailFile(
// video: pickedFile.path,
// imageFormat: ImageFormat.PNG,
// maxWidth: 128,
// quality: 25);
// print(thumbnailPath);
_controller = VideoPlayerController.file(File(pickedFile.path));
_initializeVideoPlayerFuture = _controller.initialize();
//////#相机拍照,单图选择
Future _getImageFromPictureOrCamera(ImageSource imageSource) async {
final pickedFile = await picker.getImage(source: imageSource);
setState(() {
if (pickedFile != null) {
UploadImgModel imgModel = UploadImgModel();
imgModel.file = File(pickedFile.path);
imgModel.process = 0.01;
_uploadImageProvider.imageList.add(imgModel);
imgModel.fileType = FileType.image;
widget.model.imageList.add(imgModel);
} else {
print('No image selected.');
}
});
if (pickedFile != null) {
UploadImageUtil().startUpload(
context,
File(pickedFile.path),
_uploadImageProvider.imageList.length - 1,
true,
_uploadImageProvider);
UploadImageUtil().startUpload(context, File(pickedFile.path),
widget.model.imageList.length - 1, true, widget.model);
}
}
///视频
Future _getVideoFromPictureOrCamera(ImageSource imageSource) async {
final pickedFile = await picker.getVideo(
source: imageSource, maxDuration: const Duration(seconds: 15));
await VideoCompress.setLogLevel(0);
final info = await VideoCompress.getMediaInfo(pickedFile.path);
String duration = '00';
if (info != null) {
if (info.duration > 15000 || info.duration < 11000) {
Utils.showToast('请选择10~15s的视频');
return;
}
duration = Utils.addZeroNumber((info.duration / 1000).round());
}
File thumbnailPath = await VideoCompress.getFileThumbnail(pickedFile.path,
quality: 100, // default(100)
position: -1 // default(-1)
);
if (pickedFile != null) {
UploadImgModel imgModel = UploadImgModel();
imgModel.file = File(pickedFile.path);
imgModel.process = 0.01;
imgModel.fileType = FileType.video;
imgModel.thumbnailPath = thumbnailPath;
imgModel.duration = duration;
widget.model.imageList.add(imgModel);
setState(() {});
UploadImageUtil().startUpload(context, File(pickedFile.path),
widget.model.imageList.length - 1, true, widget.model);
} else {
print('No image selected.');
}
}
... ... @@ -151,8 +145,7 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
// the check box disable color
itemRadio: 0.88,
// the content item radio
maxSelected:
widget.maxImageNumber - _uploadImageProvider.imageList.length,
maxSelected: widget.maxImageNumber - widget.model.imageList.length,
// max picker image count
// provider: I18nProvider.english,
provider: I18nProvider.chinese,
... ... @@ -186,14 +179,11 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
UploadImgModel imgModel = UploadImgModel();
imgModel.file = File(file.absolute.path);
imgModel.process = 0.01;
_uploadImageProvider.imageList.add(imgModel);
imgModel.fileType = FileType.image;
widget.model.imageList.add(imgModel);
});
UploadImageUtil().startUpload(
context,
File(file.absolute.path),
_uploadImageProvider.imageList.length - 1,
false,
_uploadImageProvider);
UploadImageUtil().startUpload(context, File(file.absolute.path),
widget.model.imageList.length - 1, false, widget.model);
// startUpload(File(file.absolute.path),
// _uploadImageProvider.imageList.length - 1, false);
}
... ... @@ -201,7 +191,7 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
}
///添加图片UI弹出
Future _openModalBottomSheet(context) async {
Future _openModalBottomSheet(context, FileType fileType) async {
final option = await showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
... ... @@ -220,7 +210,12 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
InkWell(
onTap: () {
Utils.getPickPermission(context, () {
_getFromPictureOrCamera(ImageSource.camera);
if (fileType == FileType.image) {
_getImageFromPictureOrCamera(ImageSource.camera);
} else {
_getVideoFromPictureOrCamera(ImageSource.camera);
}
Navigator.pop(context);
}, PermissionGroup.camera);
},
... ... @@ -245,8 +240,13 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
InkWell(
onTap: () {
Utils.getPickPermission(context, () {
// pickAsset(PickType.onlyVideo);
_getFromPictureOrCamera(ImageSource.gallery);
if (fileType == FileType.image) {
pickAsset(PickType.onlyImage);
} else {
_getVideoFromPictureOrCamera(ImageSource.gallery);
}
// //
// _getFromPictureOrCamera(ImageSource.gallery);
Navigator.pop(context);
}, PermissionGroup.photos);
},
... ... @@ -290,6 +290,16 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
});
}
@override
Widget build(BuildContext context) {
return _getGridImg(
widget.model.imageList.length < widget.maxImageNumber
? widget.model.imageList.length + 2
: widget.model.imageList.length,
context,
widget.model.imageList.length == widget.maxImageNumber ? true : false);
}
//查看大图
_showPhotoView(BuildContext context, int index, List imgs,
{isShow = false, List dashName}) async {
... ... @@ -298,220 +308,253 @@ class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
// 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {
// imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';
// }
// _controller = VideoPlayerController.network(imgs[index]);
// chewieController = ChewieController(
// videoPlayerController: _controller,
// // 比例
// // aspectRatio: 16 / 9,
// // 自动播放
// autoPlay: true,
// // 循环
// looping: true,
// );
ijkMediaController.setNetworkDataSource(
imgs[index],
autoPlay: true,
);
Utils.setBarStatus(false, color: Colors.black);
dynamic result = await showGeneralDialog(
context: context,
barrierDismissible: false,
barrierColor: Colors.black,
// barrierColor: Colors.red,
barrierLabel:
MaterialLocalizations.of(context).modalBarrierDismissLabel,
transitionDuration: const Duration(milliseconds: 150),
pageBuilder: (BuildContext context, Animation animation,
Animation secondaryAnimation) {
return Column(
children: [
Container(
height: ScreenUtil().setWidth(100),
color: Colors.black,
child: Row(
children: [
Material(
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Image.asset(Utils.getImgPath('invication_back')),
)),
],
),
),
// Chewie(
// controller: chewieController,
// ),
IjkPlayer(mediaController: ijkMediaController),
Widget child = Stack(
children: <Widget>[
PhotoPreview(
initialIndex: index,
photoList: imgs,
isShow: isShow,
dashName: dashName)
],
);
return child;
});
// Utils.setBarStatus(true, color: Colors.white);
}
@override
Widget build(BuildContext context) {
_uploadImageProvider =
Provider.of<UploadImageProvider>(context, listen: true);
return _getGridImg(
_uploadImageProvider.imageList.length < widget.maxImageNumber
? _uploadImageProvider.imageList.length + 1
: _uploadImageProvider.imageList.length,
context,
_uploadImageProvider.imageList.length == widget.maxImageNumber
? true
: false);
Utils.setBarStatus(true, color: Colors.white);
}
/// 九宫格
Widget _getGridImg(count, context, isLinjie) {
// return
// GridView.builder(
// controller: widget.scrollController,
// // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
// shrinkWrap: true,
// itemCount: count,
// //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// //横轴元素个数
// crossAxisCount: 1,
// //纵轴间距
// mainAxisSpacing: ScreenUtil().setWidth(30),
// //横轴间距
// crossAxisSpacing: ScreenUtil().setWidth(30),
// //子组件宽高长度比例
// // childAspectRatio: 1.0
// ),
// itemBuilder: (BuildContext context, int index) {
//Widget Function(BuildContext context, int index)
var linjie = widget.maxImageNumber;
if (isLinjie) {
linjie = widget.maxImageNumber - 1;
}
if (0 == count - 1 && 0 < linjie) {
return InkWell(
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
_openModalBottomSheet(context);
},
child: Container(
width: ScreenUtil().setWidth(90 * 2),
height: ScreenUtil().setWidth(90 * 2),
decoration: BoxDecoration(
border: Border.all(
color: MyColours.color_E0E0E0,
width: ScreenUtil().setWidth(2)),
),
child: Column(
children: [
VEmptyView(74),
Image.asset(
Utils.getImgPath('add_image'),
width: ScreenUtil().setWidth(32),
height: ScreenUtil().setWidth(32),
),
VEmptyView(10),
Text(
'添加视频',
style: TextStyle(
fontSize: ScreenUtil().setSp(24),
color: MyColours.color_999999),
)
],
)),
);
}
return _uploadImageProvider.imageList.length < 1
? Text('')
: InkWell(
onTap: () {
if (_uploadImageProvider.imageList[0].process == 1) {
_uploadImageProvider.imageQiniuUrlList = [];
if (_uploadImageProvider.imageList[0].qiniuUrl != null) {
for (int i = 0;
i < _uploadImageProvider.imageList.length;
i++) {
_uploadImageProvider.imageQiniuUrlList
.add(_uploadImageProvider.imageList[i].qiniuUrl);
}
return GridView.builder(
controller: widget.scrollController,
// padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
shrinkWrap: true,
itemCount: count,
//SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 3,
//纵轴间距
mainAxisSpacing: ScreenUtil().setWidth(30),
//横轴间距
crossAxisSpacing: ScreenUtil().setWidth(30),
//子组件宽高长度比例
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
var linjie = widget.maxImageNumber;
if (isLinjie) {
linjie = widget.maxImageNumber - 2;
}
if (index == count - 2 && index < linjie) {
return InkWell(
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
_openModalBottomSheet(context, FileType.image);
},
child: Container(
width: ScreenUtil().setWidth(90 * 2),
height: ScreenUtil().setWidth(90 * 2),
decoration: BoxDecoration(
border: Border.all(
color: MyColours.color_E0E0E0,
width: ScreenUtil().setWidth(2)),
),
child: Column(
children: [
VEmptyView(74),
Image.asset(
Utils.getImgPath('add_image'),
width: ScreenUtil().setWidth(32),
height: ScreenUtil().setWidth(32),
),
VEmptyView(10),
Text(
'添加图片',
style: TextStyle(
fontSize: ScreenUtil().setSp(24),
color: MyColours.color_999999),
)
],
)),
);
}
if (index == count - 1 && index <= linjie) {
return InkWell(
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
_openModalBottomSheet(context, FileType.video);
},
child: Container(
width: ScreenUtil().setWidth(90 * 2),
height: ScreenUtil().setWidth(90 * 2),
decoration: BoxDecoration(
border: Border.all(
color: MyColours.color_E0E0E0,
width: ScreenUtil().setWidth(2)),
),
child: Column(
children: [
VEmptyView(74),
Image.asset(
Utils.getImgPath('add_image'),
width: ScreenUtil().setWidth(32),
height: ScreenUtil().setWidth(32),
),
VEmptyView(10),
Text(
'添加视频',
style: TextStyle(
fontSize: ScreenUtil().setSp(24),
color: MyColours.color_999999),
)
],
)),
);
}
///没有上传完成的不可以点击
// _showPhotoView(
// context, 0, _uploadImageProvider.imageQiniuUrlList);
NavigatorUtil.goPlayVideoPage(context,
urlStr: _uploadImageProvider.imageQiniuUrlList[0]);
}
}
},
child: Stack(
children: [
Stack(
alignment: Alignment.topRight,
children: [
// Image.file(
// // _uploadImageProvider.imageList[index].file,
// File(thumbnailPath),
// fit: BoxFit.cover,
// width: ScreenUtil().setWidth(100 * 2),
// height: ScreenUtil().setWidth(100 * 2),
// ),
FutureBuilder(
//显示缩略图
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
print(snapshot.connectionState);
if (snapshot.hasError) print(snapshot.error);
if (snapshot.connectionState == ConnectionState.done) {
return Container(
width: ScreenUtil().setWidth(225),
child: AspectRatio(
// aspectRatio: 1 / 1,
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
return widget.model.imageList.length < 1
? Text('')
: InkWell(
onTap: () {
if (widget.model.imageList[index].process == 1) {
widget.model.imageQiniuUrlList = [];
if (widget.model.imageList[index].qiniuUrl != null) {
if (widget.model.imageList[index].fileType ==
FileType.image) {
List<UploadImgModel> temp = [];
temp.addAll(widget.model.imageList);
temp.removeWhere(
(element) => element.fileType == FileType.video);
for (int i = 0; i < temp.length; i++) {
widget.model.imageQiniuUrlList
.add(temp[i].qiniuUrl);
}
///没有上传完成的不可以点击
_showPhotoView(
context, index, widget.model.imageQiniuUrlList);
} else if (widget.model.imageList[index].fileType ==
FileType.video) {
NavigatorUtil.goPlayVideoPage(context,
urlStr: widget.model.imageList[index].qiniuUrl);
}
},
),
}
}
},
child: Stack(
children: [
Stack(
alignment: Alignment.topRight,
children: [
widget.model.imageList[index].fileType ==
FileType.image
? Image.file(
widget.model.imageList[index].file,
fit: BoxFit.cover,
width: ScreenUtil().setWidth(100 * 2),
height: ScreenUtil().setWidth(100 * 2),
)
: Image.file(
widget.model.imageList[index].thumbnailPath,
fit: BoxFit.cover,
width: ScreenUtil().setWidth(100 * 2),
height: ScreenUtil().setWidth(100 * 2),
)
// : FutureBuilder(
// //显示缩略图
// future: _initializeVideoPlayerFuture,
// builder: (context, snapshot) {
// print(snapshot.connectionState);
// if (snapshot.hasError)
// print(snapshot.error);
// if (snapshot.connectionState ==
// ConnectionState.done) {
// return Container(
// // width: ScreenUtil().setWidth(225),
// child: AspectRatio(
// aspectRatio: 1 / 1,
Offstage(
offstage: _uploadImageProvider.imageList[0].process < 1,
child: GestureDetector(
child: Image.asset(
Utils.getImgPath("delete"),
width: ScreenUtil().setWidth(40),
height: ScreenUtil().setWidth(40),
),
onTap: () {
//点击删除按钮
setState(() {
_uploadImageProvider.imageList.removeWhere(
(element) =>
element ==
_uploadImageProvider.imageList[0]);
_uploadImageProvider.imageQiniuUrlList.removeWhere(
(element) =>
element ==
_uploadImageProvider.imageQiniuUrlList[0]);
});
},
// // aspectRatio: _controller.value.aspectRatio,
// child: VideoPlayer(_controller),
// ),
// );
// } else {
// return Center(
// child: CircularProgressIndicator(),
// );
// }
// },
// ),
,
Offstage(
offstage: widget.model.imageList[index].process < 1,
child: GestureDetector(
child: Image.asset(
Utils.getImgPath("delete"),
width: ScreenUtil().setWidth(40),
height: ScreenUtil().setWidth(40),
),
onTap: () {
//点击删除按钮
setState(() {
widget.model.imageList.removeWhere(
(element) =>
element ==
widget.model.imageList[index]);
widget.model.imageQiniuUrlList.removeWhere(
(element) =>
element ==
widget
.model.imageQiniuUrlList[index]);
});
},
),
),
],
),
),
],
),
Offstage(
offstage: _uploadImageProvider.imageList[0].process == 1,
child: Progress(_uploadImageProvider.imageList[0].process),
)
],
));
// });
// Offstage(
// offstage: widget.model.imageList[index].process == 1,
// child: Progress(widget.model.imageList[index].process),
// ),
widget.model.imageList[index].process == 1
? widget.model.imageList[index].fileType ==
FileType.video
? Align(
alignment: Alignment.center,
child: Image.asset(
Utils.getImgPath('check_g'),
width: ScreenUtil().setWidth(40),
))
: Container()
: Progress(widget.model.imageList[index].process),
widget.model.imageList[index].fileType == FileType.video
? Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.only(
bottom: ScreenUtil().setWidth(10),
right: ScreenUtil().setWidth(10)),
child: Text(
'00:${widget.model.imageList[index].duration}',
style: TextStyle(
color: MyColours.color_333333,
fontSize: ScreenUtil().setSp(24)),
)),
)
: Container()
],
));
});
}
}
... ...
... ... @@ -39,6 +39,7 @@ import 'package:one_key/provider/notebook_detail_change_model.dart';
import 'package:one_key/provider/notebook_detail_model.dart';
import 'package:one_key/provider/order_food_provider.dart';
import 'package:one_key/provider/remark_manager_model.dart';
import 'package:one_key/provider/upload_img_provider.dart';
import 'package:one_key/utils/fluro_convert_utils.dart';
import 'package:provider/provider.dart';
... ... @@ -197,11 +198,13 @@ var handleOnlineCheckEditHandler = new Handler(
bool fromNotify = FluroConvertUtils.string2bool(params["fromNotify"].first);
return ChangeNotifierProvider<OrderFoodProvider>(
create: (_) => OrderFoodProvider(),
child: OnlineCheckEditPage(
fromNotify: fromNotify,
rid: rid,
mid: mid,
));
child: ChangeNotifierProvider<UploadImageProvider>(
create: (_) => UploadImageProvider(),
child: OnlineCheckEditPage(
fromNotify: fromNotify,
rid: rid,
mid: mid,
)));
});
///提前买单查看页面
... ... @@ -297,8 +300,8 @@ var createStorePageHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<Object>> params) {
// CouponSunModel couponSunModel = CouponSunModel.fromJson(json.decode(
// FluroConvertUtils.fluroCnParamsDecode(params["couponSunModel"].first)));
return CreateStorePage();
return ChangeNotifierProvider<UploadImageProvider>(
create: (_) => UploadImageProvider(), child: CreateStorePage());
});
///播放视频页
... ...
... ... @@ -221,15 +221,7 @@ class NavigatorUtil {
context,
"${Routes.play_video}?urlStr=${FluroConvertUtils.fluroCnParamsEncode(urlStr)}",
replace: replace,
transitionBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
curve: Curves.linear,
),
child: child);
},
transitionType:TransitionType.materialFullScreenDialog
);
}
}
... ...
... ... @@ -1038,6 +1038,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0-nullsafety.3"
video_compress:
dependency: "direct main"
description:
name: video_compress
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
video_player:
dependency: "direct main"
description:
... ...
... ... @@ -105,6 +105,8 @@ dependencies:
chewie:
# 视频播放
flutter_ijkplayer: 0.3.5+1
# 视频信息获取
video_compress: ^2.1.1
... ...