1import ControlBar from 'models/collect_player/control_bar' 2import Events from 'models/collect_player/events' 3import ProgressBar from 'models/collect_player/progress_bar' 4import Source from 'models/collect_player/source' 5import Visualizer from 'models/collect_player/visualizer' 6 7export default class Player { 8 9 constructor(controller) { 10 this.controller = controller 11 this.element = controller.element 12 this.canvas = controller.canvasTarget 13 14 this.controlBar = new ControlBar(this) 15 this.events = new Events(this) 16 this.progressBar = new ProgressBar(this) 17 this.source = new Source(this) 18 this.visualizer = new Visualizer(this) 19 20 this.element.player = this 21 } 22 23 get mediaElements() { 24 return [this.controller.audioTarget, this.controller.videoTarget] 25 } 26 27 destroy() { 28 this.events.unbind() 29 this.progressBar.stop() 30 this.visualizer.destroy() 31 } 32 33 isMobile() { 34 return this.element.classList.contains('mobile-player') 35 } 36 37 // ---------- 38 // Playback 39 // ---------- 40 41 // iPhone displays a black frame when just setting time to 0 42 // Do a quick play and pause to load the metadata and show the first frame 43 // This results in advancing past the loaded-data state, 44 // so we need to reset back to that, but only after the pause event fires 45 showFirstFrame() { 46 this.source.goToBeginning() 47 this.source.mediaElement.play().catch(() => {}) 48 this.source.mediaElement.pause() 49 setTimeout(() => { 50 this.controller.stateValue = 'loaded-data' 51 }, 100) // ensure this fires after pause 52 } 53 54 play() { 55 this.source.play() 56 } 57 58 pause() { 59 this.source.pause() 60 this.visualizer.stop() 61 } 62 63 goToBeginning() { 64 this.source.goToBeginning() 65 } 66 67 restartPlayback() { 68 this.source.goToBeginning() 69 this.source.play() 70 } 71 72 togglePlayback() { 73 if (this.controller.stateValue === 'playing') { 74 this.pause() 75 } else { 76 this.play() 77 } 78 } 79 80 // ---------- 81 // Volume 82 // ---------- 83 84 mute() { 85 this.source.mute() 86 this.controller.mutedValue = 'muted' 87 } 88 89 unmute() { 90 this.source.unmute() 91 this.controller.mutedValue = 'unmuted' 92 } 93 94}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.