类型 | video IOS | video Android | UC SAC | UC HAC | PlayBuddy | Glue |
---|---|---|---|---|---|---|
平台 | IOS手淘 | android手淘 | android手淘>=5.3.2 | android手淘>=5.4.9 | android手淘>=5.3.2 | android手淘<5.3.2 |
loading | 可定制 | 可定制 | 无 | 可定制 | 不可定制,丑陋 | 有 |
控件可定制性 | 可以 | 可以 | 不可以 | 可以 | 不可以 | 不可以 |
全屏 | 支持竖全屏 | 不支持 | 支持竖全屏 | 可以 | 支持 | 支持 |
模拟全屏 | 支持 | 支持 | 不支持 | 有bug | -- | -- |
兼容性 | 好 | 较好 | 较好 | 好 | 较好 | 一般,不兼容 android 5.0及以上 |
上面介绍了手淘中可供 WebView 选择的播放器,对于业务方而言迫切需要一个解决方,无需关心底层差异。为此,我们屏蔽移动端不同系统平台、宿主环境、播放器的实现细节和兼容性问题,提供统一的接口和事件,具体如下:
接下来谈谈在开发过程中遇到的各种小问题及其解决办法。
webview.allowsInlineMediaPlayback = YES;
* iPhone Safari 在 IOS >= 8 的系统中,有人也提出了一个[方案](https://link.zhihu.com/?target=https%3A//github.com/bfred-it/iphone-inline-video)
video::-webkit-media-controls-start-playback-button {
display: none;
}
_timeUpdate(e) {
var currentTime = this.getCurrentTime();
// 判断是否为首帧
if (currentTime !== undefined && currentTime !== 0) {
this.fire('firstpaint');
}
}
_playing() {
if (Env.os.ios) {
this.fire('firstpaint');
}
}
isWork() {
if (videoEl.readyState === 0 && videoEl.videoWidth === 0) {
return false;
}
return true;
}
方案一
:为了支持横全屏,我们使用 css3 的 rotate 对视频区域进行90度旋转,并且调用 bridge 接口隐藏 native 顶部的 navibar,并对自定义控件进行响应优化调整。基本到达 native全屏效果。当然顶部状态栏不能隐藏还是有些小瑕疵。同时旋转之后元素的 z-index失效,导致视频覆盖控件问题,可以通过设置 -webkit-transform: translate3d(0,0,0) 来修复requestFullscreen() {
var element = this.el[0];
var method = FullscreenApi.requestFullscreen;
if (method) {
element[method]();
} else if (element.webkitEnterFullscreen || element.enterFullScreen) {
element.webkitEnterFullscreen && element.webkitEnterFullscreen();
element.enterFullScreen && element.enterFullScreen();
} else {
// 模拟全屏
// enterFullWindow();
}
}
// 模拟全屏js核心代码
_mockFullscreen() {
if (curEl.hasClass('normal')) {
this.fullscreen = false;
playerEl.css({
width: this.originWidth,
height: this.originHeight,
left: 0
}).removeClass('fullscreen');
wrapperEl.css({
width: this.wrapperOriginWidth,
height: this.wrapperOriginHeight
});
videoEl.css('height', '100%');
curEl.removeClass('normal');
contentEl.removeClass('fullscreen');
} else {
this.fullscreen = true;
this.originWidth = playerEl.width();
this.originHeight = playerEl.height();
this.wrapperOriginWidth = wrapperEl.width();
this.wrapperOriginHeight = wrapperEl.height();
playerEl.css({
width: $(window).height(),
height: $(window).width(),
left: $(window).width()
}).addClass('fullscreen');
wrapperEl.css({
width: $(window).height(),
height: $(window).width()
});
videoEl.css('height', videoEl.height() - controlsHeight);
curEl.addClass('normal');
contentEl.addClass('fullscreen');
}
}
* 效果图:
* 预览地址(请用手淘扫码):
方案二
。方案一只是模拟了横全屏效果,对于追求完美的处女座不能忍。还有其他方案吗?有时候只需要转换下思维,问题即可迎刃而解。既然是横屏播放,只需要让 WebView 横屏即可,同时在横屏之后重新调整控件即可,关键手淘提供了打开应用横全屏的接口。注意点:横屏之后需要禁止页面滚动,要不然全屏就露馅了,因为本质还是个 WebView。if (this.transverseFullScreen) {
if (curEl.hasClass('normal')) {
curEl.removeClass('normal');
this._transverseFullScreen(false).then(() => {
$('body').removeClass('co-fullscreen').attr({ height: 'auto' });
this.videoWrapperEl.height(this.videoOriginHeight).removeClass('fullscreen');
this.player.fire('transversefullscreen', { fullscreen: false });
this.resize();
} else {
curEl.addClass('normal');
this._transverseFullScreen(true).then(() => {
$('body').addClass('co-fullscreen').attr({ height: win.height() });
this.videoWrapperEl.height(win.height()).addClass('fullscreen');
this.player.fire('transversefullscreen', { fullscreen: true });
this.resize();
});
}
return;
}
方案3
。在 UC HAC 方案视频提供全屏接口 UCSettings.setVideoViewFullscreenByDefault(true),开启后,视频全屏默认为横屏if (this.auoplay && env.app.TB && env.network.wifi) {
if (player.getCurrentTime() > 0 && !player.isPause()) {
return;
}
if (this.hasAutoPlay) {
return;
}
this.hasAutoPlay = true;
startEl.trigger('click');
function autoplay() {
doc.detach('touchstart', autoplay);
if (player.getCurrentTime() > 0) {
return;
}
startEl.trigger('click');
}
doc.on('touchstart', autoplay);
}
document.addEventListener('WV.Event.Page.Refresh', $.proxy(this.destory, this), false);
document.addEventListener('WV.Event.Key.Back', $.proxy(this.destory, this), false);
win.on('unload', $.proxy(this.destory, this));
win.on('beforeunload', $.proxy(this.destory, this));
/__
* 返回值需要是整数,否则会有异常
*/
_getVedioPos(isDpr) {
var el = this.el,
offset = el.offset(),
dpr = 1;
if (isDpr) {
dpr = this._getDpr();
}
return {
x: parseInt(offset.left / dpr),
y: parseInt(offset.top / dpr),
w: parseInt(el.width() / dpr),
h: parseInt(el.height() / dpr)
};
}
品牌 | 机型 | 手淘版本 | 操作系统版本 | 播放器控件 | 视频列表切换 | 试看控制 | 观看进度同步 | 切换模式 | 问题 |
---|---|---|---|---|---|---|---|---|---|
苹果 | 6 plus | 5.2.7 | 8.11 | √ | √ | √ | √ | √ | * |
苹果 | 6 | 5.2.7 | 8.11 | √ | √ | √ | √ | √ | * |
苹果 | 5s | 5.2.7 | 8.11 | √ | √ | √ | √ | √ | * |
苹果 | 5 | 5.2.7 | 8.11 | √ | √ | √ | √ | √ | * |
苹果 | 4s | 5.2.7 | 8.11 | √ | √ | √ | √ | √ | * |
苹果 | 4 | * | * | √ | √ | √ | √ | √ | * |
nexus 5 | * | yun os 3 | √ | √ | √ | √ | × | * | |
nexus 5 | * | 安卓 5 | √ | √ | √ | √ | × | * | |
三星 | N7100 | 4.9 | * | √ | √ | √ | √ | × | * |
三星 | NOTE4 | 4.9 | * | √ | √ | √ | √ | √ | 模式二点最大化crash |
三星 | NOTE3 | 4.9 | * | √ | √ | √ | √ | × | * |
三星 | S4 | 5.2.7.3 | * | √ | √ | √ | √ | √ | 模式二,播放有问题 |
三星 | I9300 | 4.3 | * | √ | √ | √ | √ | √ | * |
三星 | S3 | 5.2.8.2 | * | √ | √ | √ | √ | √ | * |
三星 | S5 | 5.2.7.3 | * | √ | √ | √ | √ | √ | * |
魅族 | MX2 | * | * | √ | * | √ | √ | √ | * |
魅族 | MX4 PRO | * | * | √ | √ | √ | √ | √ | * |
魅族 | 魅蓝Note | * | * | √ | √ | √ | √ | √ | * |
魅族 | MX3(安装不上) | * | * | √ | √ | √ | √ | √ | * |
华为 | 荣耀6 | * | * | √ | √ | √ | √ | √ | 模式二可能播放不了 |
华为 | mate7 | * | * | √ | √ | √ | √ | √ | 模式二可能播放不了 |
华为 | c8816 | * | * | √ | √ | √ | √ | √ | 进度条拖动会跳 |
华为 | 荣耀3c | * | 4.4.2 | √ | √ | √ | √ | ×一直展示loading的图片 | 模式二播放不了 |
华为 | C8813 | * | 4.1.1 | √ | √ | √ | √ | √ | 高清视频不能播放 |
HTC | MAX | * | * | √ | √ | √ | √ | * | * |
HTC | 816w | * | * | √ | √ | √ | √ | √ | * |
VIVO | Find5 | * | 4.1.1 | √ | √ | √ | √ | √ | * |
VIVO | X3 | * | 4.2.2 | √ | √ | √ | √ | √ | * |
小米 | 2S | * | 4.3 | √ | √ | √ | √ | * | 高清的播放不了 |
小米 | 3 | * | * | * | √ | √ | √ | * | * |
小米 | 4 | * | 4.4.4 | √ | √ | √ | √ | * | * |
索尼 | M512 | * | 4.4.2 | √ | √ | √ | √ | √ | * |
索尼 | xperia 36l | * | 4.1.2 | √ | √ | √ | √ | * | * |
nubia | nx403 | * | 4.2.2 | √ | × | √ | √ | * | 模式一,模式二播放均有问题 |
锤子 | * | * | * | √ | √ | √ | √ | * | |
oppo | x907 | * | 4.0.3 | 很难点到 | √ | √ | √ | √ | * |
nexus5 | * | * | * | √ | √ | √ | √ | √ | 第二种模式crash |
注:模式1为video,模式2为glue native播放器
← 聊一聊淘宝首页和它背后的一套 无线端的弹幕实现方案 →