我使用image_picker录制视频,但是我想限制视频的时间

时间:2019-02-18 02:17:40

标签: flutter

我使用image_picker开发了视频录制。 我们需要限制视频录制时间。

pubspec.yaml      依赖项:       image_picker:^ 0.4.10

[flutter] flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v1.0.1-pre.2, on Mac OS X 10.14.2 18C54, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.0)
[✓] IntelliJ IDEA Ultimate Edition (version 2018.1.7)
[✓] VS Code (version 1.31.1)
[✓] Connected device (2 available)

• No issues found!
exit code 0


// Open the camera for recording Code
ImagePicker.pickVideo(source: ImageSource.camera).then((File file) {
    if (file != null && mounted) {
        var tempFile = file;
    }
});

我想在打开相机之前设置记录时间。 我该怎么办?

2 个答案:

答案 0 :(得分:0)

使用Android上的Intent(ACTION_VIDEO_CAPTURE)和ios中的UIModal启动摄像机录制。它不是可以根据您的需求进行自定义的插件,它也可以满足您的预期。活动和UIModal UI是为此目的而构建的。做您想做的最好的方法是:

  1. 要创建自己的插件并在类中添加一个计时器,该计时器将在记录后触发。计时器结束后,只需停止并保存记录并返回上一个视图即可。您可以在Flutter的Android版here上看到它是如何完成的,然后看看iOS并执行相同的操作。它应该只是几行其他代码。

  2. 修改当前插件以适合您的需求,这并不难。他们不会想要将其合并回代码中,因为它不是该库的大多数用户所需要的功能,因此不会为此请求拉取,但是您可以将其保留在自己的github和分享它。代码为here。请记住,即使这里没有太大变化,您也必须自己维护它。

答案 1 :(得分:0)

@ Coding24h:

以下是捕获视频并播放视频的dart文件,说明:

  1. 导入自我飞镖:
我写的

dart文件:

(1)'GlobalVariables.dart'-包含带有静态变量的类'gv',所有“页面/小部件”都可以访问

(2)'LangStrings.dart'-此应用是多国语言,此dart文件包含不同语言的字符串(英语,中文......)

(3)'ScreenVariables.dart'-包含所有与屏幕相关的变量,例如方向,高度,宽度,物理高度,devicepixelratio ......

(4)'Utilities.dart'-包含可被所有'Pages'使用的'utilities functions',例如,在任何时候,任何地方显示一条祝酒消息。

  1. InitState()方法:这是声明和初始化相机控件的地方。

  2. dispose()方法:在以下情况下,视频录制将手动停止:(1)用户单击“停止”按钮,或(2)用户离开此页面。当用户切换到另一个应用程序或关闭手机屏幕时,视频录制也会自动停止。无论哪种情况,都应将相机控制对象放置在dispose()

  3. didChangeAppLifecycleState()方法:如果应用程序进入后台,则暂停视频播放。

  4. funTimerVideo()方法:一个计时器,它每秒更改一次“ Slider”的位置。 (如果该用户有录像限制,则可以创建另一个计时器来停止录像)

  5. funSelectVideo()方法:从图库中选择视频。

  6. funCameraStart()方法:开始捕获图片以供将来预览,然后开始捕获视频

  7. funCameraStop()方法:停止捕获视频,如果满足以下条件,则可以调用此方法:(1)用户按下“ Video Recording Stop”按钮,或者(2)我在“ funTimerVideo”中提到的“另一个计时器” '在超出记录限制时调用此方法。

屏幕捕获(视频播放器和捕获屏幕):

enter image description here

程序源代码(仅适用于视频播放器和捕获页面):

// Import Flutter Darts
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import "package:threading/threading.dart";
import 'package:video_player/video_player.dart';

// Import Self Darts
import 'GlobalVariables.dart';
import 'LangStrings.dart';
import 'ScreenVariables.dart';
import 'Utilities.dart';

// Import Pages
import 'BottomBar.dart';

// Home Page
class ClsHome extends StatefulWidget {
  @override
  _ClsHomeState createState() => _ClsHomeState();
}
class _ClsHomeState extends State<ClsHome> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

  // Declare Camera
  CameraController ctlCamera;

  // Var for Video
  bool bolVideoPaused = true;

  @override
  void initState() {
    super.initState();
    print("Init State Started");
    if (gv.bolHomeFirstInit) {
      // This page is called by navigator.push twice, do nothing on the first call
      gv.bolHomeFirstInit = false;
    } else {
      // Not the first time call of Init, do Init
      WidgetsBinding.instance.addObserver(this);

      try {
        // Try to dispose old Camera Control
        ctlCamera.dispose();
        print("Camera Disposed 1");
      } catch (err) {
        print("Camera Dispose Error: " + err.toString());
      }
      try {
        // Declare New Camera Control
        ctlCamera = CameraController(gv.cameras[1], ResolutionPreset.high);
        ctlCamera.initialize().then((_) {
          if (!mounted) {
            ut.showToast('1:' + ls.gs('SystemErrorOpenAgain'), true);
            return;
          }
          setState(() {});
          print('Controller Inited');
        });
      } catch (err) {
        ut.showToast('2:' + ls.gs('SystemErrorOpenAgain'), true);
        print("Camera Init Error: " + err.toString());
      }
      try {
        gv.threadHomeVideo = new Thread(funTimerVideo);
        gv.threadHomeVideo.start();
        print('New Video Timer Started');
      } catch (err) {
        ut.showToast('3:' + ls.gs('SystemErrorOpenAgain'), true);
        print('New Video Timer Error: ' + err.toString());
      }
    }
    print("Init State Ended");
  }

  @override
  void dispose() async {
    super.dispose();
    print("Dispose Started");
    if (gv.bolHomeFirstDispose) {
      gv.bolHomeFirstDispose = false;
    } else {
      WidgetsBinding.instance.removeObserver(this);

      try {
        await funCameraStop();
        ctlCamera?.dispose();

        print("Camera Disposed");
      } catch (err) {
        //
        print("Play Video Dispose Error 1: " + err.toString());
      }
      try {
        // gv.ctlVideo?.dispose();
        gv.ctlVideo.pause();
        // gv.threadPageHomeVideo.abort();
        // print('Thread Video Aborted');
      } catch (err) {
        //
        print("Play Video Dispose Error 2: " + err.toString());
      }
      // print('Controller dispose');
    }
    print("Dispose Ended");
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
      _lastLifecycleState = state;
      print('*****   Life Cycle State: ' + _lastLifecycleState.toString() + '   *****');
      if (_lastLifecycleState.toString() == 'AppLifecycleState.paused') {
        try {
          if (gv.ctlVideo.value.isPlaying) {
            bolVideoPaused = true;
            gv.ctlVideo.pause();
          }
          setState(() {});
        } catch (err) {
          //
        }
      } else if (_lastLifecycleState.toString() == 'AppLifecycleState.resumed') {
      }
  }

  // Timer to setState Video Play Position
  void funTimerVideo() async {
    while (true) {
      await Thread.sleep(1000);
      try {
        if (gv.ctlVideo.value.isPlaying) {
          gv.dblHomeVDSliderValueMS =
              gv.ctlVideo.value.position.inMilliseconds.toDouble();
          setState(() {});
        }
      } catch (err) {
        // Video Not Yet Ready, Do Nothing
      }
    }
  }

  // Select Video from External Storage
  funSelectVideo() async {
    print('Select Video Started');
    String filePath = '';
    filePath = await FilePicker.getFilePath(type: FileType.VIDEO);
    if (filePath != '') {
      try {
        // Declare Video if a video file is selected
        gv.ctlVideo = VideoPlayerController.file(File(filePath))
          ..initialize().then((_) {
            // Set Video Looping
            gv.ctlVideo.setLooping(true);

            // Get Video Duration in Milliseconds
            gv.intHomeVDMS = gv.ctlVideo.value.duration.inMilliseconds;
            setState(() {});
            print('Video Inited');
          });
      } catch (err) {
        print('Video Init Error: ' + err.toString());
        gv.intHomeVDMS = 0;
        ut.showToast(ls.gs('VideoErrorUnsupport'), true);
      }
    } else {
      print('No Video Selected');
      setState(() {});
    }
    print('Select Video Ended');
  }

  // The Widget that show the Video Player
  Widget ctnVideoPlayer() {
    try {
      double dblHeight = sv.dblBodyHeight / 1.8;
      print('Before Check Video Init');
      if (gv.ctlVideo.value.initialized) {
        print('Before Check Video AspectRatio');
        if (gv.ctlVideo.value.aspectRatio < 1) {
          dblHeight = sv.dblBodyHeight / 1.25;
        }
        print('Before Return ctnVideoPlayer');
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
              padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
              height: dblHeight,
              width: sv.dblScreenWidth,
              child: Center(
                child: AspectRatio(
                  aspectRatio: gv.ctlVideo.value.aspectRatio,
                  child: VideoPlayer(gv.ctlVideo),
                ),
              ),
            ),
            objVideoSlider(),
          ],
        );
        print('After Return ctnVideoPlayer');
      } else {
        print('Before Return EMPTY ctnVideoPlayer');
        return Container(
          // color: Colors.white,
          height: dblHeight,
          width: sv.dblScreenWidth,
          child: Center(
            child: Text(ls.gs('SelectVideo')),
          ),
        );
        print('After Return EMPTY ctnVideoPlayer');
      }
    } catch (err) {
      print('Page Home ctnVideoPlayer() : ' + err.toString());
      return Container(
        // color: Colors.white,
        height: sv.dblBodyHeight / 1.8,
        width: sv.dblScreenWidth,
        child: Center(
          child: Text(ls.gs('SelectVideo')),
        ),
      );
    }
  }

  // function when Play or Pause clicked
  funPlayVideo() async {
    try {
      if (gv.ctlVideo.value.initialized) {
        if (gv.ctlVideo.value.isPlaying) {
          bolVideoPaused = true;
          gv.ctlVideo.pause();

          // Stop Camera Recording
          funCameraStop();
        } else {
          bolVideoPaused = false;
          gv.ctlVideo.play();

          // Start Camera Recording
          funCameraStart();
        }
        setState(() {});
      } else {
        // Do Nothing
      }
    } catch (err) {
      // Do Nothing
    }
  }

  // function when Forward 15 seconds clicked
  funForwardVideo() async {
    try {
      if (gv.ctlVideo.value.initialized) {
        gv.ctlVideo.seekTo(gv.ctlVideo.value.position + Duration(seconds: 15));
        setState(() {});
      } else {
        // Do Nothing
      }
    } catch (err) {
      // Do Nothing
    }
  }

  // function when Backward 15 seconds clicked
  funBackwardVideo() async {
    try {
      if (gv.ctlVideo.value.initialized) {
        gv.ctlVideo.seekTo(gv.ctlVideo.value.position - Duration(seconds: 15));
        setState(() {});
      } else {
        // Do Nothing
      }
    } catch (err) {
      // Do Nothing
    }
  }

  // Widget to show the Slider of the playing position of Video
  Widget objVideoSlider() {
    try {
      if (gv.ctlVideo.value.initialized) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(' '),
            Text(gv.ctlVideo.value.position.inHours.toString() +
                ":" +
                (gv.ctlVideo.value.position.inMinutes % 60)
                    .toString()
                    .padLeft(2, '0') +
                ":" +
                (gv.ctlVideo.value.position.inSeconds % 60)
                    .toString()
                    .padLeft(2, '0')),
            Expanded(
              child: CupertinoSlider(
                min: 0.0,
                max: gv.intHomeVDMS.toDouble(),
                divisions: (gv.intHomeVDMS / 1000).toInt(),
                value: gv.dblHomeVDSliderValueMS,
                onChanged: (double dblNewValue) {
                  objVideoSliderChanged(dblNewValue);
                },
              ),
            ),
            Text(gv.ctlVideo.value.duration.inHours.toString() +
                ":" +
                (gv.ctlVideo.value.duration.inMinutes % 60)
                    .toString()
                    .padLeft(2, '0') +
                ":" +
                (gv.ctlVideo.value.duration.inSeconds % 60)
                    .toString()
                    .padLeft(2, '0')),
            Text(' '),
          ],
        );
      } else {
        return Container();
      }
    } catch (err) {
      return Container();
    }
  }

  // Function when Slider Changed Manually
  objVideoSliderChanged(dblNewValue) {
    gv.dblHomeVDSliderValueMS = dblNewValue;
    gv.ctlVideo
        .seekTo(Duration(milliseconds: gv.dblHomeVDSliderValueMS.toInt()));
    setState(() {});
  }

  // Function Start Camera
  void funCameraStart() async{
    // Declare File Name
    DateTime dtTimeStamp() => DateTime.now();
    String strTimeStamp = DateFormat('yyyyMMdd_kkmmss').format(dtTimeStamp());
    String strMovieFile = gv.strMoviePath + '/' + strTimeStamp + '.mp4';
    gv.strImageFile = gv.strImagePath + '/' + strTimeStamp;
    print('File Path: ' + strMovieFile);

    try {
      await ctlCamera.takePicture(gv.strImageFile + '_01.jpg');
      await ctlCamera.startVideoRecording(strMovieFile);
    } catch(err) {
      ut.showToast('4:' + ls.gs('SystemErrorOpenAgain'), true);
    }
  }
  // Function Stop Camera
  void funCameraStop() async{
    try {
      await ctlCamera.stopVideoRecording();
    } catch(err) {
      // ut.showToast('5:' + ls.gs('SystemErrorOpenAgain'), true);
    }
    try {
      await ctlCamera.takePicture(gv.strImageFile + '_02.jpg');
    } catch(err) {
      // ut.showToast('5:' + ls.gs('SystemErrorOpenAgain'), true);
    }
  }

  // Main Widget
  @override
  Widget build(BuildContext context) {
    try {
      if (ctlCamera != null) {
        if (!ctlCamera.value.isInitialized) {
          print('return Container');
          return Container();
        }
        print('Before Return');
        return Scaffold(
          appBar: PreferredSize(
            child: AppBar(
              title: Text(
                ls.gs('Player'),
                style: TextStyle(fontSize: sv.dblDefaultFontSize),
              ),
            ),
            preferredSize: new Size.fromHeight(sv.dblTopHeight),
          ),
          body: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                ctnVideoPlayer(),
                Stack(children: <Widget>[
                  Container(
                    // color: Colors.white,
                    height: sv.dblBodyHeight / 25,
                    width: sv.dblScreenWidth,
                    child: Center(
                      child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[
                            Text('          '),
                            AspectRatio(
                              aspectRatio: ctlCamera.value.aspectRatio,
                              child: CameraPreview(ctlCamera),
                            ),
                          ]),
                    ),
                  ),
                  Container(
                    // color: Colors.white,
                    height: sv.dblBodyHeight / 25,
                    width: sv.dblScreenWidth,
                    child: Center(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          RaisedButton(
                            onPressed: () => funSelectVideo(),
                            child: Icon(Icons.folder_open),
                          ),
                          Text(' '),
                          RaisedButton(
                            onPressed: () => funBackwardVideo(),
                            child: Icon(FontAwesomeIcons.angleDoubleLeft),
                          ),
                          Text(' '),
                          RaisedButton(
                            onPressed: () => funPlayVideo(),
                            child: bolVideoPaused
                                ? Icon(Icons.play_arrow)
                                : Icon(Icons.pause),
                          ),
                          Text(' '),
                          RaisedButton(
                            onPressed: () => funForwardVideo(),
                            child: Icon(FontAwesomeIcons.angleDoubleRight),
                          ),
                        ],
                      ),
                    ),
                  ),
                ])
              ]),
          bottomNavigationBar: ClsBottom(),
        );
      } else {
        return Container();
      }
    } catch (err) {
      print('PageHome Error build: ' + err.toString());
      return Container();
    }
  }
}