flutter 视频解码器fijkplayer使用

       本人做视频监控项目的时候,需要去展示视频流到用户端,一开始使用flutter自带的VideoPlayer播放监控视频,一开始没有发现有什么问题,因为使用多的是Android模拟器,一直没有使用iso模拟器或者真机测试能不能播放,直到开发接近尾声,在ios模拟器上测试的时候发现了问题,视频流为H264的时候能正常播放,但是视频流为H265的时候一直转圈,模拟器和真机播放不了(Android模拟器和真机都是可以播放的)。后来就打算换一个三方插件来调整播放。

  1. 在pubspec.yaml导入引用的fijkplayer插件
     # 视频解码器 软解码
      fijkplayer: ^0.10.1
  2. 状态详解
    状态名 播放器表现
    idle 闲置状态,刚完成构造的 FijkPlayer 处于此状态。
    此状态下播放器占用少量内存,无额外线程启动。
    idle 状态只能通过 setDataSource 转换为 initialized 状态
    initialized 初始化完成状态,和 idle 状态相比,仅是多了输入媒体数据源的信息。 同样无额外线程打开。
    asyncPreparing 异步准备状态,在 initialized 状态调用 prepareAsync 到达此状态。
    这不是一个稳定状态,此状态等待特定任务完成后自动转化为 prepared 状态。
    这一状态的主要准备工作是 探测媒体文件类型,打开媒体文件,打开解码器以及新建解码线程,新建数据 read 线程,打开音频输出设备,新建视频输出线程等。
    prepared asyncPreparing 完成指定任务后自动转化为此状态。
    此状态下已经开始缓冲解码了一部分音视频数据,可以随时进行播放。
    started 媒体(视频、音频)正在播放中。
    paused 媒体(视频、音频)播放暂停。
    completed 媒体(视频、音频)播放完成。 可重新从头开始播放。
    stopped 播放器各种线程占用资源都已经释放。 音频设备关闭。
    end 播放器中所有需要手动释放的内存都释放完成。
    处于此状态的播放器只能等待垃圾回收进行内存释放。
    error 播放器出现错误。

  3. 简单使用代码如下
    import 'package:fijkplayer/fijkplayer.dart';
    import 'package:flutter/material.dart';
    
    class VideoScreen extends StatefulWidget {
      final String url;//视频地址
    
      VideoScreen({@required this.url});
    
      @override
      _VideoScreenState createState() => _VideoScreenState();
    }
    
    class _VideoScreenState extends State<VideoScreen> {
      final FijkPlayer player = FijkPlayer();
    
      _VideoScreenState();
    
      @override
      void initState() {
        super.initState();
        //传入视频地址,视频是否自动播放
        player.setDataSource(widget.url, autoPlay: true);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(title: Text("视频监控")),
            body: Container(
              alignment: Alignment.center,
              child: FijkView(
                player: player,
              ),
            ));
      }
    
      @override
      void dispose() {
        super.dispose();
        player.release();
      }
    }
     
  4. 使用后能够正常播放,但是你发现UI界面太丑了,或者功能不够自己使用,需要更多的功能使用才行,别急!三方提供者早就想到了这里,所以提供了可以自己定的UI界面设置。需要修改panelBuilder更改UI界面,废话不多说,上代码。 首先加入自定的UI界面代码
    class CustomFijkPanel extends StatefulWidget {
      final FijkPlayer player;
      final BuildContext buildContext;
      final Size viewSize;
      final Rect texturePos;
    
      const CustomFijkPanel({
        @required this.player,
        this.buildContext,
        this.viewSize,
        this.texturePos,
      });
    
      @override
      _CustomFijkPanelState createState() => _CustomFijkPanelState();
    }
    
    class _CustomFijkPanelState extends State<CustomFijkPanel> {
    
      FijkPlayer get player => widget.player;
      bool _playing = false;
    
      @override
      void initState() {
        super.initState();
        widget.player.addListener(_playerValueChanged);
      }
    
      void _playerValueChanged() {
        FijkValue value = player.value;
    
        bool playing = (value.state == FijkState.started);
        if (playing != _playing) {
          setState(() {
            _playing = playing;
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        Rect rect = Rect.fromLTRB(
            max(0.0, widget.texturePos.left),
            max(0.0, widget.texturePos.top),
            min(widget.viewSize.width, widget.texturePos.right),
            min(widget.viewSize.height, widget.texturePos.bottom));
    
        return Positioned.fromRect(
          rect: rect,
          child: Container(
            alignment: Alignment.bottomLeft,
            child: IconButton(
              icon: Icon(
                _playing ? Icons.pause : Icons.play_arrow,
                color: Colors.white,
              ),
              onPressed: () {
                _playing ? widget.player.pause() : widget.player.start();
              },
            ),
          ),
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        player.removeListener(_playerValueChanged);
      }
    }

        这里是使用时候的代码

FijkView(
  player: player,
  panelBuilder: (FijkPlayer player, FijkData data, BuildContext context, Size viewSize, Rect texturePos) {
    return CustomFijkPanel(
      player: player,
      buildContext: context,
      viewSize: viewSize,
      texturePos: texturePos);
  },
)

到这里就完成了,简单使用、自定义使用,如果还需要看详细信息,可参考他们提供的官方文档,地址如下:fijkplayer -- Flutter plugin for ijkplayer - fijkplayer -- Flutter plugin for ijkplayer

猜你喜欢

转载自blog.csdn.net/as425017946/article/details/127124281
今日推荐