您已经看到很多包含视频内容的应用程序,比如带有视频教程的食谱应用程序、电影应用程序和体育相关的应用程序。您是否想知道如何将视频内容添加到您的下一个Flutter应用程序中?

从头开始实现视频功能将是一项繁重的任务。但有几个插件可以让开发者的生活变得轻松。视频播放器插件是可用于 Flutter 的最佳插件之一,可满足这一要求。

在这篇文章中,您将学习如何应用视频播放器插件以及控制视频播放器的不同功能。
我们将讨论这些主题。

  • 创建一个新的视频播放器
  • 添加播放和暂停按钮
  • 创建一个快进
  • 添加一个视频进度指示器
  • 应用视频的字幕

创建一个新的视频播放器

在使用视频播放器插件之前,你应该把它添加到你的pubspec.yaml 文件中。当你打开pubspec.yaml 文件时,你可以看到运行你的应用程序所需的一些配置和依赖性。我们的视频播放器插件应该被添加到dependencies 块下。

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  video_player: 2.1.15  //video player

该插件的当前版本是2.1.15 ,但你可以通过查看插件页面在这里添加最新版本。如果你保存文件时是在VS Code中,它会自动下载该插件。如果不是,打开终端,写flutter pub get 来下载该插件。

进入你想添加该插件的文件,并导入video_player.dart 文件。

import 'package:video_player/video_player.dart';

现在你可以在你的项目中使用视频播放器插件了。

有几种方法来加载视频。让我们从资产中加载我们的例子。在项目的根层创建一个assets/video文件夹,在该文件夹内添加一个视频。然后在pubspec.yaml ,在assets 部分,指定文件路径,如下所示。

assets:
    - assets/video/video.mp4

让我们创建一个单独的有状态的部件,称为VideoPlayerWidget ,以插入我们的视频播放器相关的实现。

你可以在initState 方法中初始化视频播放器,如下所示。另外,别忘了dispose ,让视频播放器做清理工作。

class _VideoPlayerState extends State<VideoPlayerWidget> {
  late VideoPlayerController _videoPlayerController;
  @override
  void initState() {
    super.initState();
    _videoPlayerController = VideoPlayerController.asset(
        'assets/video/video.mp4')
      ..initialize().then((_) {
        setState(() {});
        _videoPlayerController.play();
      });
  }

  @override
  void dispose() {
    _videoPlayerController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: VideoPlayer(_videoPlayerController),
    );
  }
}

VideoPlayerController 必须用late 关键字来指定,因为我们在这一行中仍然没有定义视频播放器控制器,我们将在后面做这个。在initState 里面,videoPlayerController 已经和资产的路径一起被初始化。

当初始化完成后,它改变了状态并重建了小部件。你可以在初始化后开始播放视频。

取代assets ,你可以使用视频的URL。为了访问网络,你应该给Android和iOS添加互联网权限配置。

从根目录下,进入ios/Runner ,打开info.plist 文件。然后,在该文件中添加以下配置。

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

接下来,去android/app/src/main ,并打开AndroidManifest.xml 。然后,向其添加以下代码。

<uses-permission android:name="android.permission.INTERNET"/>

现在你可以把asset 改为network ,并在那里添加视频URL。

  @override
  void initState() {
    super.initState();
    _videoPlayerController =
        VideoPlayerController.network('video_url_here')
          ..initialize().then((_) {
            setState(() {});
            _videoPlayerController.play();
          });
  }

即使初始化已经完成,也应该有办法在用户界面中显示播放器。VideoPlayer widget可以用来做到这一点。为了使它工作,你应该把控制器作为第一个参数传递给VideoPlayer widget。

在显示VideoPlayer widget之前,最好先检查初始化是否成功。

  @override
  Widget build(BuildContext context) {
    return Center(
      child: _videoPlayerController.value.isInitialized ? VideoPlayer(_videoPlayerController) : Container(),
    );
  }

现在你可以看到屏幕上的视频了。但是有一个小问题:它的长宽比不合适。这可以通过使用AspectRatio widget来解决。视频播放器提供了一个适当的视频长宽比,你可以使用这个值来设置为AspectRatio widget。

  @override
  Widget build(BuildContext context) {
    return Center(
      child: _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: 
      _videoPlayerController.value.aspectRatio,
      child: VideoPlayer(_videoPlayerController)
      ) : Container(),
    );
  }

现在你可以看到具有适当长宽比的视频。

