Commit 225137c6 authored by liupengfei's avatar liupengfei

video

parent 88148681
.video-contanier {
width: 100vw;
height: 100vh;
position: fixed;
overflow: hidden;
z-index: 10000;
left:0;
top: 0;
background: black;
}
.video-wrapper {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
display: flex;
flex-direction: column;
}
.video-instance {
z-index: 1;
object-fit: contain;
object-position: 50% 50%;
height: 0;
flex:1;
outline: none;
}
.video-inner-plugin {
};
.video-plugin {
position: absolute;
}
/* 分割 */
.video-control {
position: absolute;
width: 100%;
height: 100%;
left:0;
top:0;
}
.video-voice {
width: 8vw;
height: 8vw;
position: absolute;
right: 4.4vw;
bottom: 24vw;
opacity: 0;
pointer-events: auto;
}
.video-control-muted {
position: absolute;
width: 100%;
height: 100%;
background:url('//yun.dui88.com/advideo2020muted.png') no-repeat;
background-size: contain;
display: none;
pointer-events: auto;
}
.video-control-voice {
position: absolute;
width: 100%;
height: 100%;
background:url('//yun.dui88.com/advideo2020voice.png') no-repeat;
background-size: contain;
display: none;
pointer-events: auto;
}
.video-close {
position: absolute;
right: 4.4vw;
top: 10.6vw;
width: 8vw;
height: 8vw;
background: url('//yun.dui88.com/advideo2020close.png') no-repeat;
background-size: contain;
opacity: 0;
pointer-events: auto;
}
.video-count-down {
position: absolute;
width: 8vw;
height: 8vw;
border-radius: 100%;
background:gray;
top:10.4vw;
left: 4.4vw;
display: none;
color: white;
font-size: 4.2vw;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
pointer-events: auto;
}
/* fenge */
.video-loading {
background: url('//yun.dui88.com/advideo2020viewfile.gif') no-repeat;
background-size: contain;
background-color:black;
width: 100%;
height: 100%;
left:0;
top:0;
}
/* fenge */
/* 落地页 */
.video-land-page-content {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.6);
}
.video-land-page-content .app-close {
position: absolute;
width: 5.6vw;
height: 3.1vh;
top: 10.7vw;
right: 3.75vh;
}
.video-land-page-content .app-info-wrap {
box-sizing: border-box;
width: 84vw;
height: 78vw;
background-color: #fff;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 4px;
}
.video-land-page-content .app-star-num {
display: flex;
align-items: center;
flex-direction: row;
margin-top: 2.4vw;
margin-bottom: 3.7vw;
}
.video-land-page-content .app-star-icon {
width: 5.3vw;
height: 5.3vw;
background-size: contain;
background-repeat: no-repeat;
margin-right: 10px;
}
.video-land-page-content .app-logo {
width: 18.7vw;
margin-top: 4vh;
height: 10.5vh;
background-size: 100%;
border-radius: 12px;
}
.video-land-page-content .app-name {
font-size: 24px;
font-weight: 400;
color: rgb(70, 63, 63);
line-height: 3.4vh;
text-align: center;
margin-top: 3vw;
}
.app-star-yellow {
background-image: url('/dafuweng/star-y.png');
}
.app-star-gray {
background-image: url('/dafuweng/star-g.png')
}
.app-star-half {
background-image: url('/dafuweng/star-half.png');
}
.video-land-page-content .app-button {
width: 44.2vw;
height: 9.8vw;
margin-top: 9.8vw;
background: rgba(110, 166, 232, 1);
border-radius: 4px;
font-size: 17px;
color: rgba(255, 255, 255, 1);
display: flex;
justify-content: center;
align-items: center;
}
/* fenge */
/* 底部插件 */
.video-footer-wrapper {
background:white;
}
.video-footer-wrapper {
height: 20.2vw;
display: flex;
align-items: center;
padding: 0 2.6vw;
z-index: 999;
justify-content: space-between;
opacity:0.95;
background: white;
}
.video-footer-wrapper .app-content {
display: flex;
flex-direction: row;
align-items: center;
}
.video-footer-wrapper .app-logo {
width: 14vw;
height: 14vw;
border-radius: 12px;
background-size: contain;
background-repeat: no-repeat;
}
.video-footer-wrapper .app-desc {
padding-left: 2.6vw;
}
.video-footer-wrapper .app-name {
font-size: 4.5vw;
color: block;
font-weight: 600;
}
.video-footer-wrapper .app-comment {
display: flex;
flex-direction: row;
margin-top: 1.3vw;
align-items: center;
}
.video-footer-wrapper .app-comment-num {
font-size: 3.4vw;
}
.video-footer-wrapper .app-star-num {
display: flex;
align-items: center;
flex-direction: row;
margin-right: 1.3vw;
}
.video-footer-wrapper .app-star-icon {
width: 4.6vw;
height: 4.6vw;
background-size: contain;
background-repeat: no-repeat;
}
.app-star-yellow {
background-image: url('//yun.dui88.com/advideo2020star-y.png');
}
.app-star-gray {
background-image: url('//yun.dui88.com/advideo2020star-g.png')
}
.app-star-half {
background-image: url('//yun.dui88.com/advideo2020star-half.png');
}
.video-footer-wrapper .app-button {
font-size: 4.2vw;
background: #4A90E2;
padding: 2.6vw 4.2vw;
text-align: center;
color: white;
border-radius: 4px;
}
\ No newline at end of file
......@@ -10,6 +10,7 @@
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<link rel="stylesheet" type="text/css" href="./advideo.css" />
<style>
html,
body {
......@@ -34,66 +35,6 @@
font-family: "FZY4JW";
src: url("https://yun.duiba.com.cn/db_games/FZY4JW.TTF");
}
.video-land-page-content {
position: absolute;
z-index: 99999;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.6);
}
.app-close {
position: absolute;
width: 5vw;
height: 5vw;
top: 5vw;
right: 5vw;
}
.app-info-wrap {
padding: 3vh 0;
box-sizing: border-box;
width: 84vw;
height: 40vh;
background-color: #fff;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
}
.app-logo {
width: 18.7vw;
margin-top: 4vh;
height: 10.5vh;
background-repeat: no-repeat;
background-size: 100%;
}
.app-name {
font-size: 24px;
font-weight: 400;
color: rgb(70, 63, 63);
line-height: 3.4vh;
text-align: center;
margin-top: 3vh;
}
.app-button {
width: 75.2vw;
height: 6.9vh;
margin: 4vh;
background: rgba(110, 166, 232, 1);
border-radius: 4px;
font-size: 17px;
color: rgba(255, 255, 255, 1);
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
......@@ -214,7 +155,7 @@
}
</script>
<div id="video-contanier"></div>
<script src="output.js"></script>
</body>
......
This diff is collapsed.
import { getAppInfo, getDefaultConfig, createUnique, reportGet, replaceUrl} from './utils';
import videoControl from './video-core/videoPlugin/videoControl/index';
const reflectConfig = {
ost: 'osType',
osv: 'osVersion',
sw: 'screenWidth',
sh: 'screenHeight',
connt: 'connectionType',
androidId: 'androidId',
}
const defautToNew = (raw, reflect) => {
const newObj = {};
for (let i in raw) {
if (reflect[i]) {
newObj[reflect[i]]= raw[i];
} else {
newObj[i] = raw[i];
}
}
return newObj;
};
let config = null;
function createConfig (appInfo, device) {
config = {};
console.log(device);
let { slotId, appId, appVersion, appName, appPackage, ip, connectionType, operatorType} = appInfo
config['app'] = {
appId: appId,
appVersion,
appName,
appPackage
};
config['slot'] = {
slotId,
adtype: 5,
slotheight: 250,
slotwidth: 350
}
config['device'] = Object['assign']({
deviceType: 1,
screenOrientation: 1,
ua: window.navigator.userAgent}, device);
// config['device'] = {
// "idfa": "abcdef123456789",
// "imei": "abcdef123456789",
// "mac": "12:34:56:78:90:ab",
// "androidId":
// "TestAndroidId123",
// "deviceType": 1,
// "osType": 1,
// "osVersion": "4.2.2",
// "vendor": "MEIZU",
// "brand": "MEIZU",
// "model": "MX5",
// "screenHeight": 1080,
// "screenWidth": 1920,
// "ua": 'Mozilla/5.0 (Linux; U; Android 9.0; en-us; Redmi Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13',
// "screenOrientation": 0,
// "imsi": "MEIZU",
// "ppi": 1
// }
config['network'] = {
ip,
connectionType: connectionType,
operatorType: operatorType,
lat: 0,
lon: 0
}
return config;
}
interface adRes {
errorCode: number,
ads: Array<any>
};
async function getVideo() {
let videoRes = {};
try {
if (!config) {
const appInfo = await getAppInfo()
console.log(getDefaultConfig());
const defaultConfig = defautToNew(getDefaultConfig(), reflectConfig);
console.log(defaultConfig);
config = createConfig(appInfo, defaultConfig);
}
config['requsetId'] = createUnique(config['network']['ip'])
const res: any = await window.fetch('http://47.95.31.238/adx/ssp/dspAdTest', {
body: JSON.stringify(config),
headers: {
'content-type': 'application/json;charset=UTF-8',
},
method: 'POST'
}).then(response => {
return response.json();
})
// console.log(res.json());
// const adRes = res.json();
console.log(res);
if (res.errorCode === "200" && res.ads && res.ads.length > 0) {
return videoRes = res.ads[0];
} else {
return false;
}
} catch(err) {
console.log(err);
return false;
}
}
function dianxingReplace(raw, url, times, event) {
let pagesX, pagesY
const date = +new Date();
let clickId = raw.metaGroup[0].clickid
if (event) {
pagesX = event.screenX
pagesY = event.screenY
}
return replaceUrl(url, {
__DOWN_X__: pagesX,
__DOWN_Y__: pagesY,
__WIDTH__: document.body.clientWidth,
__HEIGHT__: document.body.clientHeight,
__UP_X__: pagesX,
__UP_Y__: pagesY,
__EVENT_TIME_START__: date,
__EVENT_TIME_END__: date,
__VIDEO_TIME__: times.duration,
__BEGIN_TIME__: 0,
__END_TIME__: times.duration,
__PLAY_FIRST_FRAME__: 1,
__PLAY_LAST_FRAME__: 1,
__SCENE__: 3,
__TYPE__: 1,
__BEHAVIOR__: 1,
__STATUS__: 0,
__CLICK_ID__: clickId
})
}
const report = {
isChanged: false,
// 加载完成
videoLoad(raw, times) {
const winLoadUrls = raw.metaGroup[0].winLoadUrls;
if (winLoadUrls) {
winLoadUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, null));
})
}
},
// 开始播放(曝光), 0进度
videoPlayStart(raw, times) {
// 曝光
const winNoticeUrls = raw.metaGroup[0].winNoticeUrls;
if (winNoticeUrls) {
winNoticeUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, null));
})
}
// 进度是0;
const track = raw.tracks
console.log('进度0')
track.forEach(e => {
if (e.type === 0) {
e.urls.forEach(url => {
reportGet(dianxingReplace(raw, url, times, null));
})
}
})
},
// 25进度
process25(raw, times) {
console.log('进度25')
const track = raw.tracks
track.forEach(e => {
if (e.type === 1) {
e.urls.forEach(url => {
reportGet(dianxingReplace(raw, url, times, null));
})
}
})
},
// 50进度
process50(raw, times) {
console.log('进度50')
const track = raw.tracks
track.forEach(e => {
if (e.type === 2) {
e.urls.forEach(url => {
reportGet(dianxingReplace(raw, url, times, null));
})
}
})
},
process75(raw, times) {
console.log('进度75')
const track = raw.tracks
track.forEach(e => {
if (e.type === 3) {
e.urls.forEach(url => {
reportGet(dianxingReplace(raw, url, times, null));
})
}
})
},
// 广告点击
async videoClick(raw, times, event) {
const winCNoticeUrls = raw.metaGroup[0].winCNoticeUrls;
if (winCNoticeUrls) {
winCNoticeUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, event));
})
}
},
async changeUrl(raw, times, event) {
if (this.isChanged) {
return;
}
this.isChanged = true;
let {interactionType, protocolType, clickUrl} = raw.metaGroup[0];
if (interactionType === 2 && protocolType === 1) {
try {
const res = await window.fetch(dianxingReplace(raw, clickUrl, times, event));
let resJson: any = res.json();
if (resJson.data.dstlink) {
window.location.href = clickUrl;
}
this.isChanged = false;
} catch (err) {
this.isChanged = false;
console.log('替换地址请求出错');
}
} else {
this.isChanged = false;
window.location.href = clickUrl;
}
},
// 广告关闭
videoClose(raw, times, event) {
const winCloseUrls = raw.metaGroup[0].winCloseUrls;
if (winCloseUrls) {
winCloseUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, event));
})
}
},
// 开始下载
async appDownload(raw, times, event) {
const winCloseUrls = raw.metaGroup[0].winCloseUrls;
if (winCloseUrls) {
winCloseUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, event));
})
}
await this.changeUrl(raw, times, event)
},
// 播放完毕, 进度100.
videoPlayEnd(raw, times) {
const track = raw.tracks
console.log('进度100')
track.forEach(e => {
if (e.type === 4) {
e.urls.forEach(url => {
reportGet(dianxingReplace(raw, url, times, null));
})
}
})
// 激励完成
const winCompleteUrls = raw.metaGroup[0].winCompleteUrls
if (winCompleteUrls) {
winCompleteUrls.forEach(e => {
reportGet(dianxingReplace(raw, e, times, event));
})
}
},
}
export function resolveParams(raw) {
console.log(raw);
const ads = {
url: '',
name: '',
appIcon: '',
slogen: '',
};
const metaGroup = raw.metaGroup
if (metaGroup && metaGroup.length > 0) {
let videoRaw = metaGroup[0]
videoRaw.videoUrl && (ads.url = videoRaw.videoUrl);
videoRaw.brandName && (ads.name = videoRaw.brandName);
videoRaw.iconUrls && videoRaw.iconUrls.length > 0 && (ads.appIcon = videoRaw.iconUrls[0]);
videoRaw.descs && videoRaw.descs.length > 0 && (ads.slogen = videoRaw.descs[0]);
}
console.log(ads);
return ads;
}
export default {
getVideo,
report,
resolveParams,
}
\ No newline at end of file
import MobileDetect from './video-core/mobile-detect';
function getCookie(key) {
var arr1 = document.cookie.split("; ");//由于cookie是通过一个分号+空格的形式串联起来的,所以这里需要先按分号空格截断,变成[name=Jack,pwd=123456,age=22]数组类型;
for (var i = 0; i < arr1.length; i++) {
var arr2 = arr1[i].split("=");//通过=截断,把name=Jack截断成[name,Jack]数组;
if (arr2[0] == key) {
return decodeURIComponent(arr2[1]);
}
}
return null
}
export const getUrl = (name) => {
var str = getCookie("dcustom");
if (str) {
//&分割
var arr = str.split("&");
for (var i = 0; i < arr.length; i++) {
if (arr[i].indexOf(name + "=") == 0) {
return arr[i].replace(name + "=", "") || '';
}
}
}
return '';
};
// 获取网络信息
export function getNetworkType(obj = {}) {
const ua = navigator.userAgent;
let networkStr = ua.match(/NetType\/\w+/) ? ua.match(/NetType\/\w+/)[0] : 'NetType/other';
networkStr = networkStr.toLowerCase().replace('nettype/', '');
let networkType;
switch (networkStr) {
case 'wifi':
networkType = 'wifi';
break;
case '4g':
networkType = '4g';
break;
case '3g':
networkType = '3g';
break;
case '3gnet':
networkType = '3g';
break;
case '2g':
networkType = '2g';
break;
default:
networkType = 'other';
}
if (obj[networkType]) {
return obj[networkType];
}
return networkType;
}
interface appInfo {
appId: string,
appPackage: string,
appName: string,
appVersion: string,
slotId: string,
ip: string,
connectionType: number,
operatorType: number
}
// 获取平台信息, app相关的,slotId , ip。
export function getAppInfo():Promise<appInfo> {
const tVideoSlotId = getUrl('tVideoSlotId');
return new Promise((resolve) => {
// window.fetch(`https://activity.tuiatest.cn/commercialloanv/common/config/video/get?slotId=${tVideoSlotId}`).then(res => {
// return res.json();
// }).then(res => {
// console.log(res);
// })
resolve({
appId: "ZG08HD",
appPackage: "com.test",
appName: "测试 APP",
appVersion: "1.1.0",
slotId: "test1030",
ip: "115.236.166.122",
connectionType: 4,
operatorType: 2
})
});
}
// 根据ip 生成唯一的值。
export function createUnique(ip) {
return ip + (+ new Date());
}
// ost (平台 1.安卓,2ios), 自行分析
// idfa(苹果唯一标示码), 必须传递
// model(设备型号), 优先传递
// osv(操作系统版本号), 优先传递
// imei(安卓平台的号码) 必须传递
// androidid(必须传递) 必须传递
// mac(mac 地址) 必须传递
// vendor(设备厂商) 优先传递
// brand(手机厂商) 有限传递
// imsi() 不做要求。
// ppi
// connt(网络状况) 优先传递
const reflectObj = {
wifi: 101,
'2g': 2,
'3g': 3,
'4g': 4,
'5g': 5,
other: 0
};
let defaultConfig;
export function getDefaultConfig() {
if (defaultConfig) return defaultConfig;
defaultConfig = {};
const md = new MobileDetect(window.navigator.userAgent);
if (md.os() === 'iOS') {
defaultConfig.ost = 2;
defaultConfig.idfa = getUrl('idfa');
defaultConfig.ppi = Math.min(window.devicePixelRatio, 3);
defaultConfig.model = getUrl('model') || md.versionStr('Mobile');
defaultConfig.osv = getUrl('osv') || md.versionStr('iPhone');
defaultConfig.imei = '';
defaultConfig.androidId = '';
defaultConfig.imsi = '';
} else {
defaultConfig.ost = 1;
defaultConfig.imei = getUrl('imei') || '866333026939494';
defaultConfig.ppi = 1;
defaultConfig.model = getUrl('model') || md.versionStr('Build');
defaultConfig.osv = getUrl('osv') || md.version('Android').toString();
defaultConfig.androidId = getUrl('androidid') || '';
defaultConfig.imsi = getUrl('imsi') || '';
defaultConfig.idfa = '';
}
defaultConfig.mac = getUrl('mac');
defaultConfig.sw = document.body.clientWidth;
defaultConfig.sh = document.body.clientHeight;
defaultConfig.vendor = getUrl('vendor') || md.phone();
defaultConfig.brand = getUrl('vendor') || md.phone();
return defaultConfig;
}
export function replaceUrl(url, replaceConfig) {
for (const i in replaceConfig) {
if (replaceConfig[i]) {
url = url.replace(i, replaceConfig[i]);
}
}
return url;
}
export const reportGet = (e) => {
const img = new Image();
img.src = e;
};
\ No newline at end of file
export default {
autoplay: false,
controls: false,
playsInline: true,
preload: 'auto',
'x5-video-player-fullscreen': true,
'x5-video-orientation': 'landscape|portrait',
'x5-video-player-type': 'h5',
'x-webkit-airplay': 'allow',
muted: true,
crossorigin: 'anonymous'
};
export default {
autoplay: false,
controls: false,
playsInline: true,
preload: 'auto',
'x5-video-player-fullscreen': true,
'x5-video-orientation': 'landscape|portrait',
'x5-video-player-type': 'h5',
'x-webkit-airplay': 'allow',
muted: true,
crossorigin: 'anonymous'
};
class EventEmitter {
_events: {};
constructor() {
this._events = {};
}
on(event, callback) {
const callbacks = this._events[event] || [];
callbacks.push(callback);
this._events[event] = callbacks;
return this;
}
off(event, callback) {
const callbacks = this._events[event];
this._events[event] = callbacks && callbacks.filter(fn => fn !== callback);
return this;
}
emit(...args) {
const event = args[0];
const params = [].slice.call(args, 1);
const callbacks = this._events[event];
if (callbacks) {
callbacks.forEach(fn => fn.apply(this, params));
}
return this;
}
once(event, callback) {
const wrapFunc = (...args) => {
callback.apply(this, args);
this.off(event, wrapFunc);
};
this.on(event, wrapFunc);
return this;
}
removeAll() {
this._events = {};
}
}
export default EventEmitter;
class EventEmitter {
_events: {};
constructor() {
this._events = {};
}
on(event, callback) {
const callbacks = this._events[event] || [];
callbacks.push(callback);
this._events[event] = callbacks;
return this;
}
off(event, callback) {
const callbacks = this._events[event];
this._events[event] = callbacks && callbacks.filter(fn => fn !== callback);
return this;
}
emit(...args) {
const event = args[0];
const params = [].slice.call(args, 1);
const callbacks = this._events[event];
if (callbacks) {
callbacks.forEach(fn => fn.apply(this, params));
}
return this;
}
once(event, callback) {
const wrapFunc = (...args) => {
callback.apply(this, args);
this.off(event, wrapFunc);
};
this.on(event, wrapFunc);
return this;
}
removeAll() {
this._events = {};
}
}
export default EventEmitter;
.video-contanier {
width: 100vw;
height: 100vh;
position: fixed;
overflow: hidden;
z-index: 10000;
left:0;
top: 0;
background: black;
}
.video-wrapper {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
display: flex;
flex-direction: column;
}
.video-instance {
z-index: 1;
object-fit: contain;
object-position: 50% 50%;
height: 0;
flex:1;
outline: none;
}
.video-inner-plugin {
};
.video-plugin {
position: absolute;
}
\ No newline at end of file
.video-contanier {
width: 100vw;
height: 100vh;
position: fixed;
overflow: hidden;
z-index: 10000;
left:0;
top: 0;
background: red;
}
.video-wrapper {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
display: flex;
flex-direction: column;
}
.video-instance {
z-index: 1;
object-fit: contain;
object-position: 50% 50%;
height: 0;
flex:1;
outline: none;
}
.video-inner-plugin {
};
.video-plugin {
position: absolute;
}
import defaultVideoConfig from './defaultVideoConfig';
import VideoPlugin from './plugins';
import EventEmitter from './event';
import { videoEvent, videoProps } from './videoEvent';
const clone = (obj) => {
return JSON.parse(JSON.stringify(obj));
};
const plugins = [];
class AdVideo {
eventType: any[];
event: EventEmitter;
$contanier: any;
$video: HTMLVideoElement;
$wrapper: HTMLDivElement;
url: any;
videoCoinfg: any;
plugins: any[];
static install: (plugConfig: any) => void;
constructor(config) {
this.eventType = [];
this.event = new EventEmitter();
this.initVideoConfig(config);
this.init(config);
}
// 初始化容器
initVideoConfig(config) {
if (!config.el) {
console.warn('player: no element');
return;
};
this.event = new EventEmitter();
this.$contanier = config.el;
this.$contanier.classList.add('video-contanier');
this.$video = document.createElement('video');
this.$wrapper = document.createElement('div');
this.$wrapper.classList.add('video-wrapper');
this.$video.classList.add('video-instance');
}
// 初始化
init(config) {
this.url = config.url || '';
this.videoCoinfg = Object["assign"](
clone(defaultVideoConfig),
config.videoConfig,
{ url: '' });
for (const i in this.videoCoinfg) {
if (videoProps["findIndex"](e => e === i) > -1) {
this.$video[i] = this.videoCoinfg[i];
} else {
this.$video.setAttribute(i, this.videoCoinfg[i]);
}
};
this.plugins = plugins || [];
this.plugins = this.plugins.map(e => {
return new VideoPlugin(Object["assign"](e, {
$video: this.$video,
$contanier: this.$contanier,
$wrapper: this.$wrapper,
$player: this
}));
});
this.$wrapper.appendChild(this.$video);
this.$contanier.appendChild(this.$wrapper);
this.plugins.forEach(e => {
e.created();
});
this.$wrapper.appendChild(this.$video);
this.$contanier.appendChild(this.$wrapper);
this.plugins.forEach(e => {
e.mounted();
});
// 准备播放;
if (this.url) {
this.$video.src = config.url;
}
}
// 初始化事件监听
on(i, fn) {
if (typeof i === 'string' && typeof fn === 'function') {
const isNative = videoEvent["findIndex"](e => e === i) > -1;
if (isNative && this.eventType["findIndex"](e => e === i) === -1) {
this.eventType.push(i);
this.$video.addEventListener(i, (e) => {
this.event.emit(i, e);
});
}
this.event.on(i, fn);
}
}
// 触发事件
emit(...args) {
const event = args[0];
// 不能触发原生事件。
if (videoEvent["findIndex"](e => e === event) > -1) {
return;
}
const params = [].slice.call(args, 1);
this.event.emit(event, ...params);
}
// 加载视频
load(url) {
this.$video.src = url;
}
play() {
if (this.$video && this.$video.play) {
this.$video.play();
}
}
pause() {
if (this.$video) {
this.$video.pause();
}
}
_removeAll() {
this.event.removeAll();
}
};
AdVideo.install = (plugConfig) => {
plugins.push(plugConfig);
};
export default AdVideo;
import defaultVideoConfig from './defaultVideoConfig';
import VideoPlugin from './plugins';
import EventEmitter from './event';
import { videoEvent, videoProps } from './videoEvent';
const clone = (obj) => {
return JSON.parse(JSON.stringify(obj));
};
const plugins = [];
class AdVideo {
eventType: any[];
event: EventEmitter;
$contanier: any;
$video: HTMLVideoElement;
$wrapper: HTMLDivElement;
url: any;
videoCoinfg: any;
plugins: any[];
static install: (plugConfig: any) => void;
constructor(config) {
this.eventType = [];
this.event = new EventEmitter();
this.initVideoConfig(config);
this.init(config);
}
// 初始化容器
initVideoConfig(config) {
if (!config.el) {
console.warn('player: no element');
return;
};
this.event = new EventEmitter();
this.$contanier = config.el;
this.$contanier.classList.add('video-contanier');
this.$video = document.createElement('video');
this.$wrapper = document.createElement('div');
this.$wrapper.classList.add('video-wrapper');
this.$video.classList.add('video-instance');
}
// 初始化
init(config) {
this.url = config.url || '';
this.videoCoinfg = Object["assign"](
clone(defaultVideoConfig),
config.videoConfig,
{ url: '' });
for (const i in this.videoCoinfg) {
if (videoProps["findIndex"](e => e === i) > -1) {
this.$video[i] = this.videoCoinfg[i];
} else {
this.$video.setAttribute(i, this.videoCoinfg[i]);
}
};
this.plugins = plugins || [];
this.plugins = this.plugins.map(e => {
return new VideoPlugin(Object["assign"](e, {
$video: this.$video,
$contanier: this.$contanier,
$wrapper: this.$wrapper,
$player: this
}));
});
this.$wrapper.appendChild(this.$video);
this.$contanier.appendChild(this.$wrapper);
this.plugins.forEach(e => {
e.created();
});
this.$wrapper.appendChild(this.$video);
this.$contanier.appendChild(this.$wrapper);
this.plugins.forEach(e => {
e.mounted();
});
// 准备播放;
if (this.url) {
this.$video.src = config.url;
}
}
// 初始化事件监听
on(i, fn) {
if (typeof i === 'string' && typeof fn === 'function') {
const isNative = videoEvent["findIndex"](e => e === i) > -1;
if (isNative && this.eventType["findIndex"](e => e === i) === -1) {
this.eventType.push(i);
this.$video.addEventListener(i, (e) => {
this.event.emit(i, e);
});
}
this.event.on(i, fn);
}
}
// 触发事件
emit(...args) {
const event = args[0];
// 不能触发原生事件。
if (videoEvent["findIndex"](e => e === event) > -1) {
return;
}
const params = [].slice.call(args, 1);
this.event.emit(event, ...params);
}
// 加载视频
load(url) {
this.$video.src = url;
}
play() {
if (this.$video && this.$video.play) {
this.$video.play();
}
}
pause() {
if (this.$video) {
this.$video.pause();
}
}
_removeAll() {
this.event.removeAll();
}
};
AdVideo.install = (plugConfig) => {
plugins.push(plugConfig);
};
export default AdVideo;
File mode changed from 100644 to 100755
import './index.less';
let nameId = 0;
class VideoPlugin {
isAbstract: any;
isInner: any;
poinerEvents: any;
configRaw: any;
name: any;
$wrapper: any;
$video: any;
$contanier: any;
$player: any;
el: HTMLDivElement;
$wapper(arg0: any): any {
throw new Error("Method not implemented.");
}
_removed: any;
constructor(config) {
this.isAbstract = config.isAbstract || false;
this.isInner = config.isInner || false;
this.poinerEvents = config.poinerEvents;
this.configRaw = config;
nameId += 1;
this.name = config.name || nameId;
// 当前video实例
this.$wrapper = config.$wrapper || '';
this.$video = config.$video || '';
this.$contanier = config.$contanier || '';
this.$player = config.$player || '';
this.proxyMethods(config);
// 初始化事件
for (const i in config.event) {
if (i && typeof config.event[i] === 'function') {
this.$player.on(i, config.event[i].bind(this));
}
}
}
// 代理methods
proxyMethods(config) {
if (config.methods) {
const that = this;
for (const i in config.methods) {
Object.defineProperty(this, i, {
get() {
return config.methods[i].bind(that);
}
});
}
}
}
// 创建
created() {
if (!this.isAbstract) {
this.el = document.createElement('div');
console.log(this.poinerEvents);
this.poinerEvents === 'none' && (this.el.style.pointerEvents = 'none');
if (this.isInner) {
this.el.classList.add('video-inner-plugin');
} else {
this.el.classList.add('video-plugin');
if (this.configRaw.zIndex) {
this.el.style.zIndex = this.configRaw.zIndex;
} else {
this.el.style.zIndex = nameId+"";
}
}
};
if (this.configRaw.created) {
this.configRaw.created.apply(this);
}
}
// 挂载完成
mounted() {
if (this.isInner) {
console.log(this.$wapper);
this.$wrapper.appendChild(this.el);
} else {
this.$contanier.appendChild(this.el);
}
if (this.configRaw.mounted) {
this.configRaw.mounted.apply(this);
}
}
// 移除
remove() {
if (this._removed) {
return;
};
if (this.isAbstract) {
return;
}
if (this.isInner) {
this.$wrapper.removeChild(this.el);
this._removed = true;
} else {
console.log(this.el);
this.$contanier.removeChild(this.el);
this._removed = true;
}
}
// 卸载
destory() {
this.el = null;
}
};
export default VideoPlugin;
let nameId = 0;
class VideoPlugin {
isAbstract: any;
isInner: any;
poinerEvents: any;
configRaw: any;
name: any;
$wrapper: any;
$video: any;
$contanier: any;
$player: any;
el: HTMLDivElement;
$wapper(arg0: any): any {
throw new Error("Method not implemented.");
}
_removed: any;
constructor(config) {
this.isAbstract = config.isAbstract || false;
this.isInner = config.isInner || false;
this.poinerEvents = config.poinerEvents;
this.configRaw = config;
nameId += 1;
this.name = config.name || nameId;
// 当前video实例
this.$wrapper = config.$wrapper || '';
this.$video = config.$video || '';
this.$contanier = config.$contanier || '';
this.$player = config.$player || '';
this.proxyMethods(config);
// 初始化事件
for (const i in config.event) {
if (i && typeof config.event[i] === 'function') {
this.$player.on(i, config.event[i].bind(this));
}
}
}
// 代理methods
proxyMethods(config) {
if (config.methods) {
const that = this;
for (const i in config.methods) {
Object.defineProperty(this, i, {
get() {
return config.methods[i].bind(that);
}
});
}
}
}
// 创建
created() {
if (!this.isAbstract) {
this.el = document.createElement('div');
console.log(this.poinerEvents);
this.poinerEvents === 'none' && (this.el.style.pointerEvents = 'none');
if (this.isInner) {
this.el.classList.add('video-inner-plugin');
} else {
this.el.classList.add('video-plugin');
if (this.configRaw.zIndex) {
this.el.style.zIndex = this.configRaw.zIndex;
} else {
this.el.style.zIndex = nameId+"";
}
}
};
if (this.configRaw.created) {
this.configRaw.created.apply(this);
}
}
// 挂载完成
mounted() {
if (this.isInner) {
console.log(this.$wapper);
this.$wrapper.appendChild(this.el);
} else {
this.$contanier.appendChild(this.el);
}
if (this.configRaw.mounted) {
this.configRaw.mounted.apply(this);
}
}
// 移除
remove() {
if (this._removed) {
return;
};
if (this.isAbstract) {
return;
}
if (this.isInner) {
this.$wrapper.removeChild(this.el);
this._removed = true;
} else {
console.log(this.el);
this.$contanier.removeChild(this.el);
this._removed = true;
}
}
// 卸载
destory() {
this.el = null;
}
};
export default VideoPlugin;
const videoEvent = [
'abort', // 在播放被终止时触发,例如, 当播放中的视频重新开始播放时会触发这个事件。
'canplay', // 在媒体数据已经有足够的数据(至少播放数帧)可供播放时触发。这个事件对应CAN_PLAY的readyState。
'canplaythrough', // 在媒体的readyState变为CAN_PLAY_THROUGH时触发,表明媒体可以在保持当前的下载速度的情况下不被中断地播放完毕。注意:手动设置currentTime会使得firefox触发一次canplaythrough事件,其他浏览器或许不会如此。
'durationchange', // 元信息已载入或已改变,表明媒体的长度发生了改变。例如,在媒体已被加载足够的长度从而得知总长度时会触发这个事件。
'emptied', // 媒体被清空(初始化)时触发。
'ended', // 播放结束时触发。
'error', // 在发生错误时触发。元素的error属性会包含更多信息。参阅 HTMLMediaElement.error 获得详细信息。
'loadeddata', // 媒体的第一帧已经加载完毕。
'loadedmetadata', // 媒体的元数据已经加载完毕,现在所有的属性包含了它们应有的有效信息。
'loadstart', // 在媒体开始加载时触发。
'mozaudioavailable', // 当音频数据缓存并交给音频层处理时
'pause', // 播放暂停时触发。
'play', // 在媒体回放被暂停后再次开始时触发。即,在一次暂停事件后恢复媒体回放。
'playing', // 在媒体开始播放时触发(不论是初次播放、在暂停后恢复、或是在结束后重新开始)。
'progress', // 告知媒体相关部分的下载进度时周期性地触发。有关媒体当前已下载总计的信息可以在元素的buffered属性中获取到。
'ratechange', // 在回放速率变化时触发。
'seeked', // 在跳跃操作完成时触发。
'seeking', // 在跳跃操作开始时触发。
'stalled', // 在尝试获取媒体数据,但数据不可用时触发。
'suspend', // 在媒体资源加载终止时触发,这可能是因为下载已完成或因为其他原因暂停。
'timeupdate', // 元素的currentTime属性表示的时间已经改变。
'volumechange', // 在音频音量改变时触发(既可以是volume属性改变,也可以是muted属性改变).。
'waiting' // 在一个待执行的操作(如回放)因等待另一个操作(如跳跃或下载)被延迟时触发。
];
const videoProps = [
'autoplay',
'controls',
'height',
'loop',
'muted',
'poster',
'preload',
'src',
'width',
'crossorigin'
];
export {
videoEvent,
videoProps
};
const videoEvent = [
'abort', // 在播放被终止时触发,例如, 当播放中的视频重新开始播放时会触发这个事件。
'canplay', // 在媒体数据已经有足够的数据(至少播放数帧)可供播放时触发。这个事件对应CAN_PLAY的readyState。
'canplaythrough', // 在媒体的readyState变为CAN_PLAY_THROUGH时触发,表明媒体可以在保持当前的下载速度的情况下不被中断地播放完毕。注意:手动设置currentTime会使得firefox触发一次canplaythrough事件,其他浏览器或许不会如此。
'durationchange', // 元信息已载入或已改变,表明媒体的长度发生了改变。例如,在媒体已被加载足够的长度从而得知总长度时会触发这个事件。
'emptied', // 媒体被清空(初始化)时触发。
'ended', // 播放结束时触发。
'error', // 在发生错误时触发。元素的error属性会包含更多信息。参阅 HTMLMediaElement.error 获得详细信息。
'loadeddata', // 媒体的第一帧已经加载完毕。
'loadedmetadata', // 媒体的元数据已经加载完毕,现在所有的属性包含了它们应有的有效信息。
'loadstart', // 在媒体开始加载时触发。
'mozaudioavailable', // 当音频数据缓存并交给音频层处理时
'pause', // 播放暂停时触发。
'play', // 在媒体回放被暂停后再次开始时触发。即,在一次暂停事件后恢复媒体回放。
'playing', // 在媒体开始播放时触发(不论是初次播放、在暂停后恢复、或是在结束后重新开始)。
'progress', // 告知媒体相关部分的下载进度时周期性地触发。有关媒体当前已下载总计的信息可以在元素的buffered属性中获取到。
'ratechange', // 在回放速率变化时触发。
'seeked', // 在跳跃操作完成时触发。
'seeking', // 在跳跃操作开始时触发。
'stalled', // 在尝试获取媒体数据,但数据不可用时触发。
'suspend', // 在媒体资源加载终止时触发,这可能是因为下载已完成或因为其他原因暂停。
'timeupdate', // 元素的currentTime属性表示的时间已经改变。
'volumechange', // 在音频音量改变时触发(既可以是volume属性改变,也可以是muted属性改变).。
'waiting' // 在一个待执行的操作(如回放)因等待另一个操作(如跳跃或下载)被延迟时触发。
];
const videoProps = [
'autoplay',
'controls',
'height',
'loop',
'muted',
'poster',
'preload',
'src',
'width',
'crossorigin'
];
export {
videoEvent,
videoProps
};
File mode changed from 100644 to 100755
.video-footer-wrapper {
height: 152px;
display: flex;
align-items: center;
padding: 0 20px;
z-index: 999;
justify-content: space-between;
opacity:0.95;
background: white;
.app-content {
display: flex;
flex-direction: row;
align-items: center;
}
.app-logo {
width: 125px;
height: 125px;
border-radius: 20px;
background-size: contain;
background-repeat: no-repeat;
}
.app-desc {
padding-left: 20px;
}
.app-name {
font-size: 34px;
color: block;
font-weight: 600;
}
.app-comment {
display: flex;
flex-direction: row;
margin-top: 10px;
align-items: center;
}
.app-comment-num {
font-size: 26px;
}
.app-star-num {
display: flex;
align-items: center;
flex-direction: row;
margin-right: 10px;
}
.app-star-icon {
width: 35px;
height: 35px;
background-size: contain;
background-repeat: no-repeat;
}
.app-star-yellow {
background-image: url('/dafuweng/star-y.png');
}
.app-star-gray {
background-image: url('/dafuweng/star-g.png')
}
.app-star-half {
background-image: url('/dafuweng/star-half.png');
}
.app-button {
font-size: 32px;
background: #4A90E2;
padding: 20px 40px;
text-align: center;
color: white;
border-radius: 4px;
}
}
import './index.less';
const padNum = (num) => {
if (typeof num === 'number') {
return num.toLocaleString();
} else {
return num;
}
};
export default {
name: 'footer-page',
isInner: true,
created() {
this.el.classList.add('video-footer-wrapper');
this.el.innerHTML = `
<div class="app-content">
<div class="app-logo"></div>
<div class="app-desc">
<div class="app-name"></div>
<div class="app-comment">
<div class="app-star-num"></div>
<div class="app-comment-num">个评分</div>
</div>
</div>
</div>
<div class="app-button"></div>
`;
this.appNameEl = this.el.querySelector('.app-name');
this.appCommentNumEl = this.el.querySelector('.app-comment-num');
this.appLogoEl = this.el.querySelector('.app-logo');
this.appButtonEl = this.el.querySelector('.app-button');
this.appIcon = this.el.querySelector('.app-logo');
this.starNumEl = this.el.querySelector('.app-star-num');
this.el.addEventListener('click', (e) => {
if (e.target === this.appButton) {
this.$player.event.emit('$footerPageClick', e);
this.$player.event.emit('$footerPageButtonClick', e);
} else {
this.$player.event.emit('$footerPageClick', e);
}
});
},
methods: {
renderStarNum(num) {
let dom = '';
let renderNum = 5;
while (renderNum > 0) {
if (num >= 1) {
dom += '<div class="app-star-yellow app-star-icon"></div>';
} else if (num === 0.5) {
dom += '<div class="app-star-half app-star-icon"></div>';
} else {
dom += '<div class="app-star-gray app-star-icon"></div>';
}
renderNum -= 1;
num -= 1;
}
console.log(dom);
this.starNumEl.innerHTML = dom;
},
hide() {
this.el.style.display = 'none';
},
show() {
this.el.style.display = 'flex';
}
},
event: {
$footerPageChangeApp({ name, commentNum, starNum, appIcon, buttonText }, show = true) {
if (!show) {
console.log('hidehide');
this.hide();
return;
} else {
this.show();
}
if (name) {
console.log(name);
this.appNameEl.innerText = name;
};
if (commentNum) {
this.appCommentNumEl.innerText = `${padNum(commentNum)}个评分`;
}
if (typeof starNum === 'number') {
this.renderStarNum(starNum);
};
if (buttonText) {
this.appButtonEl.innerText = buttonText;
}
if (appIcon) {
this.appIcon.style.backgroundImage = `url(${appIcon})`;
}
}
}
};
const padNum = (num) => {
if (typeof num === 'number') {
return num.toLocaleString();
} else {
return num;
}
};
export default {
name: 'footer-page',
isInner: true,
created() {
this.el.classList.add('video-footer-wrapper');
this.el.innerHTML = `
<div class="app-content">
<div class="app-logo"></div>
<div class="app-desc">
<div class="app-name"></div>
<div class="app-comment">
<div class="app-star-num"></div>
<div class="app-comment-num">个评分</div>
</div>
</div>
</div>
<div class="app-button"></div>
`;
this.appNameEl = this.el.querySelector('.app-name');
this.appCommentNumEl = this.el.querySelector('.app-comment-num');
this.appLogoEl = this.el.querySelector('.app-logo');
this.appButtonEl = this.el.querySelector('.app-button');
this.appIcon = this.el.querySelector('.app-logo');
this.starNumEl = this.el.querySelector('.app-star-num');
this.el.addEventListener('click', (e) => {
if (e.target === this.appButton) {
this.$player.event.emit('$footerPageClick', e);
this.$player.event.emit('$footerPageButtonClick', e);
} else {
this.$player.event.emit('$footerPageClick', e);
}
});
},
methods: {
renderStarNum(num) {
let dom = '';
let renderNum = 5;
while (renderNum > 0) {
if (num >= 1) {
dom += '<div class="app-star-yellow app-star-icon"></div>';
} else if (num === 0.5) {
dom += '<div class="app-star-half app-star-icon"></div>';
} else {
dom += '<div class="app-star-gray app-star-icon"></div>';
}
renderNum -= 1;
num -= 1;
}
console.log(dom);
this.starNumEl.innerHTML = dom;
},
hide() {
this.el.style.display = 'none';
},
show() {
this.el.style.display = 'flex';
}
},
event: {
$footerPageChangeApp({ name, commentNum, starNum, appIcon, buttonText }, show = true) {
if (!show) {
console.log('hidehide');
this.hide();
return;
} else {
this.show();
}
if (name) {
console.log(name);
this.appNameEl.innerText = name;
};
if (commentNum) {
this.appCommentNumEl.innerText = `${padNum(commentNum)}个评分`;
}
if (typeof starNum === 'number') {
this.renderStarNum(starNum);
};
if (buttonText) {
this.appButtonEl.innerText = buttonText;
}
if (appIcon) {
this.appIcon.style.backgroundImage = `url(${appIcon})`;
}
}
}
};
.video-land-page-content {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.6);
}
.app-close {
position: absolute;
width: 5.6vw;
height: 3.1vh;
top: 10.7vw;
right: 3.75vh;
}
.app-info-wrap {
padding: 3vh 0;
box-sizing: border-box;
width: 84vw;
height: 40vh;
background-color: #fff;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
}
.app-logo {
width: 18.7vw;
margin-top: 4vh;
height: 10.5vh;
background-size: 100%;
}
.app-name {
font-size: 24px;
font-weight: 400;
color: rgb(70, 63, 63);
line-height: 3.4vh;
text-align: center;
margin-top: 3vh;
}
.app-button {
width: 75.2vw;
height: 6.9vh;
margin: 4vh;
background: rgba(110, 166, 232, 1);
border-radius: 4px;
font-size: 17px;
color: rgba(255, 255, 255, 1);
display: flex;
justify-content: center;
align-items: center;
}
\ No newline at end of file
import './index.less';
const padNum = (num) => {
if (typeof num === 'number') {
return num.toLocaleString();
} else {
return num;
}
};
export default {
name: 'landPage',
zIndex: 10,
created() {
this.el.classList.add('video-land-page');
this.el.innerHTML = `
<div class="video-land-page-content">
<img class="app-close"
src="data:image/png;base64,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">
</img>
<div class="app-info-wrap">
<div class="app-logo"></div>
<div class="app-name"></div>
<div class="app-tips">新人下载立领60元现金礼包</div>
<div class="app-button"></div>
<div class="app-download-num"></div>
</div>
</div>
`;
this.appNameEl = this.el.querySelector('.app-name');
this.appClose = this.el.querySelector(".app-close");
this.appButtonEl = this.el.querySelector('.app-button');
this.appIcon = this.el.querySelector('.app-logo');
this.appDownloadNum = this.el.querySelector('.app-download-num');
this.el.addEventListener('click', (e) => {
if (e.target === this.appButton) {
this.$player.event.emit('$footerPageButtonClick');
} else if (e.target === this.appClose) {
this.hide();
} else {
this.$player.event.emit('$footerPageClick');
}
});
this.hide();
},
methods: {
hide() {
this.el.style.display = 'none';
},
show() {
this.el.style.display = 'block';
}
},
event: {
$landPageChangeApp({ name, appIcon, buttonText, donloadNum }, show = true) {
if (!show) {
this.hide();
return;
} else {
this.show();
}
if (name) {
console.log(name);
this.appNameEl.innerText = name;
};
if (donloadNum) {
this.appDownloadNum.innerText = `今天有${donloadNum}人已下载`;
}
if (buttonText) {
this.appButtonEl.innerText = buttonText;
}
if (appIcon) {
this.appIcon.style.backgroundImage = `url(${appIcon})`;
}
},
ended() {
this.show();
},
$videoReset() {
this.hide();
}
}
};
const padNum = (num) => {
if (typeof num === 'number') {
return num.toLocaleString();
} else {
return num;
}
};
export default {
name: 'landPage',
zIndex: 10,
created() {
this.el.classList.add('video-land-page');
this.el.innerHTML = `
<div class="video-land-page-content">
<div class="app-info-wrap">
<div class="app-logo"></div>
<div class="app-name"></div>
<div class="app-star-num"></div>
<div class="app-comment">
<div class="app-person-icon"></div>
<div class="app-comment-num"></div>
</div>
<div class="app-button"></div>
</div>
</div>
`;
this.appCommentNumEl = this.el.querySelector('.app-comment-num');
this.appNameEl = this.el.querySelector('.app-name');
this.appClose = this.el.querySelector(".app-close");
this.appButtonEl = this.el.querySelector('.app-button');
this.appIcon = this.el.querySelector('.app-logo');
this.starNumEl = this.el.querySelector('.app-star-num');
this.el.addEventListener('click', (e) => {
if (e.target === this.appButton) {
this.$player.event.emit('$footerPageButtonClick');
} else if (e.target === this.appClose) {
this.hide();
} else {
this.$player.event.emit('$footerPageClick', e);
}
});
this.hide();
},
methods: {
hide() {
this.el.style.display = 'none';
},
show() {
this.el.style.display = 'block';
},
renderStarNum(num) {
let dom = '';
let renderNum = 5;
while (renderNum > 0) {
if (num >= 1) {
dom += '<div class="app-star-yellow app-star-icon"></div>';
} else if (num === 0.5) {
dom += '<div class="app-star-half app-star-icon"></div>';
} else {
dom += '<div class="app-star-gray app-star-icon"></div>';
}
renderNum -= 1;
num -= 1;
}
console.log(dom);
this.starNumEl.innerHTML = dom;
},
},
event: {
$landPageChangeApp({ name, appIcon, buttonText, commentNum, starNum }, show = true) {
if (!show) {
this.hide();
return;
} else {
this.show();
}
if (name) {
console.log(name);
this.appNameEl.innerText = name;
};
if (name) {
console.log(name);
this.appNameEl.innerText = name;
};
if (commentNum) {
this.appCommentNumEl.innerText = `${padNum(commentNum)}个评分`;
}
if (typeof starNum === 'number') {
this.renderStarNum(starNum);
};
if (buttonText) {
this.appButtonEl.innerText = buttonText;
}
if (appIcon) {
this.appIcon.style.backgroundImage = `url(${appIcon})`;
}
},
ended() {
this.show();
},
$videoReset() {
this.hide();
}
}
};
.video-loading {
background: url('/dafuweng/viewfile.gif') no-repeat;
background-size: contain;
background-color:black;
width: 100%;
height: 100%;
left:0;
top:0;
.video-loading {
background: url('/dafuweng/viewfile.gif') no-repeat;
background-size: contain;
background-color:black;
width: 100%;
height: 100%;
left:0;
top:0;
}
\ No newline at end of file
import './index.less';
const loadingPlugin = {
name: 'loadingPlugin',
zIndex: 2,
created() {
this.el.classList.add('video-loading');
},
methods: {
app() {
console.log(this);
}
},
event: {
canplay() {
console.log('可以播放了');
this.el.style.display = 'none';
},
$videoReset() {
this.el.style.display = 'block';
}
}
};
export default loadingPlugin;
const loadingPlugin = {
name: 'loadingPlugin',
zIndex: 2,
created() {
this.el.classList.add('video-loading');
},
methods: {
app() {
console.log(this);
}
},
event: {
canplay() {
console.log('可以播放了');
this.el.style.display = 'none';
},
$videoReset() {
this.el.style.display = 'block';
}
}
};
export default loadingPlugin;
.none {
opacity: 0;
}
.pointEvent {
pointer-events: auto;
}
.video-control {
position: absolute;
width: 100%;
height: 100%;
left:0;
top:0;
}
.video-voice {
width: 60px;
height: 60px;
position: absolute;
right: 40px;
bottom: 180px;
.none;
.pointEvent;
}
.video-control-muted {
position: absolute;
width: 100%;
height: 100%;
background:url('/dafuweng/muted.png') no-repeat;
background-size: contain;
display: none;
.pointEvent;
}
.video-control-voice {
position: absolute;
width: 100%;
height: 100%;
background:url('/dafuweng/voice.png') no-repeat;
background-size: contain;
display: none;
.pointEvent;
}
.video-close {
position: absolute;
right: 40px;
top: 80px;
width: 60px;
height: 60px;
background: url('/dafuweng/close.png') no-repeat;
background-size: contain;
.none;
.pointEvent;
}
.video-count-down {
position: absolute;
width: 60px;
height: 60px;
border-radius: 100%;
background:gray;
top:80px;
left: 40px;
display: none;
color: white;
font-size: 32px;
display: flex;
align-items: center;
justify-content: center;
.none;
.pointEvent;
.none {
opacity: 0;
}
.pointEvent {
pointer-events: auto;
}
.video-control {
position: absolute;
width: 100%;
height: 100%;
left:0;
top:0;
}
.video-voice {
width: 60px;
height: 60px;
position: absolute;
right: 40px;
bottom: 180px;
.none;
.pointEvent;
}
.video-control-muted {
position: absolute;
width: 100%;
height: 100%;
background:url('/dafuweng/muted.png') no-repeat;
background-size: contain;
display: none;
.pointEvent;
}
.video-control-voice {
position: absolute;
width: 100%;
height: 100%;
background:url('/dafuweng/voice.png') no-repeat;
background-size: contain;
display: none;
.pointEvent;
}
.video-close {
position: absolute;
right: 40px;
top: 80px;
width: 60px;
height: 60px;
background: url('/dafuweng/close.png') no-repeat;
background-size: contain;
.none;
.pointEvent;
}
.video-count-down {
position: absolute;
width: 60px;
height: 60px;
border-radius: 100%;
background:gray;
top:80px;
left: 40px;
display: none;
color: white;
font-size: 32px;
display: flex;
align-items: center;
justify-content: center;
.none;
.pointEvent;
}
\ No newline at end of file
import './index.less';
class VideoControl {
wrapperEl: any;
el: HTMLDivElement;
$player: any;
$video: any;
$wrapper: any;
$contanier: any;
constructor(config) {
this.wrapperEl = config.el;
this.el = document.createElement('div');
this.wrapperEl.appendChild(this.el);
this.$player = config.$player;
this.$video = config.$video;
this.$wrapper = config.$wrapper;
this.$contanier = config.$contanier;
this.el.addEventListener('click', () => {
this.click();
});
}
// 挂载
mount() {
this.wrapperEl.appendChild(this.el);
}
// 展示
show() {
this.el.style.opacity = 1+"";
}
// 隐藏
hide() {
this.el.style.opacity = 0+"";
}
// 点击
click() {
console.log('我被点击了');
}
};
class MutedControl extends VideoControl {
mutedEl: HTMLDivElement;
voiceEl: HTMLDivElement;
constructor(config) {
super(config);
this.mutedEl = document.createElement('div');
this.mutedEl.classList.add('video-control-muted');
this.voiceEl = document.createElement('div');
this.voiceEl.classList.add('video-control-voice');
this.el.appendChild(this.mutedEl);
this.el.appendChild(this.voiceEl);
this.el.classList.add('video-voice');
super.mount();
}
show() {
super.show();
if (this.$video.muted) {
this.showMuted();
} else {
this.showVoice();
}
}
// 展示音量
showVoice() {
this.voiceEl.style.display = 'block';
this.mutedEl.style.display = 'none';
}
// 展示静音
showMuted() {
this.mutedEl.style.display = 'block';
this.voiceEl.style.display = '';
}
// 切换音量
click() {
if (this.$video.muted) {
this.$video.muted = false;
this.showVoice();
} else {
this.$video.muted = true;
this.showMuted();
}
}
};
class CloseControl extends VideoControl {
constructor(config) {
super(config);
this.el.classList.add('video-close');
super.mount();
}
click() {
console.log(this);
this.$player.event.emit('$videoClose');
}
};
class CountDownControl extends VideoControl {
constructor(config) {
super(config);
this.el.classList.add('video-count-down');
super.mount();
}
// 改变节奏
changeText(text) {
this.el.innerText = text;
}
};
export default {
name: 'video-control',
zIndex: 3,
poinerEvents: 'none',
created() {
this.el.classList.add('video-control');
const config = {
el: this.el,
$video: this.$video,
$wrapper: this.$wrapper,
$contanier: this.$contanier,
$player: this.$player
};
this.mutedControl = new MutedControl(config);
this.closeControl = new CloseControl(config);
this.countDownControl = new CountDownControl(config);
},
event: {
canplay() {
this.mutedControl.show();
const duration = Math.floor(this.$video.duration);
this.countDownControl.changeText(duration);
this.countDownControl.show();
},
$closeShow() {
this.closeControl.show();
},
ended() {
this.closeControl.show();
},
timeupdate() {
console.log(this.$video.currentTime);
const time = Math.floor(this.$video.duration - this.$video.currentTime);
if (isNaN(time)) {
this.countDownControl.hide();
} else {
this.countDownControl.show();
}
this.countDownControl.changeText(time);
this.$player.event.emit('$process', Math.floor(this.$video.currentTime / this.$video.duration) * 100);
if (time === 0) {
this.countDownControl.hide();
}
},
$videoReset() {
this.closeControl.hide();
this.countDownControl.hide();
this.mutedControl.hide();
}
}
};
class VideoControl {
wrapperEl: any;
el: HTMLDivElement;
$player: any;
$video: any;
$wrapper: any;
$contanier: any;
constructor(config) {
this.wrapperEl = config.el;
this.el = document.createElement('div');
this.wrapperEl.appendChild(this.el);
this.$player = config.$player;
this.$video = config.$video;
this.$wrapper = config.$wrapper;
this.$contanier = config.$contanier;
this.el.addEventListener('click', () => {
this.click();
});
}
// 挂载
mount() {
this.wrapperEl.appendChild(this.el);
}
// 展示
show() {
this.el.style.opacity = 1+"";
}
// 隐藏
hide() {
this.el.style.opacity = 0+"";
}
// 点击
click() {
console.log('我被点击了');
}
};
class MutedControl extends VideoControl {
mutedEl: HTMLDivElement;
voiceEl: HTMLDivElement;
constructor(config) {
super(config);
this.mutedEl = document.createElement('div');
this.mutedEl.classList.add('video-control-muted');
this.voiceEl = document.createElement('div');
this.voiceEl.classList.add('video-control-voice');
this.el.appendChild(this.mutedEl);
this.el.appendChild(this.voiceEl);
this.el.classList.add('video-voice');
super.mount();
}
show() {
super.show();
if (this.$video.muted) {
this.showMuted();
} else {
this.showVoice();
}
}
// 展示音量
showVoice() {
this.voiceEl.style.display = 'block';
this.mutedEl.style.display = 'none';
}
// 展示静音
showMuted() {
this.mutedEl.style.display = 'block';
this.voiceEl.style.display = '';
}
// 切换音量
click() {
if (this.$video.muted) {
this.$video.muted = false;
this.showVoice();
} else {
this.$video.muted = true;
this.showMuted();
}
}
};
class CloseControl extends VideoControl {
constructor(config) {
super(config);
this.el.classList.add('video-close');
super.mount();
}
click() {
console.log(this);
this.$player.event.emit('$videoClose');
}
};
class CountDownControl extends VideoControl {
constructor(config) {
super(config);
this.el.classList.add('video-count-down');
super.mount();
}
// 改变节奏
changeText(text) {
this.el.innerText = text;
}
};
export default {
name: 'video-control',
zIndex: 3,
poinerEvents: 'none',
created() {
this.el.classList.add('video-control');
const config = {
el: this.el,
$video: this.$video,
$wrapper: this.$wrapper,
$contanier: this.$contanier,
$player: this.$player
};
this.mutedControl = new MutedControl(config);
this.closeControl = new CloseControl(config);
this.countDownControl = new CountDownControl(config);
},
event: {
canplay() {
this.mutedControl.show();
const duration = Math.floor(this.$video.duration);
this.countDownControl.changeText(duration);
this.countDownControl.show();
},
$closeShow() {
this.closeControl.show();
},
ended() {
this.closeControl.show();
},
timeupdate() {
console.log(this.$video.currentTime);
const time = Math.floor(this.$video.duration - this.$video.currentTime);
if (isNaN(time)) {
this.countDownControl.hide();
} else {
this.countDownControl.show();
}
this.countDownControl.changeText(time);
this.$player.event.emit('$process', this.$video.currentTime / this.$video.duration * 100);
if (time === 0) {
this.countDownControl.hide();
}
},
$videoReset() {
this.closeControl.hide();
this.countDownControl.hide();
this.mutedControl.hide();
}
}
};
......@@ -3,34 +3,56 @@ import { getWuhanAds, getVideoIns } from "./Video";
import { NetManager } from "../../libs/tw/manager/NetManager";
import { showToast } from "../../libs/new_wx/ctrls/toastCtrl";
import layers from "../../libs/new_wx/views/layers";
import MyAdvideo from "../adVideo/adVideo";
let videoIns: MyAdvideo;
let videoContanier = document.querySelector('#video-contanier');
export const handleVideo = (
returnCallback: (s: boolean) => void,
completeCallback: Function,
slotid: string,
) => {
Loading.instace.show();
if (!videoIns) {
videoIns = new MyAdvideo({
el: videoContanier
})
}
videoIns.getVideo().then((res) => {
Loading.instace.hide();
if (res) {
videoIns.play().then(() => {
completeCallback();
})
videoIns.player.event.once('$videoClose', () => {
returnCallback(true);
})
} else {
showToast("广告准备中,请稍后再试");
}
});
//发激励视频接口获取素材
getWuhanAds(
(s, res) => {
Loading.instace.hide();
if (s &&
res.data.errcode == "0" &&
res.data.ad &&
res.data.ad[0] &&
res.data.ad[0].rewardvideo
) {
var rewardvideo = res.data.ad[0];
var videoIns = getVideoIns(rewardvideo);
videoIns.returnCallback = returnCallback;
videoIns.completeCallback = completeCallback;
layers.videoLayer.addChild(videoIns)
//app方法
if (window["helpbridge"] && window["helpbridge"].adShowing) window["helpbridge"].adShowing();
} else {
showToast("广告准备中,请稍后再试");
}
},
slotid
)
// getWuhanAds(
// (s, res) => {
// if (s &&
// res.data.errcode == "0" &&
// res.data.ad &&
// res.data.ad[0] &&
// res.data.ad[0].rewardvideo
// ) {
// var rewardvideo = res.data.ad[0];
// var videoIns = getVideoIns(rewardvideo);
// videoIns.returnCallback = returnCallback;
// videoIns.completeCallback = completeCallback;
// console.log(layers);
// console.log(videoContanier);
// layers.videoLayer.addChild(videoIns)
// //app方法
// if (window["helpbridge"] && window["helpbridge"].adShowing) window["helpbridge"].adShowing();
// } else {
// showToast("广告准备中,请稍后再试");
// }
// },
// slotid
// )
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment