ps-tcplayer
Version:
Tencent Cloud Player component with Vue2/Vue3 compatibility
285 lines (253 loc) • 9.3 kB
JavaScript
import qualityHtml from './index.html'
import qualityModal from './quality-modal.html'
import './index.scss'
import { parseDom } from '../../utils'
/**
* 切换清晰度组件
*/
export default class QualityComponent {
constructor(player, getQuality, definition, desc) {
this.player = player
this.html = parseDom(qualityHtml)
this.modalHtml = parseDom(qualityModal)
this.hasCreated = false
this.definition = definition
this.getQuality = getQuality
this.desc = desc
this.html.style.display = 'none'
}
createEl (el) {
const player = this.player;
let lang = false;
try {
if (typeof player.lang === 'function') {
lang = player.lang() === 'en-us';
}
else if (typeof player.lang === 'string') {
lang = player.lang === 'en-us';
}
else if (player.options_ && player.options_.language) {
lang = player.options_.language === 'en-us';
}
} catch (e) {
console.warn('无法获取播放器语言设置,使用默认中文');
}
this.isEn = lang;
this.html.querySelector('.current-quality-cto').innerText = this.isEn ? 'Resolution' : (this.desc || '清晰度');
this.modalHtml.querySelector('.switchimg').innerText = this.isEn ? 'Switching to you for' : '正在为您切换到';
this.modalHtml.querySelector('.wait').innerText = this.isEn ? 'Please wait...' : '请稍后...';
// vjs-control-bar
// TODO 看是否需要更改
let eleControlbar = el.querySelector('.vjs-control-bar');
console.log(this.html, 'this.html');
if (eleControlbar) {
eleControlbar.appendChild(this.html);
} else {
console.warn('找不到播放器控制栏,尝试添加到根元素');
el.appendChild(this.html);
console.log(this.html, 'this.html');
}
el.appendChild(this.modalHtml);
}
setCurrentQuality(quality, def) {
this.html.style.display = 'block'
let currentQuality = this.html.querySelector('.current-quality-cto')
currentQuality.innerText = quality
currentQuality.dataset.def = def
this.definition = def
let qualityListEle = this.html.querySelector('.quality-list')
let currentEle = qualityListEle.querySelector('.current')
if (currentEle) {
currentEle.className = ''
}
let li_target = qualityListEle.querySelector(`li[data-def="${def}"]`)
if (li_target) {
li_target.className = 'current'
}
}
filterDefinitionList(urls) {
return urls.filter(url => url.definition !== 'SD')
}
created() {
const player = this.player;
try {
let qualityLevels = [];
if (player.getVideoQualityList && typeof player.getVideoQualityList === 'function') {
qualityLevels = player.getVideoQualityList();
}
else if (player.qualities && typeof player.qualities === 'function') {
qualityLevels = player.qualities();
}
else if (player.tech_ && player.tech_.hls && player.tech_.hls.representations) {
const reps = player.tech_.hls.representations();
qualityLevels = Array.from(reps).map((rep, index) => {
return {
definition: rep.height + 'p',
name: rep.height + 'p',
url: rep.id
};
});
}
else {
console.warn('无法获取清晰度列表,使用默认值');
qualityLevels = [
{ definition: 'HD', name: '超清', url: '' },
{ definition: 'SD', name: '标清', url: '' }
];
}
this._urls = qualityLevels.map(quality => {
return {
definition: quality.definition || quality.id || 'HD',
desc: quality.name || quality.label || '高清',
Url: quality.url || ''
};
});
if (!this._urls || this._urls.length === 0) {
this._urls = [
{ definition: 'HD', desc: '超清', Url: '' },
{ definition: 'SD', desc: '标清', Url: '' }
];
}
for (var index = 0; index < this._urls.length; index++) {
if ('AUTO' === this._urls[index].definition) {
this._urls[index].desc = '自动';
}
if (!this._urls[index].desc) {
this._urls[index].desc = '';
}
}
let currentQualityEle = this.html.querySelector('.current-quality-cto');
let qualityListEle = this.html.querySelector('.quality-list');
if (!currentQualityEle || !qualityListEle) {
console.error('清晰度组件HTML元素未找到');
return;
}
let definitionList = this.filterDefinitionList(this._urls);
let lis_ele = definitionList.map(url => {
return `<li data-def="${url.definition}">${url.desc}</li>`;
});
const qualityList = this.html.querySelector('.quality-list');
if (qualityList) {
qualityList.innerHTML = lis_ele.join('');
}
if (this.hasCreated == false) {
if(!this.definition && this._urls.length > 0){
let li_target = qualityListEle.querySelector(`li[data-def="${this._urls[0].definition}"]`);
if (li_target) {
li_target.className = 'current';
currentQualityEle.innerText = this._urls[0].desc;
}
} else {
for (var index = 0; index < this._urls.length; index++) {
if(this.definition == this._urls[index].definition){
var li_target = qualityListEle.querySelector(`li[data-def="${this.definition}"]`);
if (li_target) {
li_target.className = 'current';
currentQualityEle.innerText = this._urls[index].desc;
}
break;
}
}
}
}
this.hasCreated = true;
let timeId = null;
currentQualityEle.onclick = () => {
qualityListEle.style.display = 'block';
};
currentQualityEle.onmouseleave = () => {
timeId = setTimeout(() => {
qualityListEle.style.display = 'none';
}, 100);
};
qualityListEle.onmouseenter = () => {
clearTimeout(timeId);
};
qualityListEle.onmouseleave = () => {
qualityListEle.style.display = 'none';
};
qualityListEle.onclick = ({target}) => {
let definition = target.dataset.def;
let desc = target.innerText;
if (definition) {
if (target.className !== 'current') {
let url = this._urls.find(url => url.definition === definition);
if (!url) return;
let currentTime = 0;
try {
currentTime = player.currentTime();
} catch (e) {
console.warn('无法获取当前播放时间', e);
}
try {
if (player.switchQuality && typeof player.switchQuality === 'function') {
player.switchQuality(definition);
} else if (player.tech_ && player.tech_.hls && player.tech_.hls.selectPlaylist) {
const reps = player.tech_.hls.representations();
const rep = Array.from(reps).find(r => r.height + 'p' === definition);
if (rep) {
rep.enabled(true);
}
}
} catch (e) {
console.warn('切换清晰度失败', e);
}
this.setCurrentQuality(url.desc, url.definition);
this.modalHtml.style.display = 'block';
const qualityTag = this.modalHtml.querySelector('span.current-quality-tag');
if (qualityTag) {
qualityTag.innerText = url.desc;
}
setTimeout(() => {
try {
player.currentTime(currentTime);
} catch (e) {
console.warn('无法设置播放时间', e);
}
}, 500);
}
}
console.log(definition, 'getQuality-definition');
console.log(desc, 'getQuality-desc');
try {
localStorage.setItem("cto_video_definition", definition);
localStorage.setItem("cto_video_desc", desc);
} catch (e) {
console.warn('无法保存清晰度设置到localStorage', e);
}
timeId = setTimeout(() => {
qualityListEle.style.display = 'none';
}, 100);
};
} catch (err) {
console.error('QualityComponent创建过程出错:', err);
}
}
ready() {
const player = this.player;
try {
let Quality = null;
if (player.getVideoQuality && typeof player.getVideoQuality === 'function') {
try {
Quality = player.getVideoQuality();
console.log(Quality, 'Quality');
} catch (e) {
console.warn('获取视频清晰度失败', e);
}
}
if (this.modalHtml) {
this.modalHtml.style.display = 'none';
}
try {
let settingEle = document.querySelector('.vcp-quality');
if (settingEle) {
settingEle.style.display = 'none';
}
} catch (e) {
console.warn('无法隐藏原始清晰度按钮', e);
}
} catch (err) {
console.error('QualityComponent ready过程出错:', err);
}
}
}