添加播放和暂停按钮

首先,让我们把视频播放器小部件包在一个列小部件里面,因为我们应该把播放和暂停按钮放在播放器下面。在播放器小组件之后的列内,让我们在一个Row 小组件内添加两个ElevatedButton 小组件,在这些按钮之间让我们添加一个Padding 小组件以保持一些呼吸空间。

对每个ElevatedButton ,添加相关的Icons ,作为子部件。然后在播放按钮onPressed 的回调里面,你可以参考_videoPlayerController ,并调用play 方法来开始播放视频。在暂停按钮里面,使用pause 方法而不是播放。

现在你可以删除之前在initState 方法里面添加的播放。

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: 
        _videoPlayerController.value.aspectRatio,
        child: VideoPlayer(_videoPlayerController)
        ) : Container(),
        Row(
          mainAxisAlignment: MainAxisAlignment.center, 
          children: [

            ElevatedButton(onPressed: (){
              _videoPlayerController.pause();
            }, child: Icon(Icons.pause)),
              Padding(padding: EdgeInsets.all(2)),
             ElevatedButton(onPressed: (){
              _videoPlayerController.play();
            }, child: Icon(Icons.play_arrow))
          ],
        )
      ],
    );
  }

另外,你可以给按钮添加样式,得到一个看起来很圆的按钮,这通常是在视频播放器中。

 @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        _videoPlayerController.value.isInitialized
            ? AspectRatio(
                aspectRatio: _videoPlayerController.value.aspectRatio,
                child: VideoPlayer(_videoPlayerController))
            : Container(),
        Padding(
          padding: EdgeInsets.all(20),
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
                    fixedSize: MaterialStateProperty.all(Size(70, 70)),
                    shape: MaterialStateProperty.all(RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(100)))),
                onPressed: () {
                  _videoPlayerController.pause();
                },
                child: Icon(Icons.pause)),
            Padding(padding: EdgeInsets.all(2)),
            ElevatedButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent),
                    fixedSize: MaterialStateProperty.all<Size>(Size(80, 80)),
                    shape: MaterialStateProperty.all(RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(100)))),
                onPressed: () {
                  _videoPlayerController.play();
                },
                child: Icon(Icons.play_arrow))
          ],
        )
      ],
    );
  }

创建一个快进

在实现快进之前,让我们思考一下我们需要什么。首先,应该有一个访问当前视频位置/时间的方法和一个设置新值的方法。控制器的seekTo 方法允许我们为视频设置持续时间。

你可以通过视频播放器value 属性访问当前的视频位置,就像下面这样。

ElevatedButton(
       style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
          fixedSize: MaterialStateProperty.all(Size(70, 70)),
          shape: MaterialStateProperty.all(RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(100)))),
                onPressed: () {
                  _videoPlayerController.seekTo(Duration(
                   seconds: _videoPlayerController.value.position.inSeconds   10));
                },
                child: Icon(Icons.fast_forward))

像这样,当用户点击按钮时,你也可以通过减少10 秒来实现向后倒转。

添加一个视频进度指示器

视频播放器插件提供了内置的功能来添加一个进度条以及一些控件。你可以使用VideoProgressIndicator widget来实现这个功能。

作为第一个参数,你必须传递控制器并设置allowScrubbing 属性。allowScrubbing 属性将允许用户通过触摸小组件来滑动进度。通过启用这个,用户可以跳到视频的不同时间戳。此外,你还可以单独控制寻求栏的背景颜色、缓冲区颜色和播放区颜色。

VideoProgressIndicator(
          _videoPlayerController,
          allowScrubbing: true,
          colors: VideoProgressColors(
              backgroundColor: Colors.red,
              bufferedColor: Colors.black,
              playedColor: Colors.blueAccent),
        )

应用视频的字幕

字幕对你的应用程序来说需要两样东西。第一个是不同时期的段落/单词列表,第二个是在视频播放时显示这些标题的方法。为此,应该有一种方法来为时间变化添加一个监听器。

视频播放器包含一个addListener 方法,每秒钟执行一次。你可以使用这个监听器,根据不同的时间段为视频播放器提供字幕。

首先,让我们创建一个Map ,其中包含时间作为一个键,字幕文本作为一个值。在Map ,时间的单位将是秒。

Map<int,String> captions = {
    5:"First subtitle",
    20:"Second subtitle"
  };

