Flutter:获取视频的第一帧

时间:2019-01-19 07:54:16

标签: dart flutter flutter-layout

如何在Flutter项目中获取本地视频文件的第一帧? 这是我的代码:

ImagePicker.pickVideo(source: ImageSource.camera).then((File file) {
  if (file != null && mounted) {
    //I got the video file here, but I want to get the first frame of the video.
  }
 });
},

5 个答案:

答案 0 :(得分:0)

我使用发布的thumbnails实现了这一点。

String thumb = await Thumbnails.getThumbnail(
    thumbnailFolder:'[FOLDER PATH TO STORE THUMBNAILS]', // creates the specified path if it doesnt exist
    videoFile: '[VIDEO PATH HERE]',
    imageType: ThumbFormat.PNG,
    quality: 30);

/*
* thumbnailFolder property can be omitted if you dont wish to keep the generated thumbails past each usage
*/

答案 1 :(得分:0)

String thumb = await Thumbnails.getThumbnail(
    thumbnailFolder:'[FOLDER PATH TO STORE THUMBNAILS]', // creates the specified path if it doesnt exist
    videoFile: '[VIDEO PATH HERE]',
    imageType: ThumbFormat.PNG,
    quality: 30);

/*
* thumbnailFolder property can be omitted if you dont wish to keep the generated thumbails past each usage
*/

答案 2 :(得分:0)

下面的代码使用video_thumbnail插件,该插件在其文档中显示了对Android和ios的支持

Future genThumbnailFile() async{
    final thumbnail = await VideoThumbnail.thumbnailFile(
        video:
        _video.path,
        // thumbnailPath: _tempDir,
        imageFormat: ImageFormat.JPEG,
        //maxHeightOrWidth: 0,
        maxHeight:3,
        maxWidth: 2,
        quality: 10);
    setState(() {
      final file = File(thumbnail);
      filePath = file.path;
    });
  }

然后按如下所示在“图像”小部件中使用此filePath变量

filePath != null
                      ? Container(
                      width:400,
                      height: 200,
                      child: Image(image: AssetImage(filePath)))
                      : Text('No Floatting Button Click')

答案 3 :(得分:0)

使用export_video_frame,它适用于IOS。

var duration = Duration(seconds: 1);
var image = await ExportVideoFrame.exportImageBySeconds(widget.file, duration, 0);

答案 4 :(得分:0)

这是一个可以用于此的视图示例

import 'dart:io';

import 'package:export_video_frame/export_video_frame.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_compress/video_compress.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail/video_thumbnail.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String thumbNailImage = '';
  late VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset('assets/videos/butterfly.mp4')
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {
          Future.delayed(Duration.zero, () async {
            final byteData =
                await rootBundle.load("assets/videos/butterfly.mp4");
            Directory tempDir = await getTemporaryDirectory();

            File tempVideo = File("${tempDir.path}/assets/videos/butterfly.mp4")
              ..createSync(recursive: true)
              ..writeAsBytesSync(byteData.buffer
                  .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));

            final thumbnailFile = await VideoCompress.getFileThumbnail(
                tempVideo.path,
                quality: 50, // default(100)
                position:
                    (_controller.value.duration.inMilliseconds) // default(-1)
                );

            var duration = _controller.value.duration;
            var image = await ExportVideoFrame.exportImageBySeconds(
                tempVideo, Duration(seconds: 3), 0);

            thumbNailImage = image.path;

            // final fileName = await VideoThumbnail.thumbnailFile(
            //   video: tempVideo.path,
            //   thumbnailPath: (await getTemporaryDirectory()).path,
            //   imageFormat: ImageFormat.JPEG,
            //   timeMs: _controller.value.duration.inMilliseconds,
            //   maxHeight: MediaQuery.of(context).size.height.toInt(),
            //   //quality: 100,
            // );
            //thumbNailImage = fileName!;
            print(
                "file name = $thumbNailImage video duration = ${_controller.value.duration.inMilliseconds}");
            setState(() {});
          });
        });
      });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: thumbNailImage != ''
          ? Image.file(
              File(thumbNailImage),
              fit: BoxFit.contain,
            )
          : Container(), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

这些是需要的包

video_player: ^2.1.12
path_provider: ^2.0.2
export_video_frame: ^0.0.6