@ldelia/react-media 0.2.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.storybook/main.js +25 -2
  2. package/README.md +1 -4
  3. package/config/env.js +104 -0
  4. package/config/getHttpsConfig.js +66 -0
  5. package/config/jest/babelTransform.js +29 -0
  6. package/config/jest/cssTransform.js +14 -0
  7. package/config/jest/fileTransform.js +40 -0
  8. package/config/modules.js +134 -0
  9. package/config/paths.js +77 -0
  10. package/config/webpack/persistentCache/createEnvironmentHash.js +9 -0
  11. package/config/webpack.config.js +755 -0
  12. package/config/webpackDevServer.config.js +127 -0
  13. package/dist/stories/timeline.stories.d.ts +6 -6
  14. package/package.json +127 -18
  15. package/scripts/build.js +217 -0
  16. package/scripts/start.js +154 -0
  17. package/scripts/test.js +52 -0
  18. package/src/components/__tests__/timeline/timeline.test.js +22 -0
  19. package/src/components/index.js +1 -0
  20. package/src/components/reproduction-widget/README.md +27 -0
  21. package/src/components/reproduction-widget/ReproductionWidget.js +29 -0
  22. package/src/components/reproduction-widget/ReproductionWidget.tsx +68 -0
  23. package/src/components/reproduction-widget/index.js +1 -0
  24. package/src/components/reproduction-widget/index.tsx +1 -0
  25. package/src/components/reproduction-widget/inner-players/PlayAlongInnerPlayer.js +5 -0
  26. package/src/components/reproduction-widget/inner-players/PlayAlongInnerPlayer.tsx +10 -0
  27. package/src/components/reproduction-widget/inner-players/YouTubeInnerPlayer.js +21 -0
  28. package/src/components/reproduction-widget/inner-players/YouTubeInnerPlayer.tsx +36 -0
  29. package/src/components/reproduction-widget/models/Player/PlayAlongPlayer.js +97 -0
  30. package/src/components/reproduction-widget/models/Player/PlayAlongPlayer.ts +129 -0
  31. package/src/components/reproduction-widget/models/Player/PlayerEvents.js +4 -0
  32. package/src/components/reproduction-widget/models/Player/PlayerEvents.ts +4 -0
  33. package/src/components/reproduction-widget/models/Player/YouTubePlayer.js +126 -0
  34. package/src/components/reproduction-widget/models/Player/YouTubePlayer.ts +171 -0
  35. package/src/components/reproduction-widget/models/Reproduction.js +214 -0
  36. package/src/components/reproduction-widget/models/Reproduction.ts +272 -0
  37. package/src/components/reproduction-widget/models/ReproductionBuilder.js +51 -0
  38. package/src/components/reproduction-widget/models/ReproductionBuilder.ts +70 -0
  39. package/{dist/components/timeline → src/components/timeline/RangeSelectorCanvas}/RangeSelectorCanvas.js +16 -22
  40. package/src/components/timeline/Timeline.js +77 -0
  41. package/src/components/timeline/TimelineCanvas/TickTime.js +26 -0
  42. package/src/components/timeline/TimelineCanvas/TickTimeCollectionDisplay.js +19 -0
  43. package/src/components/timeline/TimelineCanvas/TimelineCanvas.js +44 -0
  44. package/src/components/timeline/TimelineCanvas/drawTimeBlocksOnCanvas.js +28 -0
  45. package/src/components/timeline/TimelineValue/TimelineValue.js +50 -0
  46. package/src/components/timeline/ZoomContext/ZoomContext.js +2 -0
  47. package/src/components/timeline/constants.js +13 -0
  48. package/src/components/timeline/index.js +1 -0
  49. package/src/components/timeline/utils/utils.js +28 -0
  50. package/src/index.js +1 -0
  51. package/src/react-app-env.d.ts +71 -1
  52. package/src/react-docgen-types.d.ts +37 -0
  53. package/src/setupTests.js +5 -0
  54. package/src/stories/reproduction-widget.stories.js +16 -0
  55. package/src/stories/reproduction-widget.stories.tsx +23 -0
  56. package/src/stories/timeline.stories.js +54 -0
  57. package/storybook-static/favicon.svg +1 -0
  58. package/storybook-static/index.html +173 -0
  59. package/storybook-static/index.json +1 -0
  60. package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  61. package/storybook-static/nunito-sans-bold.woff2 +0 -0
  62. package/storybook-static/nunito-sans-italic.woff2 +0 -0
  63. package/storybook-static/nunito-sans-regular.woff2 +0 -0
  64. package/storybook-static/project.json +1 -0
  65. package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
  66. package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js.LEGAL.txt +0 -0
  67. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +12 -0
  68. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js.LEGAL.txt +0 -0
  69. package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js +412 -0
  70. package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js.LEGAL.txt +0 -0
  71. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +3 -0
  72. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js.LEGAL.txt +0 -0
  73. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +3 -0
  74. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js.LEGAL.txt +0 -0
  75. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +3 -0
  76. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js.LEGAL.txt +0 -0
  77. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +3 -0
  78. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js.LEGAL.txt +0 -0
  79. package/storybook-static/sb-addons/links-1/manager-bundle.js +3 -0
  80. package/storybook-static/sb-addons/links-1/manager-bundle.js.LEGAL.txt +0 -0
  81. package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  82. package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js.LEGAL.txt +0 -0
  83. package/storybook-static/sb-common-assets/favicon.svg +1 -0
  84. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  85. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  86. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  87. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  88. package/storybook-static/sb-manager/globals-module-info.js +995 -0
  89. package/storybook-static/sb-manager/globals-runtime.js +53527 -0
  90. package/storybook-static/sb-manager/globals.js +48 -0
  91. package/storybook-static/sb-manager/runtime.js +11885 -0
  92. package/storybook-static/sb-preview/globals.js +33 -0
  93. package/storybook-static/sb-preview/runtime.js +9483 -0
  94. package/tsconfig.json +8 -7
  95. package/.storybook/main.ts +0 -18
  96. package/.storybook/preview.ts +0 -14
  97. package/dist/components/timeline/RangeSelectorCanvas.d.ts +0 -8
  98. package/dist/components/timeline/TickTime.d.ts +0 -7
  99. package/dist/components/timeline/TickTime.js +0 -31
  100. package/dist/components/timeline/TickTimeCollectionDisplay.d.ts +0 -6
  101. package/dist/components/timeline/TickTimeCollectionDisplay.js +0 -24
  102. package/dist/components/timeline/VaLueLineCanvas.d.ts +0 -7
  103. package/dist/components/timeline/VaLueLineCanvas.js +0 -111
  104. package/dist/reportWebVitals.d.ts +0 -3
  105. package/dist/reportWebVitals.js +0 -37
  106. package/src/reportWebVitals.ts +0 -15
