Merge pull request #209 from zhw2590582/ads-option

Ads option
This commit is contained in:
Harvey Zack authored and GitHub committed 2021-12-23 16:47:36 +08:00
commit 362a89c4f6
19 files changed
+391 -15

No files matched your search

@@ -0,0 +1,78 @@
---
title: How to add video ads
sidebar_position: 5
---
Video ads play before main video playback, support multiple video ads
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://artplayer.org/assets/sample/video.mp4',
muted: true,
autoSize: true,
autoplay: true,
ads: [
{
url: '/assets/sample/test1.mp4'
},
{
url: '/assets/sample/test2.webm'
},
],
controls: [
{
position: 'right',
html: 'Skip The Ads',
click: function () {
// Skip The Ads
art.ads.end();
},
},
],
layers: [
{
html: 'Skip The Ads',
style: {
position: 'absolute',
top: '20px',
right: '20px',
},
click: function () {
// Skip The Ads
art.ads.end();
},
},
],
});
// Triggers when each video advertisement is played
art.on('ads:start', (item) => {
console.info('Ads is playing: ' + item.url);
});
// Triggers when all video advertisements are end
art.on('ads:end', () => {
console.info('Ads is end');
});
// Current advertising index
console.info(art.ads.index);
// Whether all the advertisements are ended
console.info(art.ads.isEnd);
// Whether the advertisement is playing
console.info(art.ads.playing);
// The object of the prev advertisement
console.info(art.ads.prev);
// The object of the current advertisement
console.info(art.ads.current);
// The object of the next advertisement
console.info(art.ads.next);
```
@@ -0,0 +1,78 @@
---
title: 如何添加视频广告
sidebar_position: 5
---
视频广告存在于正式视频播放之前,支持多个视频广告
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://artplayer.org/assets/sample/video.mp4',
muted: true,
autoSize: true,
autoplay: true,
ads: [
{
url: '/assets/sample/test1.mp4'
},
{
url: '/assets/sample/test2.webm'
},
],
controls: [
{
position: 'right',
html: '跳过广告',
click: function () {
// 跳过广告
art.ads.end();
},
},
],
layers: [
{
html: '跳过广告',
style: {
position: 'absolute',
top: '20px',
right: '20px',
},
click: function () {
// 跳过广告
art.ads.end();
},
},
],
});
// 当每个视频广告播放时触发
art.on('ads:start', (item) => {
console.info('Ads is playing: ' + item.url);
});
// 当全部视频广告播放完成
art.on('ads:end', () => {
console.info('Ads is end');
});
// 当前广告的下标
console.info(art.ads.index);
// 广告是否已经结束
console.info(art.ads.isEnd);
// 广告是否正在播放
console.info(art.ads.playing);
// 上一个广告的对象
console.info(art.ads.prev);
// 当前广告的对象
console.info(art.ads.current);
// 下一个广告的对象
console.info(art.ads.next);
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "artplayer",
"version": "4.0.9",
"version": "4.1.0",
"expose": "Artplayer",
"description": "ArtPlayer.js is a modern and full featured HTML5 video player",
"main": "dist/artplayer.js",
+56
View File
@@ -0,0 +1,56 @@
export default class Ads {
constructor(art) {
this.art = art;
const { option } = art;
this.index = 0;
this.isEnd = false;
this.playing = false;
this.urlCache = option.url;
if (this.current) {
this.playing = true;
this.play(this.current);
}
}
get current() {
return this.art.option.ads[this.index];
}
get prev() {
return this.art.option.ads[this.index - 1];
}
get next() {
return this.art.option.ads[this.index + 1];
}
play(item = {}) {
if (this.isEnd) return;
this.art.player.switchUrl(item.url);
this.art.once('video:timeupdate', () => {
this.art.emit('ads:start', item);
});
this.art.once('video:ended', () => {
const next = this.next;
if (next) {
this.index += 1;
this.play(next);
} else {
this.end();
}
});
}
end() {
if (this.isEnd) return;
this.isEnd = true;
this.playing = false;
this.art.option.url = this.urlCache;
this.art.player.switchUrl(this.urlCache);
this.art.emit('ads:end');
}
}
+1 -1
View File
@@ -111,7 +111,7 @@ export default function progress(option) {
setBar('loaded', player.loaded);
});
art.on('video:timeupdate', () => {
art.on('timeupdate', () => {
setBar('played', player.played);
});
+3
View File
@@ -22,6 +22,7 @@ import Icons from './icons';
import Setting from './setting';
import Storage from './storage';
import Plugins from './plugins';
import Ads from './ads';
import Mobile from './mobile';
let id = 0;
@@ -52,6 +53,7 @@ export default class Artplayer extends Emitter {
this.controls = new Control(this);
this.contextmenu = new Contextmenu(this);
this.subtitle = new Subtitle(this);
this.ads = new Ads(this);
this.info = new Info(this);
this.loading = new Loading(this);
this.hotkey = new Hotkey(this);
@@ -141,6 +143,7 @@ export default class Artplayer extends Emitter {
localVideo: false,
localSubtitle: false,
useSSR: false,
ads: [],
layers: [],
contextmenu: [],
controls: [],
+4 -1
View File
@@ -34,5 +34,8 @@ export default function attrInit(art, player) {
}
$video.controls = false;
player.url = option.url;
if (option.ads.length === 0) {
player.url = option.url;
}
}
+2
View File
@@ -2,6 +2,7 @@ import urlMix from './urlMix';
import attrInit from './attrInit';
import eventInit from './eventInit';
import exclusiveInit from './exclusiveInit';
import timeupdateInit from './timeupdateInit';
import playMix from './playMix';
import pauseMix from './pauseMix';
import toggleMix from './toggleMix';
@@ -34,6 +35,7 @@ export default class Player {
eventInit(art, this);
attrInit(art, this);
exclusiveInit(art, this);
timeupdateInit(art, this);
playMix(art, this);
pauseMix(art, this);
toggleMix(art, this);
+1 -1
View File
@@ -22,7 +22,7 @@ export default function loopMin(art, player) {
},
});
art.on('video:timeupdate', () => {
art.on('timeupdate', () => {
if (interval.length) {
if (player.currentTime < interval[0] || player.currentTime > interval[1]) {
player.seek = interval[0];
+1 -2
View File
@@ -7,7 +7,6 @@ export default function switchMix(art, player) {
return new Promise((resolve) => {
if (url === player.url) return resolve(url);
URL.revokeObjectURL(player.url);
const { playing } = player;
player.url = url;
art.once('video:canplay', () => {
player.playbackRate = false;
@@ -16,7 +15,7 @@ export default function switchMix(art, player) {
player.autoSize = option.autoSize;
player.currentTime = currentTime;
art.notice.show = '';
if (playing) {
if (player.playing) {
player.play();
}
if (name) {
@@ -0,0 +1,14 @@
export default function timeupdateInit(art, player) {
let timer = null;
(function timeupdate() {
art.emit('timeupdate', player.currentTime || 0);
if (!art.isDestroy) {
timer = window.requestAnimationFrame(timeupdate);
}
})();
art.on('destroy', () => {
window.cancelAnimationFrame(timer);
});
}
@@ -25,7 +25,7 @@ export default function miniProgressBar(art) {
$progressBar.style.display = 'none';
});
art.on('video:timeupdate', () => {
art.on('timeupdate', () => {
$progressBar.style.width = `${player.played * 100}%`;
});
},
+5
View File
@@ -57,6 +57,11 @@ export default {
localVideo: b,
localSubtitle: b,
useSSR: b,
ads: [
{
url: s,
},
],
plugins: [f],
whitelist: [`${s}|${f}|${r}`],
layers: [ComponentOption],
+22
View File
@@ -139,6 +139,13 @@ type SubtitleOption = {
bilingual?: boolean;
};
type AdsOption = {
/**
* The ads video url
*/
url: string;
};
type Option = {
/**
* The container mounted by the player
@@ -305,6 +312,11 @@ type Option = {
*/
whitelist?: (string | WhitelistFunction | RegExp)[];
/**
* Custom ads list
*/
ads?: AdsOption[];
/**
* Custom layer list
*/
@@ -644,6 +656,16 @@ declare class Artplayer extends Player {
switch(url: string, option?: SubtitleOption): Promise<string>;
};
readonly ads: {
index: number;
isEnd: boolean;
playing: boolean;
current: AdsOption;
prev: AdsOption;
next: AdsOption;
end(): void;
};
readonly mobile: object;
readonly player: Player;