UNPKG

ps-tcplayer

Version:

Tencent Cloud Player component with Vue2/Vue3 compatibility

285 lines (253 loc) 9.3 kB
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); } } }