Flutter 使用GlobalKey实现父布局调用子布局方法完成视频url切换播放 & 视频url中文件名中文导致无法播放的问题

前言

  video_player: ^2.1.10
  chewie: ^1.2.2

当把chewie封装到一个Widget - VideoPlayer,在父布局调用初始化第一个视频url后,发现不知如何切换视频url。

自己封装的VideoPlayer中封装了切换视频的方法

//切换视频url
switchVideo(String url,bool isAuto) {
    _videoPlayerController.pause();
    setState(() {
      _prepareVideo(url,isAuto);
    });
  }

void _prepareVideo(String url, bool isAuto) {
    _url = url;
    //解决视频url中文件名中文导致无法播放的问题
    if (!url.contains('%')) {
      int index = url.lastIndexOf('/');
      String prefix = url.substring(0, index + 1);
      String subfix = url.substring(index + 1);
      var encodeSubfix = Uri.encodeComponent(subfix).toString();
      _url = prefix + encodeSubfix;
      print('编码后:' + _url);
    }

    _videoPlayerController = VideoPlayerController.network(_url);
    _chewieController = ChewieController(
      videoPlayerController: _videoPlayerController,
      autoPlay: isAuto,
      aspectRatio: widget.aspectRatio,
      //customControls: CustomControls(),
    );
  }

父布局调用子布局方法

关键方法:
final GlobalKey<子布局State> _globalKey = GlobalKey(); //一般子布局state时设置成私有的,此时需要去掉_

取得子组件的state对象: _globalKey.currentState.子布局方法()

父布局使用的是Stateful,在父布局State类中定义GlobalKey变量

 final GlobalKey<VideoPlayerState> _globalKey = GlobalKey();

使用子组件VideoPlayer时,通过key传给子组件

VideoPlayer(
      key: _globalKey,
      playUrl: _courseDatas[_currentVideoIndex].videoUrl,
      autoPlay: true,
    )

切换视频:

  void _play(CourseData course) {
    _currentVieo = course;
    _currentVideoIndex = _courseDatas.indexOf(course);
    print('current index = ${_currentVideoIndex}');
    setState(() {});
    //when is first play,when is switch?
    _globalKey.currentState!.switchVideo(course.videoUrl, true);
  }

url中带有中文导致视频播放器无法播放的问题分析

原因:

在iOS中,访问HTTP/HTTPS时,url中存在中文或者特殊字符时,会导致无法正常的访问到资源或服务,想要解决这个问题,需要对url进行编码。

网络标准RFC 1738规定url中只能包含英文字母和阿拉伯数字,以及一些特殊字符。“只有字母和数字[0-9a-zA-Z]、和特殊符号”$-_.+!*’(),”[不包括双引号]、及某些保留字,才可以不经过编码直接用于URL。”

dart中对url进行编码:

Uri.encodeComponent(url); 
Uri.decodeComponent(encodedUrl); 
    _url = url;
    //解决视频url中文件名中文导致无法播放的问题
    if (!url.contains('%')) {
      int index = url.lastIndexOf('/');
      String prefix = url.substring(0, index + 1);
      String subfix = url.substring(index + 1);
      var encodeSubfix = Uri.encodeComponent(subfix).toString();
      _url = prefix + encodeSubfix;
      print('编码后:' + _url);
    }

注意:

  • 上文中的url编码方式,仅适用于只有最后的文件名中含有中文的情况,且未测试更多复杂的文件名情况
  • 上文中的方式,因为服务器返回的url,部分是已经对中文编码的,部分没有,所以粗暴地根据url文件名部分是否含有%来判定是否已经编码
  • 更好的方式应当检查判定url中是否含有中文以及非RFC 1738规定字符以外的字符,并对这部分字符进行编码
  • 若我直接对全url进行编码,就会对其他字符也编码了, 导致新的url即使在Chrome中也无法访问

参考
https://cloud.tencent.com/developer/article/1329400
https://blog.csdn.net/weixin_34378922/article/details/89616796

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘词木头人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值