123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- import utils from './utils';
- import Thumbnails from './thumbnails';
- import Icons from './icons';
- import { Subject } from 'rxjs';
- let cast;
- let runOnce = true;
- let isCasting = false;
- class Controller {
- constructor(player) {
- this.player = player;
- this.autoHideTimer = 0;
- if (!utils.isMobile) {
- this.player.container.addEventListener('mousemove', () => {
- this.setAutoHide();
- });
- this.player.container.addEventListener('click', () => {
- this.setAutoHide();
- });
- this.player.on('play', () => {
- this.setAutoHide();
- });
- this.player.on('pause', () => {
- this.setAutoHide();
- });
- }
- this.initPlayButton();
- this.initThumbnails();
- this.initPlayedBar();
- this.initFullButton();
- this.initQualityButton();
- this.initScreenshotButton();
- this.initSubtitleButton();
- this.initHighlights();
- this.initAirplayButton();
- this.initChromecastButton();
- if (!utils.isMobile) {
- this.initVolumeButton();
- }
- }
- initPlayButton() {
- this.player.template.playButton.addEventListener('click', () => {
- this.player.toggle();
- });
- this.player.template.mobilePlayButton.addEventListener('click', () => {
- this.player.toggle();
- });
- if (!utils.isMobile) {
- this.player.template.videoWrap.addEventListener('click', () => {
- this.player.toggle();
- });
- this.player.template.controllerMask.addEventListener('click', () => {
- this.player.toggle();
- });
- } else {
- this.player.template.videoWrap.addEventListener('click', () => {
- this.toggle();
- });
- this.player.template.controllerMask.addEventListener('click', () => {
- this.toggle();
- });
- }
- }
- initHighlights() {
- this.player.on('durationchange', () => {
- if (this.player.video.duration !== 1 && this.player.video.duration !== Infinity) {
- if (this.player.options.highlight) {
- const highlights = document.querySelectorAll('.dplayer-highlight');
- [].slice.call(highlights, 0).forEach((item) => {
- this.player.template.playedBarWrap.removeChild(item);
- });
- for (let i = 0; i < this.player.options.highlight.length; i++) {
- if (!this.player.options.highlight[i].text || !this.player.options.highlight[i].time) {
- continue;
- }
- const p = document.createElement('div');
- p.classList.add('dplayer-highlight');
- p.style.left = (this.player.options.highlight[i].time / this.player.video.duration) * 100 + '%';
- p.innerHTML = '<span class="dplayer-highlight-text">' + this.player.options.highlight[i].text + '</span>';
- this.player.template.playedBarWrap.insertBefore(p, this.player.template.playedBarTime);
- }
- }
- }
- });
- }
- initThumbnails() {
- if (this.player.options.video.thumbnails) {
- this.thumbnails = new Thumbnails({
- container: this.player.template.barPreview,
- barWidth: this.player.template.barWrap.offsetWidth,
- url: this.player.options.video.thumbnails,
- events: this.player.events,
- });
- this.player.on('loadedmetadata', () => {
- this.thumbnails.resize(160, (this.player.video.videoHeight / this.player.video.videoWidth) * 160, this.player.template.barWrap.offsetWidth);
- });
- }
- }
- initPlayedBar() {
- const thumbMove = (e) => {
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - utils.getBoundingClientRectViewLeft(this.player.template.playedBarWrap)) / this.player.template.playedBarWrap.clientWidth;
- percentage = Math.max(percentage, 0);
- percentage = Math.min(percentage, 1);
- this.player.bar.set('played', percentage, 'width');
- this.player.template.ptime.innerHTML = utils.secondToTime(percentage * this.player.video.duration);
- };
- const thumbUp = (e) => {
- document.removeEventListener(utils.nameMap.dragEnd, thumbUp);
- document.removeEventListener(utils.nameMap.dragMove, thumbMove);
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - utils.getBoundingClientRectViewLeft(this.player.template.playedBarWrap)) / this.player.template.playedBarWrap.clientWidth;
- percentage = Math.max(percentage, 0);
- percentage = Math.min(percentage, 1);
- this.player.bar.set('played', percentage, 'width');
- this.player.seek(this.player.bar.get('played') * this.player.video.duration);
- this.player.timer.enable('progress');
- };
- this.player.template.playedBarWrap.addEventListener(utils.nameMap.dragStart, () => {
- this.player.timer.disable('progress');
- document.addEventListener(utils.nameMap.dragMove, thumbMove);
- document.addEventListener(utils.nameMap.dragEnd, thumbUp);
- });
- this.player.template.playedBarWrap.addEventListener(utils.nameMap.dragMove, (e) => {
- if (this.player.video.duration) {
- const px = this.player.template.playedBarWrap.getBoundingClientRect().left;
- const tx = (e.clientX || e.changedTouches[0].clientX) - px;
- if (tx < 0 || tx > this.player.template.playedBarWrap.offsetWidth) {
- return;
- }
- const time = this.player.video.duration * (tx / this.player.template.playedBarWrap.offsetWidth);
- if (utils.isMobile) {
- this.thumbnails && this.thumbnails.show();
- }
- this.thumbnails && this.thumbnails.move(tx);
- this.player.template.playedBarTime.style.left = `${tx - (time >= 3600 ? 25 : 20)}px`;
- this.player.template.playedBarTime.innerText = utils.secondToTime(time);
- this.player.template.playedBarTime.classList.remove('hidden');
- }
- });
- this.player.template.playedBarWrap.addEventListener(utils.nameMap.dragEnd, () => {
- if (utils.isMobile) {
- this.thumbnails && this.thumbnails.hide();
- }
- });
- if (!utils.isMobile) {
- this.player.template.playedBarWrap.addEventListener('mouseenter', () => {
- if (this.player.video.duration) {
- this.thumbnails && this.thumbnails.show();
- this.player.template.playedBarTime.classList.remove('hidden');
- }
- });
- this.player.template.playedBarWrap.addEventListener('mouseleave', () => {
- if (this.player.video.duration) {
- this.thumbnails && this.thumbnails.hide();
- this.player.template.playedBarTime.classList.add('hidden');
- }
- });
- }
- }
- initFullButton() {
- this.player.template.browserFullButton.addEventListener('click', () => {
- this.player.fullScreen.toggle('browser');
- });
- this.player.template.webFullButton.addEventListener('click', () => {
- this.player.fullScreen.toggle('web');
- });
- }
- initVolumeButton() {
- const vWidth = 35;
- const volumeMove = (event) => {
- const e = event || window.event;
- const percentage = ((e.clientX || e.changedTouches[0].clientX) - utils.getBoundingClientRectViewLeft(this.player.template.volumeBarWrap) - 5.5) / vWidth;
- this.player.volume(percentage);
- };
- const volumeUp = () => {
- document.removeEventListener(utils.nameMap.dragEnd, volumeUp);
- document.removeEventListener(utils.nameMap.dragMove, volumeMove);
- this.player.template.volumeButton.classList.remove('dplayer-volume-active');
- };
- this.player.template.volumeBarWrapWrap.addEventListener('click', (event) => {
- const e = event || window.event;
- const percentage = ((e.clientX || e.changedTouches[0].clientX) - utils.getBoundingClientRectViewLeft(this.player.template.volumeBarWrap) - 5.5) / vWidth;
- this.player.volume(percentage);
- });
- this.player.template.volumeBarWrapWrap.addEventListener(utils.nameMap.dragStart, () => {
- document.addEventListener(utils.nameMap.dragMove, volumeMove);
- document.addEventListener(utils.nameMap.dragEnd, volumeUp);
- this.player.template.volumeButton.classList.add('dplayer-volume-active');
- });
- this.player.template.volumeButtonIcon.addEventListener('click', () => {
- if (this.player.video.muted) {
- this.player.video.muted = false;
- this.player.switchVolumeIcon();
- this.player.bar.set('volume', this.player.volume(), 'width');
- } else {
- this.player.video.muted = true;
- this.player.template.volumeIcon.innerHTML = Icons.volumeOff;
- this.player.bar.set('volume', 0, 'width');
- }
- });
- }
- initQualityButton() {
- if (this.player.options.video.quality) {
- this.player.template.qualityList.addEventListener('click', (e) => {
- if (e.target.classList.contains('dplayer-quality-item')) {
- this.player.switchQuality(e.target.dataset.index);
- }
- });
- }
- }
- initScreenshotButton() {
- if (this.player.options.screenshot) {
- this.player.template.camareButton.addEventListener('click', () => {
- const canvas = document.createElement('canvas');
- canvas.width = this.player.video.videoWidth;
- canvas.height = this.player.video.videoHeight;
- canvas.getContext('2d').drawImage(this.player.video, 0, 0, canvas.width, canvas.height);
- let dataURL;
- canvas.toBlob((blob) => {
- dataURL = URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = dataURL;
- link.download = 'DPlayer.png';
- link.style.display = 'none';
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- URL.revokeObjectURL(dataURL);
- });
- this.player.events.trigger('screenshot', dataURL);
- });
- }
- }
- initAirplayButton() {
- if (this.player.options.airplay) {
- if (window.WebKitPlaybackTargetAvailabilityEvent) {
- this.player.video.addEventListener(
- 'webkitplaybacktargetavailabilitychanged',
- function (event) {
- switch (event.availability) {
- case 'available':
- this.template.airplayButton.disable = false;
- break;
- default:
- this.template.airplayButton.disable = true;
- }
- this.template.airplayButton.addEventListener(
- 'click',
- function () {
- this.video.webkitShowPlaybackTargetPicker();
- }.bind(this)
- );
- }.bind(this.player)
- );
- } else {
- this.player.template.airplayButton.style.display = 'none';
- }
- }
- }
- initChromecast() {
- const script = window.document.createElement('script');
- script.setAttribute('type', 'text/javascript');
- script.setAttribute('src', 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1');
- window.document.body.appendChild(script);
- window.__onGCastApiAvailable = (isAvailable) => {
- if (isAvailable) {
- cast = window.chrome.cast;
- const sessionRequest = new cast.SessionRequest(cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID);
- const apiConfig = new cast.ApiConfig(
- sessionRequest,
- () => {},
- (status) => {
- if (status === cast.ReceiverAvailability.AVAILABLE) {
- console.log('chromecast: ', status);
- }
- }
- );
- cast.initialize(apiConfig, () => {});
- }
- };
- }
- initChromecastButton() {
- if (this.player.options.chromecast) {
- if (runOnce) {
- runOnce = false;
- this.initChromecast();
- }
- const discoverDevices = () => {
- const subj = new Subject();
- cast.requestSession(
- (s) => {
- this.session = s;
- subj.next('CONNECTED');
- launchMedia(this.player.options.video.url);
- },
- (err) => {
- if (err.code === 'cancel') {
- this.session = undefined;
- subj.next('CANCEL');
- } else {
- console.error('Error selecting a cast device', err);
- }
- }
- );
- return subj;
- };
- const launchMedia = (media) => {
- const mediaInfo = new cast.media.MediaInfo(media);
- const request = new cast.media.LoadRequest(mediaInfo);
- if (!this.session) {
- window.open(media);
- return false;
- }
- this.session.loadMedia(request, onMediaDiscovered.bind(this, 'loadMedia'), onMediaError).play();
- return true;
- };
- const onMediaDiscovered = (how, media) => {
- this.currentMedia = media;
- };
- const onMediaError = (err) => {
- console.error('Error launching media', err);
- };
- this.player.template.chromecastButton.addEventListener('click', () => {
- if (isCasting) {
- isCasting = false;
- this.currentMedia.stop();
- this.session.stop();
- this.initChromecast();
- } else {
- isCasting = true;
- discoverDevices();
- }
- });
- }
- }
- initSubtitleButton() {
- if (this.player.options.subtitle) {
- this.player.events.on('subtitle_show', () => {
- this.player.template.subtitleButton.dataset.balloon = this.player.tran('Hide subtitle');
- this.player.template.subtitleButtonInner.style.opacity = '';
- this.player.user.set('subtitle', 1);
- });
- this.player.events.on('subtitle_hide', () => {
- this.player.template.subtitleButton.dataset.balloon = this.player.tran('Show subtitle');
- this.player.template.subtitleButtonInner.style.opacity = '0.4';
- this.player.user.set('subtitle', 0);
- });
- this.player.template.subtitleButton.addEventListener('click', () => {
- this.player.subtitle.toggle();
- });
- }
- }
- setAutoHide() {
- this.show();
- clearTimeout(this.autoHideTimer);
- this.autoHideTimer = setTimeout(() => {
- if (this.player.video.played.length && !this.player.paused && !this.disableAutoHide) {
- this.hide();
- }
- }, 3000);
- }
- show() {
- this.player.container.classList.remove('dplayer-hide-controller');
- }
- hide() {
- this.player.container.classList.add('dplayer-hide-controller');
- this.player.setting.hide();
- this.player.comment && this.player.comment.hide();
- }
- isShow() {
- return !this.player.container.classList.contains('dplayer-hide-controller');
- }
- toggle() {
- if (this.isShow()) {
- this.hide();
- } else {
- this.show();
- }
- }
- destroy() {
- clearTimeout(this.autoHideTimer);
- }
- }
- export default Controller;
|