@flighthq/media 0.1.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.
- package/dist/audioChannel.d.ts +16 -0
- package/dist/audioChannel.d.ts.map +1 -0
- package/dist/audioChannel.js +163 -0
- package/dist/audioChannel.js.map +1 -0
- package/dist/audioMixer.d.ts +18 -0
- package/dist/audioMixer.d.ts.map +1 -0
- package/dist/audioMixer.js +230 -0
- package/dist/audioMixer.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/videoChannel.d.ts +14 -0
- package/dist/videoChannel.d.ts.map +1 -0
- package/dist/videoChannel.js +128 -0
- package/dist/videoChannel.js.map +1 -0
- package/package.json +40 -0
- package/src/audioChannel.test.ts +207 -0
- package/src/audioMixer.test.ts +281 -0
- package/src/videoChannel.test.ts +200 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { createVideoResource } from '@flighthq/video';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getVideoChannelCurrentTime,
|
|
5
|
+
getVideoChannelDuration,
|
|
6
|
+
getVideoChannelHeight,
|
|
7
|
+
getVideoChannelWidth,
|
|
8
|
+
isVideoChannelPlaying,
|
|
9
|
+
pauseVideoChannel,
|
|
10
|
+
playVideoResource,
|
|
11
|
+
resumeVideoChannel,
|
|
12
|
+
setVideoChannelCurrentTime,
|
|
13
|
+
setVideoChannelGain,
|
|
14
|
+
setVideoChannelPlaybackRate,
|
|
15
|
+
stopVideoChannel,
|
|
16
|
+
} from './videoChannel';
|
|
17
|
+
|
|
18
|
+
describe('getVideoChannelCurrentTime', () => {
|
|
19
|
+
it('returns stored currentTime when not playing', () => {
|
|
20
|
+
const source = createVideoResource(createMockVideoElement());
|
|
21
|
+
const channel = playVideoResource(source, { currentTime: 500 });
|
|
22
|
+
expect(channel).not.toBeNull();
|
|
23
|
+
pauseVideoChannel(channel!);
|
|
24
|
+
expect(getVideoChannelCurrentTime(channel!)).toBe(500);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('getVideoChannelDuration', () => {
|
|
29
|
+
it('returns the channel length', () => {
|
|
30
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement(5)));
|
|
31
|
+
expect(channel).not.toBeNull();
|
|
32
|
+
expect(getVideoChannelDuration(channel!)).toBe(5000);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('getVideoChannelHeight', () => {
|
|
37
|
+
it('returns the element videoHeight', () => {
|
|
38
|
+
const element = createMockVideoElement(10, 480);
|
|
39
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
40
|
+
expect(channel).not.toBeNull();
|
|
41
|
+
expect(getVideoChannelHeight(channel!)).toBe(480);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('returns 0 when element is null', () => {
|
|
45
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()));
|
|
46
|
+
expect(channel).not.toBeNull();
|
|
47
|
+
channel!.source = { element: null };
|
|
48
|
+
expect(getVideoChannelHeight(channel!)).toBe(0);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('getVideoChannelWidth', () => {
|
|
53
|
+
it('returns the element videoWidth', () => {
|
|
54
|
+
const element = createMockVideoElement(10, 480, 640);
|
|
55
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
56
|
+
expect(channel).not.toBeNull();
|
|
57
|
+
expect(getVideoChannelWidth(channel!)).toBe(640);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('returns 0 when element is null', () => {
|
|
61
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()));
|
|
62
|
+
expect(channel).not.toBeNull();
|
|
63
|
+
channel!.source = { element: null };
|
|
64
|
+
expect(getVideoChannelWidth(channel!)).toBe(0);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('isVideoChannelPlaying', () => {
|
|
69
|
+
it('returns true while playing', () => {
|
|
70
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()));
|
|
71
|
+
expect(channel).not.toBeNull();
|
|
72
|
+
expect(isVideoChannelPlaying(channel!)).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('returns false when stopped', () => {
|
|
76
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()));
|
|
77
|
+
expect(channel).not.toBeNull();
|
|
78
|
+
stopVideoChannel(channel!);
|
|
79
|
+
expect(isVideoChannelPlaying(channel!)).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('pauseVideoChannel', () => {
|
|
84
|
+
it('marks the channel as paused and calls element.pause', () => {
|
|
85
|
+
const element = createMockVideoElement();
|
|
86
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
87
|
+
expect(channel).not.toBeNull();
|
|
88
|
+
pauseVideoChannel(channel!);
|
|
89
|
+
expect(channel!.state).toBe('paused');
|
|
90
|
+
expect(element.paused).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('playVideoResource', () => {
|
|
95
|
+
it('returns null when element is null', () => {
|
|
96
|
+
expect(playVideoResource(createVideoResource())).toBeNull();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('returns a playing channel with applied options', () => {
|
|
100
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()), { gain: 0.5 });
|
|
101
|
+
expect(channel).not.toBeNull();
|
|
102
|
+
expect(channel!.gain).toBe(0.5);
|
|
103
|
+
expect(channel!.state).toBe('playing');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('resumeVideoChannel', () => {
|
|
108
|
+
it('resumes a paused channel', () => {
|
|
109
|
+
const channel = playVideoResource(createVideoResource(createMockVideoElement()));
|
|
110
|
+
expect(channel).not.toBeNull();
|
|
111
|
+
pauseVideoChannel(channel!);
|
|
112
|
+
resumeVideoChannel(channel!);
|
|
113
|
+
expect(channel!.state).toBe('playing');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('setVideoChannelCurrentTime', () => {
|
|
118
|
+
it('clamps the value to channel length', () => {
|
|
119
|
+
const element = createMockVideoElement(1);
|
|
120
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
121
|
+
expect(channel).not.toBeNull();
|
|
122
|
+
expect(setVideoChannelCurrentTime(channel!, 9999)).toBe(1000);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('setVideoChannelGain', () => {
|
|
127
|
+
it('updates channel gain and element volume', () => {
|
|
128
|
+
const element = createMockVideoElement();
|
|
129
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
130
|
+
expect(channel).not.toBeNull();
|
|
131
|
+
expect(setVideoChannelGain(channel!, 0.3)).toBe(0.3);
|
|
132
|
+
expect(element.volume).toBe(0.3);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('setVideoChannelPlaybackRate', () => {
|
|
137
|
+
it('updates channel playback rate and element rate', () => {
|
|
138
|
+
const element = createMockVideoElement();
|
|
139
|
+
const channel = playVideoResource(createVideoResource(element));
|
|
140
|
+
expect(channel).not.toBeNull();
|
|
141
|
+
expect(setVideoChannelPlaybackRate(channel!, 2)).toBe(2);
|
|
142
|
+
expect(element.playbackRate).toBe(2);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('stopVideoChannel', () => {
|
|
147
|
+
it('stops playback and resets currentTime', () => {
|
|
148
|
+
const element = createMockVideoElement();
|
|
149
|
+
const channel = playVideoResource(createVideoResource(element), { currentTime: 400 });
|
|
150
|
+
expect(channel).not.toBeNull();
|
|
151
|
+
stopVideoChannel(channel!);
|
|
152
|
+
expect(channel!.currentTime).toBe(0);
|
|
153
|
+
expect(channel!.state).toBe('stopped');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
class MockVideoElement {
|
|
158
|
+
currentTime = 0;
|
|
159
|
+
duration: number;
|
|
160
|
+
loop = false;
|
|
161
|
+
paused = false;
|
|
162
|
+
playbackRate = 1;
|
|
163
|
+
videoHeight: number;
|
|
164
|
+
videoWidth: number;
|
|
165
|
+
volume = 1;
|
|
166
|
+
private _listeners = new Map<string, (() => void)[]>();
|
|
167
|
+
|
|
168
|
+
constructor(duration = 10, videoHeight = 0, videoWidth = 0) {
|
|
169
|
+
this.duration = duration;
|
|
170
|
+
this.videoHeight = videoHeight;
|
|
171
|
+
this.videoWidth = videoWidth;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
addEventListener(type: string, handler: () => void): void {
|
|
175
|
+
const list = this._listeners.get(type) ?? [];
|
|
176
|
+
list.push(handler);
|
|
177
|
+
this._listeners.set(type, list);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
removeEventListener(type: string, handler: () => void): void {
|
|
181
|
+
const list = this._listeners.get(type) ?? [];
|
|
182
|
+
this._listeners.set(
|
|
183
|
+
type,
|
|
184
|
+
list.filter((h) => h !== handler),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
pause(): void {
|
|
189
|
+
this.paused = true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
play(): Promise<void> {
|
|
193
|
+
this.paused = false;
|
|
194
|
+
return Promise.resolve();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function createMockVideoElement(duration = 10, videoHeight = 0, videoWidth = 0): HTMLVideoElement {
|
|
199
|
+
return new MockVideoElement(duration, videoHeight, videoWidth) as unknown as HTMLVideoElement;
|
|
200
|
+
}
|