@@ -0,0 +1,126 @@
1
+ import { PlayAlongPlayer } from './PlayAlongPlayer';
2
+ import { PLAYER_EVENTS } from './PlayerEvents';
3
+ // https://developers.google.com/youtube/iframe_api_reference
4
+ var INNER_YOUTUBE_PLAYER_EVENTS;
5
+ (function (INNER_YOUTUBE_PLAYER_EVENTS) {
6
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_UNSTARTED"] = -1] = "VIDEO_UNSTARTED";
7
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_ENDED"] = 0] = "VIDEO_ENDED";
8
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_PLAYING"] = 1] = "VIDEO_PLAYING";
9
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_PAUSED"] = 2] = "VIDEO_PAUSED";
10
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_BUFFERING"] = 3] = "VIDEO_BUFFERING";
11
+ INNER_YOUTUBE_PLAYER_EVENTS[INNER_YOUTUBE_PLAYER_EVENTS["VIDEO_CUED"] = 5] = "VIDEO_CUED";
12
+ })(INNER_YOUTUBE_PLAYER_EVENTS || (INNER_YOUTUBE_PLAYER_EVENTS = {}));
13
+ const dispatchOnReadyHandlers = Symbol();
14
+ const dispatchOnFinishHandlers = Symbol();
15
+ export class YouTubePlayer {
16
+ static get EVENTS() {
17
+ return PLAYER_EVENTS;
18
+ }
19
+ constructor(innerPlayer) {
20
+ this[dispatchOnFinishHandlers] = [];
21
+ this[dispatchOnReadyHandlers] = [];
22
+ this.currentTime = 0;
23
+ this.isRunning = false;
24
+ this.setInnerPlayer(innerPlayer);
25
+ }
26
+ setInnerPlayer(innerPlayer) {
27
+ this.innerPlayer = innerPlayer;
28
+ this.dispatch(YouTubePlayer.EVENTS.READY);
29
+ // this is necessary for avoiding the state video cued.
30
+ // When a video is in this state, when user seek to X, the song is played
31
+ this.innerPlayer.playVideo();
32
+ this.innerPlayer.pauseVideo();
33
+ this.innerPlayer.addEventListener('onStateChange', (videoState) => {
34
+ switch (videoState.data) {
35
+ case INNER_YOUTUBE_PLAYER_EVENTS.VIDEO_ENDED:
36
+ this.dispatch(YouTubePlayer.EVENTS.FINISH);
37
+ this.isRunning = false;
38
+ this.currentTime = 0;
39
+ break;
40
+ default:
41
+ break;
42
+ }
43
+ });
44
+ }
45
+ getInnerPlayer() {
46
+ return this.innerPlayer;
47
+ }
48
+ play() {
49
+ const videoPlayer = this.getInnerPlayer();
50
+ videoPlayer.playVideo();
51
+ this.isRunning = true;
52
+ }
53
+ pause() {
54
+ this.isRunning = false;
55
+ this.getInnerPlayer().pauseVideo();
56
+ this.currentTime = this.getInnerPlayer().getCurrentTime();
57
+ }
58
+ stop() {
59
+ this.isRunning = false;
60
+ /**
61
+ * Hay un issue al llamar a getDuration del video luego de reanudar una canción pausada (devuelve siempre 0)
62
+ * Para evitar que se pierda la información y tener que cargarla de nuevo, se simula un stop pausando y llevando al comienzo
63
+ * videoPlayer.stopVideo();
64
+ */
65
+ this.getInnerPlayer().pauseVideo();
66
+ this.seekTo(0);
67
+ }
68
+ seekTo(seconds) {
69
+ const videoPlayer = this.getInnerPlayer();
70
+ this.currentTime = seconds;
71
+ videoPlayer.seekTo(this.currentTime);
72
+ if (this.isRunning) {
73
+ this.play();
74
+ }
75
+ }
76
+ getCurrentTime() {
77
+ return this.isRunning
78
+ ? this.getInnerPlayer().getCurrentTime()
79
+ : this.currentTime;
80
+ }
81
+ getDuration() {
82
+ if (this.isAvailable()) {
83
+ return this.getInnerPlayer().getDuration();
84
+ }
85
+ }
86
+ getAvailablePlaybackRates() {
87
+ return this.getInnerPlayer().getAvailablePlaybackRates();
88
+ }
89
+ setPlaybackRate(playbackRate) {
90
+ if (!this.getAvailablePlaybackRates().includes(playbackRate)) {
91
+ throw new Error(`The PlayAlongPlayer doesn't support a playbackRate with value ${playbackRate}`);
92
+ }
93
+ this.getInnerPlayer().setPlaybackRate(playbackRate);
94
+ }
95
+ isAvailable() {
96
+ return this.getInnerPlayer() !== null;
97
+ }
98
+ on(eventName, handler) {
99
+ switch (eventName) {
100
+ case PlayAlongPlayer.EVENTS.READY:
101
+ return this[dispatchOnReadyHandlers].push(handler);
102
+ case PlayAlongPlayer.EVENTS.FINISH:
103
+ return this[dispatchOnFinishHandlers].push(handler);
104
+ default:
105
+ break;
106
+ }
107
+ }
108
+ dispatch(eventName) {
109
+ let handler, i, len;
110
+ let ref = [];
111
+ switch (eventName) {
112
+ case YouTubePlayer.EVENTS.READY:
113
+ ref = this[dispatchOnReadyHandlers];
114
+ break;
115
+ case YouTubePlayer.EVENTS.FINISH:
116
+ ref = this[dispatchOnFinishHandlers];
117
+ break;
118
+ default:
119
+ break;
120
+ }
121
+ for (i = 0, len = ref.length; i < len; i++) {
122
+ handler = ref[i];
123
+ setTimeout(handler, 0);
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,171 @@
1
+ import { YouTubePlayer as InnerYouTubePlayer } from 'react-youtube';
2
+ import { PlayAlongPlayer } from './PlayAlongPlayer';
3
+ import { PLAYER_EVENTS } from './PlayerEvents';
4
+
5
+ // https://developers.google.com/youtube/iframe_api_reference
6
+ enum INNER_YOUTUBE_PLAYER_EVENTS {
7
+ VIDEO_UNSTARTED = -1,
8
+ VIDEO_ENDED = 0,
9
+ VIDEO_PLAYING = 1,
10
+ VIDEO_PAUSED = 2,
11
+ VIDEO_BUFFERING = 3,
12
+ VIDEO_CUED = 5,
13
+ }
14
+
15
+ interface INNER_YOUTUBE_PLAYER_StateChangeEvent {
16
+ data: INNER_YOUTUBE_PLAYER_EVENTS;
17
+ }
18
+
19
+ const dispatchOnReadyHandlers = Symbol();
20
+ const dispatchOnFinishHandlers = Symbol();
21
+
22
+ export class YouTubePlayer {
23
+ private currentTime: number;
24
+ private isRunning: boolean;
25
+ private innerPlayer: InnerYouTubePlayer | number;
26
+ private [dispatchOnReadyHandlers]: (() => void)[];
27
+ private [dispatchOnFinishHandlers]: (() => void)[];
28
+
29
+ static get EVENTS() {
30
+ return PLAYER_EVENTS;
31
+ }
32
+
33
+ constructor(innerPlayer: InnerYouTubePlayer) {
34
+ this[dispatchOnFinishHandlers] = [];
35
+ this[dispatchOnReadyHandlers] = [];
36
+
37
+ this.currentTime = 0;
38
+ this.isRunning = false;
39
+
40
+ this.setInnerPlayer(innerPlayer);
41
+ }
42
+
43
+ private setInnerPlayer(innerPlayer: InnerYouTubePlayer) {
44
+ this.innerPlayer = innerPlayer;
45
+ this.dispatch(YouTubePlayer.EVENTS.READY);
46
+
47
+ // this is necessary for avoiding the state video cued.
48
+ // When a video is in this state, when user seek to X, the song is played
49
+ this.innerPlayer.playVideo();
50
+ this.innerPlayer.pauseVideo();
51
+
52
+ this.innerPlayer.addEventListener(
53
+ 'onStateChange',
54
+ (videoState: INNER_YOUTUBE_PLAYER_StateChangeEvent) => {
55
+ switch (videoState.data) {
56
+ case INNER_YOUTUBE_PLAYER_EVENTS.VIDEO_ENDED:
57
+ this.dispatch(YouTubePlayer.EVENTS.FINISH);
58
+ this.isRunning = false;
59
+ this.currentTime = 0;
60
+ break;
61
+ default:
62
+ break;
63
+ }
64
+ }
65
+ );
66
+ }
67
+
68
+ getInnerPlayer() {
69
+ return this.innerPlayer;
70
+ }
71
+
72
+ play() {
73
+ const videoPlayer = this.getInnerPlayer();
74
+ videoPlayer.playVideo();
75
+
76
+ this.isRunning = true;
77
+ }
78
+
79
+ pause() {
80
+ this.isRunning = false;
81
+
82
+ this.getInnerPlayer().pauseVideo();
83
+
84
+ this.currentTime = this.getInnerPlayer().getCurrentTime();
85
+ }
86
+
87
+ stop() {
88
+ this.isRunning = false;
89
+
90
+ /**
91
+ * Hay un issue al llamar a getDuration del video luego de reanudar una canción pausada (devuelve siempre 0)
92
+ * Para evitar que se pierda la información y tener que cargarla de nuevo, se simula un stop pausando y llevando al comienzo
93
+ * videoPlayer.stopVideo();
94
+ */
95
+ this.getInnerPlayer().pauseVideo();
96
+
97
+ this.seekTo(0);
98
+ }
99
+
100
+ seekTo(seconds: number) {
101
+ const videoPlayer = this.getInnerPlayer();
102
+ this.currentTime = seconds;
103
+
104
+ videoPlayer.seekTo(this.currentTime);
105
+
106
+ if (this.isRunning) {
107
+ this.play();
108
+ }
109
+ }
110
+
111
+ getCurrentTime() {
112
+ return this.isRunning
113
+ ? this.getInnerPlayer().getCurrentTime()
114
+ : this.currentTime;
115
+ }
116
+
117
+ getDuration() {
118
+ if (this.isAvailable()) {
119
+ return this.getInnerPlayer().getDuration();
120
+ }
121
+ }
122
+
123
+ getAvailablePlaybackRates() {
124
+ return this.getInnerPlayer().getAvailablePlaybackRates();
125
+ }
126
+
127
+ setPlaybackRate(playbackRate: number) {
128
+ if (!this.getAvailablePlaybackRates().includes(playbackRate)) {
129
+ throw new Error(
130
+ `The PlayAlongPlayer doesn't support a playbackRate with value ${playbackRate}`
131
+ );
132
+ }
133
+ this.getInnerPlayer().setPlaybackRate(playbackRate);
134
+ }
135
+
136
+ isAvailable() {
137
+ return this.getInnerPlayer() !== null;
138
+ }
139
+
140
+ on(eventName: keyof typeof PlayAlongPlayer.EVENTS, handler: () => void) {
141
+ switch (eventName) {
142
+ case PlayAlongPlayer.EVENTS.READY:
143
+ return this[dispatchOnReadyHandlers].push(handler);
144
+ case PlayAlongPlayer.EVENTS.FINISH:
145
+ return this[dispatchOnFinishHandlers].push(handler);
146
+ default:
147
+ break;
148
+ }
149
+ }
150
+
151
+ dispatch(eventName: keyof typeof PlayAlongPlayer.EVENTS) {
152
+ let handler, i, len;
153
+ let ref: (() => void)[] = [];
154
+
155
+ switch (eventName) {
156
+ case YouTubePlayer.EVENTS.READY:
157
+ ref = this[dispatchOnReadyHandlers];
158
+ break;
159
+ case YouTubePlayer.EVENTS.FINISH:
160
+ ref = this[dispatchOnFinishHandlers];
161
+ break;
162
+ default:
163
+ break;
164
+ }
165
+
166
+ for (i = 0, len = ref.length; i < len; i++) {
167
+ handler = ref[i];
168
+ setTimeout(handler, 0);
169
+ }
170
+ }
171
+ }
@@ -0,0 +1,214 @@
1
+ import { PLAYER_EVENTS } from './Player/PlayerEvents';
2
+ import { ReproductionBuilder } from './ReproductionBuilder';
3
+ const STATES = {
4
+ STOPPED: 0,
5
+ COUNTING_IN: 1,
6
+ PLAYING: 2,
7
+ PAUSED: 3,
8
+ };
9
+ const EVENTS = {
10
+ READY: 'READY',
11
+ START: 'START',
12
+ COUNTING_IN: 'COUNTING_IN',
13
+ PLAY: 'PLAY',
14
+ PLAYING: 'PLAYING',
15
+ PAUSED: 'PAUSED',
16
+ FINISH: 'FINISH',
17
+ };
18
+ const dispatchOnReadyHandlers = Symbol();
19
+ const dispatchOnSongStartHandlers = Symbol();
20
+ const dispatchOnCountingInHandlers = Symbol();
21
+ const dispatchOnPlayHandlers = Symbol();
22
+ const dispatchOnPlayingHandlers = Symbol();
23
+ const dispatchOnPausedHandlers = Symbol();
24
+ const dispatchOnFinishHandlers = Symbol();
25
+ export class Reproduction {
26
+ static get EVENTS() {
27
+ return EVENTS;
28
+ }
29
+ static get STATES() {
30
+ return STATES;
31
+ }
32
+ constructor(player, requiresCountingIn, songTempo) {
33
+ this[dispatchOnReadyHandlers] = [];
34
+ this[dispatchOnSongStartHandlers] = [];
35
+ this[dispatchOnCountingInHandlers] = [];
36
+ this[dispatchOnPlayHandlers] = [];
37
+ this[dispatchOnPlayingHandlers] = [];
38
+ this[dispatchOnPausedHandlers] = [];
39
+ this[dispatchOnFinishHandlers] = [];
40
+ this.songTempo = songTempo;
41
+ this.player = player;
42
+ this.ready = false;
43
+ this.state = Reproduction.STATES.STOPPED;
44
+ this.interval = null;
45
+ this.requiresCountingIn = requiresCountingIn;
46
+ this.countingInCounter = 0;
47
+ this.player.on(PLAYER_EVENTS.READY, () => {
48
+ this.ready = true;
49
+ this.dispatch(Reproduction.EVENTS.READY);
50
+ });
51
+ this.player.on(PLAYER_EVENTS.FINISH, () => {
52
+ this.state = Reproduction.STATES.STOPPED;
53
+ clearInterval(this.interval);
54
+ this.dispatch(Reproduction.EVENTS.FINISH);
55
+ });
56
+ }
57
+ on(eventName, handler) {
58
+ switch (eventName) {
59
+ case Reproduction.EVENTS.READY:
60
+ return this[dispatchOnReadyHandlers].push(handler);
61
+ case Reproduction.EVENTS.START:
62
+ return this[dispatchOnSongStartHandlers].push(handler);
63
+ case Reproduction.EVENTS.COUNTING_IN:
64
+ return this[dispatchOnCountingInHandlers].push(handler);
65
+ case Reproduction.EVENTS.PLAY:
66
+ return this[dispatchOnPlayHandlers].push(handler);
67
+ case Reproduction.EVENTS.PLAYING:
68
+ return this[dispatchOnPlayingHandlers].push(handler);
69
+ case Reproduction.EVENTS.PAUSED:
70
+ return this[dispatchOnPausedHandlers].push(handler);
71
+ case Reproduction.EVENTS.FINISH:
72
+ return this[dispatchOnFinishHandlers].push(handler);
73
+ default:
74
+ break;
75
+ }
76
+ }
77
+ dispatch(eventName) {
78
+ let handler, i, len;
79
+ let ref = [];
80
+ switch (eventName) {
81
+ case Reproduction.EVENTS.READY:
82
+ ref = this[dispatchOnReadyHandlers];
83
+ break;
84
+ case Reproduction.EVENTS.START:
85
+ ref = this[dispatchOnSongStartHandlers];
86
+ break;
87
+ case Reproduction.EVENTS.COUNTING_IN:
88
+ ref = this[dispatchOnCountingInHandlers];
89
+ break;
90
+ case Reproduction.EVENTS.PLAY:
91
+ ref = this[dispatchOnPlayHandlers];
92
+ break;
93
+ case Reproduction.EVENTS.PLAYING:
94
+ ref = this[dispatchOnPlayingHandlers];
95
+ break;
96
+ case Reproduction.EVENTS.PAUSED:
97
+ ref = this[dispatchOnPausedHandlers];
98
+ break;
99
+ case Reproduction.EVENTS.FINISH:
100
+ ref = this[dispatchOnFinishHandlers];
101
+ break;
102
+ default:
103
+ break;
104
+ }
105
+ for (i = 0, len = ref.length; i < len; i++) {
106
+ handler = ref[i];
107
+ handler();
108
+ // setTimeout(handler, 0);
109
+ }
110
+ }
111
+ countIn(timeout, limit) {
112
+ // the initial count starts instantly, no waiting
113
+ this.countingInCounter++;
114
+ this.dispatch(Reproduction.EVENTS.COUNTING_IN);
115
+ const interval = setInterval(() => {
116
+ this.countingInCounter++;
117
+ if (this.countingInCounter === limit) {
118
+ clearInterval(interval);
119
+ this.countingInCounter = 0;
120
+ if (limit !== 5) {
121
+ this.countIn(this.getBPMInterval(), 5);
122
+ }
123
+ else {
124
+ this.play();
125
+ }
126
+ }
127
+ else {
128
+ this.dispatch(Reproduction.EVENTS.COUNTING_IN);
129
+ }
130
+ }, timeout);
131
+ }
132
+ start() {
133
+ if (this.state === Reproduction.STATES.STOPPED) {
134
+ this.dispatch(Reproduction.EVENTS.START);
135
+ }
136
+ if (this.requiresCountingIn && this.getCurrentTime() === 0) {
137
+ this.state = Reproduction.STATES.COUNTING_IN;
138
+ this.countIn(this.getBPMInterval() * 2, 3);
139
+ }
140
+ else {
141
+ this.play();
142
+ }
143
+ }
144
+ play() {
145
+ this.state = Reproduction.STATES.PLAYING;
146
+ this.dispatch(Reproduction.EVENTS.PLAY);
147
+ this.player.play();
148
+ const intervalTimeout = 200;
149
+ this.interval = setInterval(() => {
150
+ if (this.isPlaying()) {
151
+ this.dispatch(Reproduction.EVENTS.PLAYING);
152
+ }
153
+ }, intervalTimeout);
154
+ }
155
+ pause() {
156
+ this.state = Reproduction.STATES.PAUSED;
157
+ this.player.pause();
158
+ clearInterval(this.interval);
159
+ this.dispatch(Reproduction.EVENTS.PAUSED);
160
+ }
161
+ stop() {
162
+ this.state = Reproduction.STATES.STOPPED;
163
+ this.player.stop();
164
+ clearInterval(this.interval);
165
+ this.dispatch(Reproduction.EVENTS.FINISH);
166
+ }
167
+ isReady() {
168
+ // It's necessary to avoid play the reproduction-widget when the player is not ready
169
+ return this.ready;
170
+ }
171
+ isPlaying() {
172
+ return this.state === Reproduction.STATES.PLAYING;
173
+ }
174
+ isStopped() {
175
+ return this.state === Reproduction.STATES.STOPPED;
176
+ }
177
+ isPaused() {
178
+ return this.state === Reproduction.STATES.PAUSED;
179
+ }
180
+ isCountingIn() {
181
+ return this.state === Reproduction.STATES.COUNTING_IN;
182
+ }
183
+ getPlayer() {
184
+ return this.player;
185
+ }
186
+ getTempo() {
187
+ return this.songTempo;
188
+ }
189
+ getCurrentTime() {
190
+ // in seconds with milliseconds.
191
+ return this.player.getCurrentTime();
192
+ }
193
+ getDuration() {
194
+ return this.player.getDuration();
195
+ }
196
+ seekTo(seconds) {
197
+ this.player.seekTo(seconds);
198
+ }
199
+ getAvailablePlaybackRates() {
200
+ return this.player.getAvailablePlaybackRates();
201
+ }
202
+ setPlaybackRate(playbackRate) {
203
+ this.player.setPlaybackRate(playbackRate);
204
+ }
205
+ isAvailable() {
206
+ return this.player.isAvailable();
207
+ }
208
+ getBPMInterval() {
209
+ return 60000 / this.getTempo();
210
+ }
211
+ static newBuilder() {
212
+ return new ReproductionBuilder();
213
+ }
214
+ }