Skip to content

Commit bd4945d

Browse files
authored
Merge pull request #7 from samhirtarif/add_support_for_native_props
Add support for native props
2 parents ba9344d + 3cc1e69 commit bd4945d

File tree

5 files changed

+169
-34
lines changed

5 files changed

+169
-34
lines changed

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,28 @@ const Player = () => {
4646
}
4747

4848
```
49+
## Audio element native props
50+
| Props | Description | Default | Optional |
51+
| :------------ |:--------------- |:--------------- | :--------------- |
52+
| **`src`** | The address or URL of the a audio resource that is to be considered | N/A | No |
53+
| **`volume`** | Initial volume level for the audio, minimum being `0`, maximum being `1` | `0.75` | Yes |
54+
| **`loop`** | Sets a flag to specify whether playback should restart after it completes | `false` | Yes |
55+
| **`muted`** | Sets a flag that indicates whether the audio is muted | `false` | Yes |
56+
| **`autoplay`** | Sets a value that indicates whether to start playing the media automatically | `false` | Yes |
57+
| **`crossOrigin`** | The CORS setting for this media element. [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/crossOrigin) | `null` | Yes |
58+
| **`autoplay`** | Sets a value indicating what data should be preloaded, if any. Allowed values `""`, `"none"`, `"metadata"`, `"auto"` | `""` | Yes |
59+
| **`playbackRate`** | Sets the rate at which media is being played back | `1.0` | Yes |
60+
---
61+
<br>
4962

63+
## Audio element events
64+
#### `AudioPlayer` supports all the events for `HTMLMediaElement` ([MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement#events)). All of the events listed in the MDN docs can be passed as a prop to the `AudioPlayer`
65+
---
66+
<br>
67+
68+
## Audio player props
5069
| Props | Description | Default | Optional |
5170
| :------------ |:--------------- |:--------------- | :--------------- |
52-
| **`src`** | Source for the audio file that needs to be played | N/A | No |
5371
| **`minimal`** | Displays a minimal version of the audio player, with only the play/pause button, track bar and timestamp | `false` | Yes |
5472
| **`width`** | Width of the audio player | N/A | No |
5573
| **`barWidth`** | Width of each individual bar in the visualization | `2` | Yes |
@@ -61,11 +79,10 @@ const Player = () => {
6179
| **`barPlayedColor`** | Color for the bars that have been played | `"rgb(160, 198, 255)""` | Yes |
6280
| **`allowSkip`** | Represents whether the skip forward/backward options should be displayed | `true` | Yes |
6381
| **`skipDuration`** | The number of seconds to skip forward/backward | `5` | Yes |
64-
| **`initialVolume`** | Initial volume for the audio, minimum being `0`, maximum being `1` | `0.75` | Yes |
65-
| **`loop`** | Setting this to `true` will keep playing the audio in a loop | `false` | Yes |
6682
| **`showLoopOption`** | Represents whether to show the loop options | `true` | Yes |
6783
| **`showVolumeControl`** | Represents whether the volume control should be shown | `true` | Yes |
6884
| **`seekBarColor`** | Color for the audio seek bar | `rgba(140, 140, 140)` | Yes |
6985
| **`volumeControlColor`** | Color for the volumn control | `rgba(140, 140, 140)` | Yes |
7086
| **`hideSeekBar`** | Hides the seek bar if set to `true`, the audio will still be seekable | `false` | Yes |
7187
| **`hideSeekKnobWhenPlaying`** | Hides the seek knob when audio is playing if set to `true` | `false` | Yes |
88+

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
{
22
"name": "react-audio-player-component",
33
"private": false,
4-
"version": "1.0.1",
4+
"version": "1.1.0",
55
"license": "MIT",
66
"author": "",
77
"repository": {
88
"type": "git",
99
"url": "https://github.com/samhirtarif/react-audio-player.git"
1010
},
1111
"keywords": [
12+
"react",
13+
"reactjs",
14+
"react-audio-player",
15+
"react-audio-playback",
16+
"react-voice-player",
17+
"react-voice-playback",
18+
"react-audio-player-component",
19+
"react audio player",
20+
"react audio playback",
21+
"react voice player",
22+
"react voice playback",
1223
"audio",
1324
"voice",
1425
"player",
1526
"audio player",
1627
"audio playback",
1728
"voice player",
18-
"voice playback"
29+
"voice playback",
30+
"media",
31+
"media-player",
32+
"media player"
1933
],
2034
"files": [
2135
"dist"
@@ -34,13 +48,14 @@
3448
"build": "tsc && vite build",
3549
"preview": "vite preview",
3650
"test": "vitest test.tsx",
51+
"tf": "vitest",
3752
"test:browser": "karma start",
3853
"coverage": "vitest run --coverage",
3954
"lint": "eslint src/**/*.ts{,x}",
4055
"lint:fix": "npm run lint -- --fix"
4156
},
4257
"dependencies": {
43-
"react-audio-visualize": "^1.0.0"
58+
"react-audio-visualize": "^1.1.0"
4459
},
4560
"devDependencies": {
4661
"@testing-library/dom": "^9.3.0",

src/components/AudioPlayer.tsx

Lines changed: 123 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,67 @@ import repeatSVG from "../icons/repeat.svg";
1010
import repeatOneSVG from "../icons/repeat-one.svg";
1111
import Timer from "./Timer";
1212

13-
interface AudioPlayerProps {
13+
interface AudioElementNativeProps {
1414
/**
15-
* Source for the audio file that needs to be played
15+
* The address or URL of the a audio resource that is to be considered.
1616
*/
1717
src: string;
18+
/**
19+
* Sets a flag to specify whether playback should restart after it completes. Defaults to `false`
20+
*/
21+
loop?: boolean;
22+
/**
23+
* Initial volume level for the audio, minimum being `0`, maximum being `1`. Defaults to `0.75`
24+
*/
25+
volume?: number;
26+
/**
27+
* Sets a flag that indicates whether the audio is muted. Defaults to `false`
28+
*/
29+
muted?: boolean;
30+
/**
31+
* Sets a value that indicates whether to start playing the media automatically. Defaults to `false`
32+
*/
33+
autoplay?: boolean;
34+
/**
35+
* The CORS setting for this media element. {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/crossOrigin MDN Reference}. Defaults to `null`
36+
*/
37+
crossOrigin?: string;
38+
/**
39+
* Sets a value indicating what data should be preloaded, if any. Defaults to empty string
40+
*/
41+
preload?: "" | "none" | "metadata" | "auto";
42+
/**
43+
* Sets the rate at which media is being played back. Defaults to `1.0`
44+
*/
45+
playbackRate?: number;
46+
}
47+
48+
interface AudioElementEventProps {
49+
onabort?: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;
50+
oncanplay?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
51+
oncanplaythrough?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
52+
ondurationchange?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
53+
onemptied?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
54+
onended?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
55+
onerror?: OnErrorEventHandler | null;
56+
onloadeddata?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
57+
onloadedmetadata?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
58+
onloadstart?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
59+
onpause?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
60+
onplay?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
61+
onplaying?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
62+
onprogress?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
63+
onratechange?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
64+
onseeked?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
65+
onseeking?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
66+
onstalled?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
67+
onsuspend?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
68+
ontimeupdate?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
69+
onvolumechange?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
70+
onwaiting?: ((this: GlobalEventHandlers, ev: Event) => any) | null;
71+
}
72+
73+
interface AudioPlayerProps {
1874
/**
1975
* Displays a minimal version of the audio player, with only the play/pause button, track bar and timestamp. Defaults to `false`
2076
*/
@@ -31,7 +87,6 @@ interface AudioPlayerProps {
3187
* Gap between each individual bar in the visualization. Defaults to `1`
3288
*/
3389
gap?: number;
34-
3590
/**
3691
* Represents whether the audio visualization (waveform) should be displayed. Defaults to `true`
3792
*/
@@ -52,7 +107,6 @@ interface AudioPlayerProps {
52107
* Bar color for the bars that have been played
53108
*/
54109
barPlayedColor?: string;
55-
56110
/**
57111
* Represents whether the skip forward/backward options should be displayed. Defaults to `true`. Not applicable when `minimal` is set to `true`
58112
*/
@@ -61,14 +115,6 @@ interface AudioPlayerProps {
61115
* The number of seconds to skip forward/backward. Defaults to `5`
62116
*/
63117
skipDuration?: number;
64-
/**
65-
* Initial volume for the audio, minimum being `0`, maximum being `1`. Defaults to `0.75`
66-
*/
67-
initialVolume?: number;
68-
/**
69-
* Setting this to `true` will keep playing the audio in a loop. Defaults to `false`
70-
*/
71-
loop?: boolean;
72118
/**
73119
* Represents whether to show the loop options. Defaults to `true`
74120
*/
@@ -95,8 +141,42 @@ interface AudioPlayerProps {
95141
hideSeekKnobWhenPlaying?: boolean;
96142
}
97143

98-
const AudioPlayer: React.FC<AudioPlayerProps> = ({
144+
const AudioPlayer: React.FC<
145+
AudioElementNativeProps & AudioElementEventProps & AudioPlayerProps
146+
> = ({
147+
// native props
99148
src,
149+
loop = false,
150+
volume = 0.75,
151+
muted = false,
152+
autoplay = false,
153+
crossOrigin = null,
154+
preload = "",
155+
playbackRate = 1.0,
156+
// audio element events
157+
onabort = null,
158+
oncanplay = null,
159+
oncanplaythrough = null,
160+
ondurationchange = null,
161+
onemptied = null,
162+
onended = null,
163+
onerror = null,
164+
onloadeddata = null,
165+
onloadedmetadata = null,
166+
onloadstart = null,
167+
onpause = null,
168+
onplay = null,
169+
onplaying = null,
170+
onprogress = null,
171+
onratechange = null,
172+
onseeked = null,
173+
onseeking = null,
174+
onstalled = null,
175+
onsuspend = null,
176+
ontimeupdate = null,
177+
onvolumechange = null,
178+
onwaiting = null,
179+
// Audio player props
100180
minimal = false,
101181
width,
102182
trackHeight = 75,
@@ -108,8 +188,6 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({
108188
barPlayedColor,
109189
allowSkip = true,
110190
skipDuration = 5,
111-
initialVolume = 0.75,
112-
loop = false,
113191
showLoopOption = true,
114192
showVolumeControl = true,
115193
seekBarColor,
@@ -122,7 +200,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({
122200
const [currentTime, setCurrentTime] = useState<number>(0);
123201
const [duration, setDuration] = useState<number>(0);
124202
const [isPlaying, setIsPlaying] = useState<boolean>(false);
125-
const [volume, setVolume] = useState<number>(initialVolume);
203+
const [internalVolume, setVolume] = useState<number>(volume);
126204
const [isMuted, setIsMuted] = useState<boolean>(false);
127205
const [isLoop, setIsLoop] = useState<boolean>(loop);
128206

@@ -131,8 +209,35 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({
131209
.then(async (response): Promise<Blob> => {
132210
const blob = await response.blob();
133211
audio.src = URL.createObjectURL(blob);
134-
audio.volume = initialVolume;
212+
audio.volume = volume;
135213
audio.loop = loop;
214+
audio.muted = muted;
215+
audio.autoplay = autoplay;
216+
audio.crossOrigin = crossOrigin;
217+
audio.preload = preload;
218+
audio.playbackRate = playbackRate;
219+
audio.onabort = onabort;
220+
audio.oncanplay = oncanplay;
221+
audio.oncanplaythrough = oncanplaythrough;
222+
audio.ondurationchange = ondurationchange;
223+
audio.onemptied = onemptied;
224+
audio.onended = onended;
225+
audio.onerror = onerror;
226+
audio.onloadeddata = onloadeddata;
227+
audio.onloadedmetadata = onloadedmetadata;
228+
audio.onloadstart = onloadstart;
229+
audio.onpause = onpause;
230+
audio.onplay = onplay;
231+
audio.onplaying = onplaying;
232+
audio.onprogress = onprogress;
233+
audio.onratechange = onratechange;
234+
audio.onseeked = onseeked;
235+
audio.onseeking = onseeking;
236+
audio.onstalled = onstalled;
237+
audio.onsuspend = onsuspend;
238+
audio.ontimeupdate = ontimeupdate;
239+
audio.onvolumechange = onvolumechange;
240+
audio.onwaiting = onwaiting;
136241
setBlob(blob);
137242
return blob;
138243
})
@@ -345,7 +450,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({
345450
}}
346451
/>
347452
<TrackBar
348-
current={volume}
453+
current={internalVolume}
349454
total={1}
350455
setCurrent={setAudioVolume}
351456
color={volumeControlColor}

tests/AudioPlayer.test.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import React from "react";
22
import { expect, test, vi } from "vitest";
33
import renderer from "react-test-renderer"
4-
import userEvent from "@testing-library/user-event";
5-
import { render, act, screen } from "@testing-library/react";
64
import { AudioPlayer } from "../src/components/AudioPlayer";
75

86
describe("Test AudioPlayer", () => {

0 commit comments

Comments
 (0)