接下来,在初始化视频播放器时注册一个Listener 。在回调里面,你可以检查视频是否正在播放,如果视频正在播放,则获得当前的时间为秒。然后,如果当前值包含在captions 地图中,我们可以像下面这样将该值设置为选定的标题。

void initState() {
    super.initState();
    _videoPlayerController =
        VideoPlayerController.asset('assets/video/video.mp4')
        ..addListener(() {
            if(_videoPlayerController.value.isPlaying){
              setState(() { 
                if(captions.containsKey(_videoPlayerController.value.position.inSeconds)){
              selectedCaption = captions[_videoPlayerController.value.position.inSeconds];                
                }
              });
            }
        })
          ..initialize().then((_) {
            setState(() {});
            _videoPlayerController.play();
          });
  }

现在你可以使用ClosedCaption 来设置那个选定的标题。你可以给标题文本添加一些样式,以获得更好的可见性。

 ClosedCaption(
     text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),)

但是,每次标题改变时,建立主部件并不是好的做法。因此,我们应该把标题逻辑提取到一个单独的小部件。

要注册一个监听器,你应该把视频控制器传递给一个新创建的子部件。

从那里,你可以在子部件内注册监听器。

class VCaption extends StatefulWidget {
  const VCaption(
     this.videoPlayerController,
  );
  final VideoPlayerController videoPlayerController;
  @override
  _VCaptionState createState() => _VCaptionState();
}
class _VCaptionState extends State<VCaption> {
  String? selectedCaption = "";
  Map<int,String> captions = {
    5:"First subtitle",
    20:"Second subtitle"
  };

  @override
  void initState() {
    widget.videoPlayerController.addListener(() {
      if(widget.videoPlayerController.value.isPlaying){
              print("Time ${widget.videoPlayerController.value.position.inSeconds}");
              setState(() { 
                if(captions.containsKey(widget.videoPlayerController.value.position.inSeconds)){
              selectedCaption = captions[widget.videoPlayerController.value.position.inSeconds];                
                }
              });
            }
    });
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return ClosedCaption(
      text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),);
  }
}

现在我们可以在之前创建的栏目内添加这个小部件,并将_videoPlayerController 作为参数传递。你可以在把小部件添加到树上之前检查视频播放器是否已经被初始化,就像下面这样。

 _videoPlayerController.value.isInitialized ? VCaption(_videoPlayerController) : Container(),

你可以使用Stack widget在视频顶部显示这些字幕,而不是在视频下面显示那些字幕。字幕以及进度指示器已经被移到了Stack widget里面,以便在视频的顶部显示。

 Stack(
          children: [
            _videoPlayerController.value.isInitialized
                ? AspectRatio(
                    aspectRatio: _videoPlayerController.value.aspectRatio,
                    child: VideoPlayer(_videoPlayerController))
                : Container(),
            Positioned(
              bottom: 2,
              width: MediaQuery.of(context).size.width,
              child: _videoPlayerController.value.isInitialized
                  ? VCaption(_videoPlayerController)
                  : Container(),
            ),
            Positioned(
                bottom: 0,
                width: MediaQuery.of(context).size.width,
                child: VideoProgressIndicator(
                  _videoPlayerController,
                  allowScrubbing: false,
                  colors: VideoProgressColors(
                      backgroundColor: Colors.blueGrey,
                      bufferedColor: Colors.blueGrey,
                      playedColor: Colors.blueAccent),
                ))
          ],
        )

结论

使用视频播放器插件而不是从头开始实现一个视频播放器,可以节省大量的开发时间,并提供所有开箱即用的功能。

如果您想超越这些定制,实现一个具有Material-和Cupertino灵感的漂亮的视频播放器,您可以选择chewie Flutter插件。

以上就是详解Flutter中视频播放器插件的使用教程的详细内容,更多关于Flutter视频播放器插件的资料请关注Devmax其它相关文章!

详解Flutter中视频播放器插件的使用教程的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Flutter中文教程-Cookbook

    Flutter中文网的Cookbook中包含了在编写Flutter应用程序时常见问题及示例。设计基础使用主题共享颜色和字体样式Images显示来自网上的图片用占位符淡入图片使用缓存图Lists创建一个基本list创建一个水平list使用长列表创建不同类型子项的List创建一个gridList处理手势处理点击添加Material触摸水波效果实现滑动关闭导航导航到新页面并返回给新页面传值从新页面返回数据给上一个页面网络从网上获取数据进行认证请求使用WebSockets

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部