main.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import 'dart:io';
  2. import 'dart:async';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_ali_camera/camera_export.dart';
  5. import 'package:path_provider/path_provider.dart';
  6. import 'package:path/path.dart' as path;
  7. void main() async {
  8. WidgetsFlutterBinding.ensureInitialized();
  9. runApp(FirstPage());
  10. }
  11. class FirstPage extends StatefulWidget {
  12. @override
  13. State<StatefulWidget> createState() {
  14. return FirstPageState();
  15. }
  16. }
  17. class FirstPageState extends State<FirstPage> {
  18. @override
  19. Widget build(BuildContext context) {
  20. return MaterialApp(
  21. home: FirstState(),
  22. );
  23. }
  24. }
  25. class FirstState extends StatelessWidget {
  26. @override
  27. Widget build(BuildContext context) {
  28. return Scaffold(
  29. body: Center(
  30. child: RawMaterialButton(
  31. child: Text(
  32. "push",
  33. ),
  34. onPressed: () {
  35. Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
  36. return MyApp();
  37. }));
  38. },
  39. ),
  40. ),
  41. );
  42. }
  43. }
  44. class MyApp extends StatefulWidget {
  45. @override
  46. _MyAppState createState() => _MyAppState();
  47. }
  48. class _MyAppState extends State<MyApp> {
  49. final Completer<CameraViewController> _controller = Completer<CameraViewController>();
  50. StreamSubscription _durationSubscription; // 播放进度订阅
  51. final int duration = 5000;
  52. double value = 0;
  53. bool recording = false;
  54. List<String> recordPath = List();
  55. @override
  56. void initState() {
  57. super.initState();
  58. }
  59. @override
  60. void dispose() {
  61. _durationSubscription.cancel();
  62. _dispose();
  63. super.dispose();
  64. }
  65. void _dispose() async {
  66. if (_controller.isCompleted) {
  67. CameraViewController controller = await _controller.future;
  68. controller.dispose();
  69. }
  70. }
  71. void _onPlatformViewCreated(CameraViewController controller) async {
  72. await controller.create(
  73. recordOption: CameraRecordOption(
  74. videoWidth: 720, videoHeight: 1280, quality: VideoQuality.SD));
  75. _durationSubscription = controller.recordUpdate.listen((result) {
  76. print("record update" + result.toString());
  77. if (result.containsKey("path")) {
  78. print("录制完成");
  79. setState(() {
  80. recording = false;
  81. recordPath.add(result['path']);
  82. });
  83. }
  84. });
  85. }
  86. static Future<String> _findLocalPath() async {
  87. final directory = Platform.isAndroid
  88. ? await getExternalStorageDirectory()
  89. : await getApplicationDocumentsDirectory();
  90. return directory.path;
  91. }
  92. Future<void> _record(CameraViewController controller) async {
  93. setState(() {
  94. recording = true;
  95. });
  96. String mp4Path = path.join(await _findLocalPath(), "1.mp4");
  97. controller.startRecord(duration, mp4Path);
  98. }
  99. void _compose(CameraViewController controller) async {
  100. if (recordPath.length == 0) return;
  101. String resultPath = path.join(await _findLocalPath(), "result.mp4");
  102. bool success = await controller.startCompose(
  103. resultPath,
  104. null,
  105. recordPath,
  106. recordPath.map((f) => duration).toList(),
  107. CameraComposeOption(
  108. outputWidth: 480,
  109. outputHeight: 480 * 16 ~/ 9,
  110. videoCodecs: VideoCodecs.H264_HARDWARE,
  111. quality: VideoQuality.SD,
  112. frameRate: 20,
  113. bitrate: 500000),
  114. );
  115. print("compose result: ${success ? "successful" : "failed"}");
  116. }
  117. @override
  118. Widget build(BuildContext context) {
  119. return Scaffold(
  120. backgroundColor: Colors.white,
  121. appBar: AppBar(
  122. title: const Text('Plugin example app'),
  123. ),
  124. body: ListView(
  125. padding: EdgeInsets.symmetric(horizontal: 10),
  126. children: <Widget>[
  127. SizedBox(
  128. width: double.maxFinite,
  129. height: 200,
  130. child: CameraView(
  131. onCameraViewCreated: (controller) {
  132. _controller.complete(controller);
  133. _onPlatformViewCreated(controller);
  134. },
  135. ),
  136. ),
  137. FutureBuilder(
  138. future: _controller.future,
  139. builder: (ctx, controller) {
  140. if (controller.hasData) {
  141. return Row(
  142. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  143. children: <Widget>[
  144. IconButton(
  145. icon: Icon(
  146. Icons.play_arrow,
  147. size: 26,
  148. ),
  149. onPressed: () {
  150. if (!recording) controller.data.startPreview();
  151. }),
  152. IconButton(
  153. icon: Icon(
  154. Icons.pause,
  155. size: 26,
  156. ),
  157. onPressed: () {
  158. if (!recording) controller.data.stopPreview();
  159. }),
  160. IconButton(
  161. icon: Icon(
  162. Icons.switch_camera,
  163. size: 26,
  164. ),
  165. onPressed: () {
  166. if (!recording) controller.data.switchCamera();
  167. }),
  168. IconButton(
  169. icon: Icon(
  170. recording ? Icons.stop : Icons.fiber_manual_record,
  171. size: 26,
  172. ),
  173. onPressed: () {
  174. if (!recording) _record(controller.data);
  175. }),
  176. IconButton(
  177. icon: Icon(
  178. Icons.settings,
  179. size: 26,
  180. ),
  181. onPressed: () {
  182. if (!recording) _compose(controller.data);
  183. }),
  184. ],
  185. );
  186. }
  187. return Container();
  188. },
  189. ),
  190. SizedBox(
  191. height: 5,
  192. ),
  193. FutureBuilder(
  194. future: _controller.future,
  195. builder: (ctx, controller) {
  196. if (controller.hasData) {
  197. return Row(
  198. children: <Widget>[
  199. Text("美颜0-100"),
  200. Expanded(
  201. child: Slider(
  202. value: value,
  203. max: 100,
  204. onChanged: (value) {
  205. controller.data.setBeauty(value.toInt());
  206. setState(() {
  207. this.value = value;
  208. });
  209. }),
  210. ),
  211. ],
  212. );
  213. }
  214. return Container();
  215. },
  216. ),
  217. ],
  218. ),
  219. );
  220. }
  221. }