前言
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