Merge branch 'pr/dpgiakatos/943'
This commit is contained in:
commit
fccdda6d47
|
|
@ -79,6 +79,7 @@
|
|||
"dependencies": {
|
||||
"axios": "0.27.2",
|
||||
"balloon-css": "^1.0.3",
|
||||
"promise-polyfill": "8.2.3"
|
||||
"promise-polyfill": "8.2.3",
|
||||
"rxjs": "^6.6.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="chromecast" class="svg-inline--fa fa-chromecast fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M447.8,64H64c-23.6,0-42.7,19.1-42.7,42.7v63.9H64v-63.9h383.8v298.6H298.6V448H448c23.6,0,42.7-19.1,42.7-42.7V106.7 C490.7,83.1,471.4,64,447.8,64z M21.3,383.6L21.3,383.6l0,63.9h63.9C85.2,412.2,56.6,383.6,21.3,383.6L21.3,383.6z M21.3,298.6V341 c58.9,0,106.6,48.1,106.6,107h42.7C170.7,365.6,103.7,298.7,21.3,298.6z M213.4,448h42.7c-0.5-129.5-105.3-234.3-234.8-234.6l0,42.4 C127.3,255.6,213.3,342,213.4,448z"></path></svg>
|
||||
|
After Width: | Height: | Size: 642 B |
|
|
@ -167,6 +167,7 @@
|
|||
.dplayer-volume,
|
||||
.dplayer-camera-icon,
|
||||
.dplayer-airplay-icon,
|
||||
.dplayer-chromecast-icon,
|
||||
.dplayer-play-icon {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
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) {
|
||||
|
|
@ -31,6 +36,7 @@ class Controller {
|
|||
this.initSubtitleButton();
|
||||
this.initHighlights();
|
||||
this.initAirplayButton();
|
||||
this.initChromecastButton();
|
||||
if (!utils.isMobile) {
|
||||
this.initVolumeButton();
|
||||
}
|
||||
|
|
@ -279,6 +285,90 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
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', () => {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ const tranTxt = {
|
|||
Send: '发送',
|
||||
Screenshot: '截图',
|
||||
AirPlay: '无线投屏',
|
||||
ChromeCast: 'ChromeCast',
|
||||
s: '秒',
|
||||
'Show subtitle': '显示字幕',
|
||||
'Hide subtitle': '隐藏字幕',
|
||||
|
|
@ -93,6 +94,7 @@ const tranTxt = {
|
|||
Send: '發送',
|
||||
Screenshot: '截圖',
|
||||
AirPlay: '無線投屏',
|
||||
ChromeCast: 'ChromeCast',
|
||||
s: '秒',
|
||||
'Show subtitle': '顯示字幕',
|
||||
'Hide subtitle': '隱藏字幕',
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import camera from '../assets/camera.svg';
|
|||
import airplay from '../assets/airplay.svg';
|
||||
import subtitle from '../assets/subtitle.svg';
|
||||
import loading from '../assets/loading.svg';
|
||||
import chromecast from '../assets/chromecast.svg';
|
||||
|
||||
const Icons = {
|
||||
play: play,
|
||||
|
|
@ -34,6 +35,7 @@ const Icons = {
|
|||
subtitle: subtitle,
|
||||
loading: loading,
|
||||
airplay: airplay,
|
||||
chromecast: chromecast,
|
||||
};
|
||||
|
||||
export default Icons;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* global DPLAYER_VERSION */
|
||||
import defaultApiBackend from './api.js';
|
||||
import utils from './utils';
|
||||
|
||||
export default (options) => {
|
||||
// default options
|
||||
|
|
@ -12,6 +13,7 @@ export default (options) => {
|
|||
lang: (navigator.language || navigator.browserLanguage).toLowerCase(),
|
||||
screenshot: false,
|
||||
airplay: true,
|
||||
chromecast: utils.isChrome,
|
||||
hotkey: true,
|
||||
preload: 'metadata',
|
||||
volume: 0.7,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class Template {
|
|||
pic: this.options.video.pic,
|
||||
screenshot: this.options.screenshot,
|
||||
airplay: this.options.airplay,
|
||||
chromecast: this.options.chromecast,
|
||||
preload: this.options.preload,
|
||||
url: this.options.video.url,
|
||||
subtitle: this.options.subtitle,
|
||||
|
|
@ -80,6 +81,7 @@ class Template {
|
|||
this.qualityList = this.container.querySelector('.dplayer-quality-list');
|
||||
this.camareButton = this.container.querySelector('.dplayer-camera-icon');
|
||||
this.airplayButton = this.container.querySelector('.dplayer-airplay-icon');
|
||||
this.chromecastButton = this.container.querySelector('.dplayer-chromecast-icon');
|
||||
this.subtitleButton = this.container.querySelector('.dplayer-subtitle-icon');
|
||||
this.subtitleButtonInner = this.container.querySelector('.dplayer-subtitle-icon .dplayer-icon-content');
|
||||
this.subtitle = this.container.querySelector('.dplayer-subtitle');
|
||||
|
|
|
|||
|
|
@ -120,6 +120,11 @@
|
|||
<span class="dplayer-icon-content">{{@ icons.airplay }}</span>
|
||||
</div>
|
||||
{{ /if }}
|
||||
{{ if options.chromecast }}
|
||||
<div class="dplayer-icon dplayer-chromecast-icon" data-balloon="{{ tran('ChromeCast') }}" data-balloon-pos="up">
|
||||
<span class="dplayer-icon-content">{{@ icons.chromecast }}</span>
|
||||
</div>
|
||||
{{ /if }}
|
||||
<div class="dplayer-comment">
|
||||
<button class="dplayer-icon dplayer-comment-icon" data-balloon="{{ tran('Send danmaku') }}" data-balloon-pos="up">
|
||||
<span class="dplayer-icon-content">{{@ icons.comment }}</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue