UNPKG

clappr-playback-rate-plugin

Version:

A simple plugin for Clappr that adds support to manually select the playback rate on HTML5 containers.

168 lines (135 loc) 4.16 kB
import {Events, Styler, UICorePlugin, template} from '@clappr/player' import pluginHtml from './public/playback-rate-selector.html' import pluginStyle from './public/style.scss' const DEFAULT_PLAYBACK_RATES = [ {value: 0.5, label: '0.5x'}, {value: 0.75, label: '0.75x'}, {value: 1, label: 'Normal'}, {value: 1.5, label: '1.5x'}, {value: 2, label: '2x'} ] const DEFAULT_PLAYBACK_RATE = 1 const DEFAULT_PLAYBACK_RATE_SUFFIX = 'x' // Used by getTitle method export default class PlaybackRatePlugin extends UICorePlugin { get name() { return 'playback_rate' } get template() { return template(pluginHtml) } /** * Clappr 0.4.x wants to know what versions this plugin is targeting. */ get supportedVersion() { return { min: '0.4.0', max: '0.5.0' }; } get attributes() { return { 'class': this.name, 'data-playback-rate-select': '' } } get events() { return { 'click [data-playback-rate-select]': 'onRateSelect', 'click [data-playback-rate-button]': 'onShowMenu' } } get container() { return this.core.activeContainer ? this.core.activeContainer : this.core.mediaControl.container } get playback() { return this.core.activePlayback ? this.core.activePlayback : this.core.getCurrentPlayback() } bindEvents() { if (Events.CORE_ACTIVE_CONTAINER_CHANGED) this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.reload) else this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED, this.reload) this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_RENDERED, this.render) this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_HIDE, this.hideContextMenu) } getExternalInterface() { return { getPlaybackRate: this.getSelectedRate, setPlaybackRate: this.setSelectedRate } } reload() { this.stopListening() this.bindEvents() } shouldRender() { return this.container && ( this.playback.tagName === 'video' || this.playback.tagName === 'audio' ) } render() { if (! this.shouldRender()) return this const cfg = this.core.options.playbackRateConfig || {} this.playbackRates = cfg.options || DEFAULT_PLAYBACK_RATES this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE this.rateSuffix = cfg.rateSuffix || DEFAULT_PLAYBACK_RATE_SUFFIX let t = template(pluginHtml) let html = t({playbackRates: this.playbackRates, title: this.getTitle()}) this.$el.html(html) let style = Styler.getStyleFor(pluginStyle, {baseUrl: this.core.options.baseUrl}) this.$el.append(style) this.core.mediaControl.$('.media-control-right-panel').append(this.el) this.updateText() return this } onRateSelect(event) { event.stopPropagation() let rate = event.target.dataset.playbackRateSelect // data-playback-rate-select this.setSelectedRate(rate) this.toggleContextMenu() return false } onShowMenu() { this.toggleContextMenu() } toggleContextMenu() { this.$('.playback_rate ul').toggle() } hideContextMenu() { this.$('.playback_rate ul').hide() } toNumber(value) { value = Number(value) // Fallback to default playback rate if cannot be converted return isNaN(value) ? DEFAULT_PLAYBACK_RATE : value } setSelectedRate(rate) { rate = this.toNumber(rate) this.playback.el.playbackRate = rate this.selectedRate = rate this.updateText() } getSelectedRate() { return this.selectedRate } setActiveListItem(rateValue) { this.$('a').removeClass('active') this.$(`a[data-playback-rate-select="${rateValue}"]`).addClass('active') } buttonElement() { return this.$('.playback_rate button') } getTitle() { let rate = this.selectedRate for (const i in this.playbackRates) { if (this.playbackRates[i].value == rate) return this.playbackRates[i].label } // Unknown rate formatted title return rate + this.rateSuffix } updateText() { this.buttonElement().text(this.getTitle()) this.setActiveListItem(this.selectedRate) } }