source: main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/js/AudioPlaybackModule.js@ 35502

Last change on this file since 35502 was 35502, checked in by cstephen, 3 years ago

Use requestAnimationFrame to update audio time

File size: 3.9 KB
Line 
1/**
2 * @file Provides an interface for playing transcription audio.
3 * @author Carl Stephens
4 * @module
5 */
6
7class LoadedAudio {
8 /**
9 * Initialises a new instance of the {@link LoadedAudio} class.
10 * @param {String | null} id The ID of the transcription for which this audio belongs to.
11 * @param {String | null} url The audio object URL.
12 */
13 constructor(id, url) {
14 /** @type {String | null} The ID of the transcription for which this audio belongs to. */
15 this.id = id;
16
17 /** @type {String | null} The audio object URL. */
18 this.url = url;
19 }
20}
21
22/**
23 * Polls an audio element's current time and updates the vuex store accordingly.
24 * @param {Audio} audioElement The audio element.
25 * @param {*} store The vuex store to update.
26 */
27function pollAudioTime(audioElement, store) {
28 var lastTime = 0;
29
30 (function poll() {
31 if (audioElement.currentTime !== lastTime) {
32 lastTime = audioElement.currentTime;
33 store.commit("playbackStateSetTime", { id: store.state.playbackState.id, time: lastTime });
34 }
35
36 // setTimeout(poll, 33); // Slightly more than 30hz
37 requestAnimationFrame(poll);
38 })();
39}
40
41/**
42 * Loads an audio file.
43 * @param {Audio} player The audio player.
44 * @param {TranscriptionViewModel} transcription The name of the requested audio file.
45 * @param {LoadedAudio} current The currently loaded audio.
46 * @returns {LoadedAudio} If a new audio file was loaded, a new audio tracking object, else the current one.
47 */
48function loadAudio(player, transcription, current) {
49 // TODO: Need to profile on some larger tracks; this may not be worth it? Better to cache a URL object instead?
50 if (current.url !== null) {
51 URL.revokeObjectURL(current.url);
52 }
53
54 const urlObject = URL.createObjectURL(transcription.file);
55 player.src = urlObject;
56 player.load();
57
58 return new LoadedAudio(transcription.id, urlObject);
59}
60
61export default class AudioPlayback {
62 /**
63 * Initialises the {@link AudioPlayback} class.
64 * @param {*} store The vuex store to update.
65 */
66 static initialise(store) {
67 /** @type The vuex store. */
68 this.store = store;
69
70 this.player = new Audio();
71 this.loadedAudio = new LoadedAudio(null, null);
72
73 pollAudioTime(this.player, store);
74
75 this.player.addEventListener("ended", function() {
76 store.commit("playbackStateSetIsPlaying", false);
77 });
78 }
79
80 /**
81 * Plays a transcription's audio file.
82 * @param {String} id The ID of the transcription to play audio for.
83 * @param {Number} startTime The time into the audio at which to start playing. Leave negative to resume playback if paused.
84 */
85 static async play(id, startTime = -1) {
86 const playbackTimes = this.store.state.playbackState.playbackTimes;
87
88 let playbackTime = startTime;
89 if (playbackTimes.has(id) && startTime < 0) {
90 playbackTime = playbackTimes.get(id);
91 }
92
93 if (this.loadedAudio.id !== id) {
94 this.loadedAudio = loadAudio(this.player, this.store.state.rawTranscriptions.get(id), this.loadedAudio);
95
96 this.store.commit("playbackStateSetID", id);
97 }
98
99 this.player.currentTime = playbackTime;
100 await this.player.play();
101
102 this.store.commit("playbackStateSetLength", { id: id, time: this.player.duration });
103 this.store.commit("playbackStateSetIsPlaying", true);
104 }
105
106 /**
107 * Sets the current time of the audio player.
108 * @param {Number} time The time to scrub to.
109 * @param {Boolean} fromCurrent Indicates if the time is an offset.
110 */
111 static scrub(time, fromCurrent) {
112 const newTime = fromCurrent ? this.player.currentTime + time : time;
113 this.player.currentTime = newTime;
114 }
115
116 /**
117 * Pauses playback.
118 */
119 static pause() {
120 this.player.pause();
121 this.store.commit("playbackStateSetIsPlaying", false);
122 }
123}
Note: See TracBrowser for help on using the repository browser.