前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter插件式解耦架构在播放器领域中的应用

Flutter插件式解耦架构在播放器领域中的应用

原创
作者头像
晨之阴影
修改2021-12-06 16:04:46
9001
修改2021-12-06 16:04:46
举报
文章被收录于专栏:晨光的Code晨光的Code

1. 项目背景

播放器作为应用内使用最频繁的SDK之一,尝尝需要应对多种应用场景,因此如何通过合理设计框架,从而根据各个团队的需求开发出针对性的业务插件,是播放器SDK应用使用多种实用场景的重要思路。

2. 解耦架构

解耦架构
解耦架构

可以看到,在解耦架构下,所有的第三方功能均从内核中拆出,如画中画、换链、控制面板、上报等,使得内核保持纯粹,并且在需要的时候可以组合多个插件。

这里以UI控制面板为例,阐述一下Flutter场景下的播放器UI插件化开发的应用。

UI控制面板
UI控制面板
代码语言:txt
复制
├── base
│   └── ftp_panel_base.dart
├── components
│   ├── ftp_hide_timer.dart
│   ├── ftp_play_pause.dart
│   └── ftp_progress_bar.dart
└── utils
│   └── ftp_ui_utils.dart
├── ftp_panel.dart

其中ftp_panel_base.dart为基础抽象类,提供FTPController给插件访问,最终由组合出来的StatefulWidget实现方法。

代码语言:txt
复制
abstract class FTPPanelBase {
  FTPPlayerController get playerController;
  FTPPlayerValue get playerValue => playerController.value;
}

而播放按钮PlayPauseMixin采用Dart中mixin的写法,mix的对象为State<T>,这样最后封装Panel的时候可以任意组合相关插件,而通过声明实现FTPPanelBase抽象类,即可访问playerController实例,直接获取播放状态,并控制播放和暂停。

代码语言:txt
复制
mixin PlayPauseMixin<T extends StatefulWidget> on State<T>
    implements HideTimer, FTPPanelBase {
	GestureDetector buildPlayPause(Color iconColor) {
    return GestureDetector(
      onTap: playPause,
      child: Container(
        height: 48.0,
        color: Colors.transparent,
        margin: const EdgeInsets.only(left: 8.0, right: 4.0),
        padding: const EdgeInsets.only(
          left: 12.0,
          right: 12.0,
        ),
        child: Icon(
            playerController.value.isPlaying ? Icons.pause : Icons.play_arrow,
            color: iconColor),
      ),
    );
  }
}

而在使用这些UI组件时,通过with的方式对mixin和抽象接口类进行组合,即可访问UI组件的实现方法,快速组合出可用的控制面板UI。

代码语言:txt
复制
class FTPDefaultPanelState extends State<FTPDefaultPanel>
    with
        FTPPanelBase,
        CenterPlayPauseMixin,
        HideTimerMixin,
        HideTimer,
        ExpandButtonMixin,
        MuteButtonMixin,
        SpeedButtonMixin,
        TotalPositionMixin,
        CurrentPositionMixin,
        ProgressBarMixin,
        PlayPauseMixin,
        SingleTickerProviderStateMixin {
  @override
  FTPPlayerController get playerController => widget.playerController;
  
  AnimatedOpacity _buildBottomBar(
    BuildContext context,
  ) {
    final iconColor = Theme.of(context).textTheme.button!.color;
    return AnimatedOpacity(
      opacity: hideStuff ? 0.0 : 1.0,
      duration: const Duration(milliseconds: 300),
      child: Container(
        color: Colors.white,
        height: barHeight,
        child: Row(
          children: <Widget>[
            buildPlayPause(iconColor!),
            const SizedBox(width: 12),
            buildCurPosition(iconColor),
            buildProgressBar(null),
            buildTotalPosition(iconColor),
            buildSpeedButton(iconColor),
            buildMuteButton(iconColor),
            buildExpandButton(iconColor),
          ],
        ),
      ),
    );
  }

  @override
  late bool isFullScreen = false;

  @override
  void setPlayPauseListener(FTPPlayPauseListener ftpPlayPauseListener) {
    super.setPlayPauseListener(widget.ftpPlayPauseListener);
  }

接下来以换链为例阐述非UI控制插件的实现方式。

这里通过extension的方式为FTPPlayerController增加了使用腾讯云vid换链功能的方法,只要import对应的扩展方法,即可无缝实用插件方法。

代码语言:txt
复制
extension VideoInfoExtension on FTPPlayerController {
  static const String BASEURL = 'https://playvideo.qcloud.com/getplayinfo/v4/';

  /// 使用设置播放地址
  Future<int?> setDataSourceWithVideoId(
      SuperPlayerVideoModel superPlayerVideoId) async {
    if (superPlayerVideoId.fileId!.isEmpty ||
        superPlayerVideoId.appId!.isEmpty) {
      return -1;
    }
    var videoInfo = await VideoInfo.getVideoInfo(superPlayerVideoId);
    return setDataSource(videoInfo.videoUrl ?? '');
  }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 项目背景
  • 2. 解耦架构
相关产品与服务
播放器 SDK
播放器 SDK 是音视频终端 SDK(腾讯云视立方)的子产品之一,提供直播、点播场景的视频播放能力,支持Web/H5、iOS、Android、Flutter平台。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档