Skip to content

Commit 39966fd

Browse files
authored
AudioPlayer updates (#667)
* Refactored AudioPlayer to have a 'headless' mode * Fixed issue with source as useEffect dependandancy * Fixed type of style prop in audio player * Moved AudioPlayer into core * Allowed more customization to player interface + updated default style to use theme colors * Removed inline styles from audio player * Updated name of thumbColor prop * Added @expo/vector-icons dependancy to core * Change audio player default colors * Rplace touchable highlight with pressable * Added error handling to failed setting of audio mode
1 parent decb6ca commit 39966fd

File tree

12 files changed

+595
-312
lines changed

12 files changed

+595
-312
lines changed

example/src/AudioPlayerExample.tsx

Lines changed: 107 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,114 @@
11
import React from "react";
22
import { Text } from "react-native";
3-
import { AudioPlayer, ScreenContainer } from "@draftbit/ui";
3+
import { AudioPlayer, ButtonSolid } from "@draftbit/ui";
4+
import type { AudioPlayerRef } from "@draftbit/ui";
5+
import Section, { Container } from "./Section";
46

57
export default function AudioPlayerExample() {
8+
const audioPlayerRef = React.useRef<AudioPlayerRef>(null);
9+
const [headlessState, setHeadlessState] = React.useState<object>();
10+
611
return (
7-
<ScreenContainer hasSafeArea={false} scrollable={false}>
8-
<Text> Local asset value </Text>
9-
<AudioPlayer
10-
style={{
11-
backgroundColor: "#eee",
12-
paddingLeft: 8,
13-
paddingRight: 8,
14-
paddingTop: 8,
15-
paddingBottom: 8,
16-
borderRadius: 24,
17-
marginBottom: 20,
18-
fontWeight: "bold",
19-
height: 40,
20-
width: "80%",
21-
}}
22-
source={require("./assets/loop.wav")}
23-
sliderColor="red"
24-
completedTrackColor="white"
25-
remainingTrackColor="#999999"
26-
playSize={18}
27-
playsInBackground
28-
interruptionMode="stop"
29-
/>
30-
<AudioPlayer
31-
style={{
32-
backgroundColor: "#333",
33-
padding: 8,
34-
margin: 8,
35-
marginBottom: 20,
36-
borderRadius: 4,
37-
color: "#fff",
38-
}}
39-
source={require("./assets/loop.wav")}
40-
sliderColor="white"
41-
completedTrackColor="white"
42-
remainingTrackColor="#dedede"
43-
playSize={18}
44-
playColor="#fff"
45-
/>
46-
<Text> Remote value </Text>
47-
<AudioPlayer
48-
style={{
49-
paddingLeft: 20,
50-
paddingRight: 20,
51-
paddingTop: 8,
52-
paddingBottom: 8,
53-
color: "red",
54-
fontSize: 14,
55-
}}
56-
source={{
57-
uri: "https://static.draftbit.com/audio/intro-to-draftbit-audio.mp3",
58-
}}
59-
/>
60-
</ScreenContainer>
12+
<Container style={{}}>
13+
<Section style={{}} title="Default styling">
14+
<AudioPlayer
15+
source={require("./assets/loop.wav")}
16+
playsInBackground
17+
interruptionMode="stop"
18+
/>
19+
</Section>
20+
<Section style={{}} title="Custom styling">
21+
<AudioPlayer
22+
style={{
23+
backgroundColor: "#eee",
24+
borderRadius: 24,
25+
borderWidth: 0,
26+
fontWeight: "bold",
27+
height: 40,
28+
width: "80%",
29+
}}
30+
source={require("./assets/loop.wav")}
31+
sliderColor="red"
32+
completedTrackColor="white"
33+
remainingTrackColor="#999999"
34+
togglePlaybackIconSize={18}
35+
togglePlaybackIconColor="green"
36+
playsInBackground
37+
interruptionMode="stop"
38+
/>
39+
<AudioPlayer
40+
style={{
41+
backgroundColor: "#333",
42+
padding: 8,
43+
borderWidth: 0,
44+
borderRadius: 4,
45+
color: "#fff",
46+
marginTop: 10,
47+
}}
48+
source={require("./assets/loop.wav")}
49+
sliderColor="white"
50+
completedTrackColor="white"
51+
remainingTrackColor="#dedede"
52+
togglePlaybackIconSize={18}
53+
togglePlaybackIconColor="#fff"
54+
/>
55+
<AudioPlayer
56+
style={{ width: 50, marginTop: 10 }}
57+
source={require("./assets/loop.wav")}
58+
playsInBackground
59+
interruptionMode="stop"
60+
hideDuration
61+
hideSlider
62+
/>
63+
<AudioPlayer
64+
style={{ width: 150, marginTop: 10 }}
65+
source={require("./assets/loop.wav")}
66+
playsInBackground
67+
interruptionMode="stop"
68+
hideSlider
69+
/>
70+
</Section>
71+
<Section style={{}} title="Local asset value">
72+
<AudioPlayer
73+
source={require("./assets/loop.wav")}
74+
playsInBackground
75+
interruptionMode="stop"
76+
/>
77+
</Section>
78+
<Section style={{}} title="Remote value">
79+
<AudioPlayer
80+
source={{
81+
uri: "https://static.draftbit.com/audio/intro-to-draftbit-audio.mp3",
82+
}}
83+
/>
84+
</Section>
85+
<Section style={{}} title="Headless">
86+
<AudioPlayer
87+
ref={audioPlayerRef}
88+
source={{
89+
uri: "https://static.draftbit.com/audio/intro-to-draftbit-audio.mp3",
90+
}}
91+
mode="headless"
92+
onPlaybackStatusUpdate={(state) => {
93+
setHeadlessState(state);
94+
}}
95+
/>
96+
<ButtonSolid
97+
title="Toggle playback headless"
98+
onPress={() => {
99+
audioPlayerRef?.current?.togglePlayback();
100+
}}
101+
/>
102+
<ButtonSolid
103+
title="Seek headless to 30 second mark"
104+
onPress={() => {
105+
audioPlayerRef?.current?.seekToPosition(30000);
106+
}}
107+
/>
108+
<Text>{`Current headless state: ${JSON.stringify(
109+
headlessState
110+
)}`}</Text>
111+
</Section>
112+
</Container>
61113
);
62114
}

packages/core/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@
4545
"@react-native-community/slider": "4.2.4",
4646
"@react-native-picker/picker": "2.4.8",
4747
"@shopify/flash-list": "1.3.1",
48+
"@expo/vector-icons": "^13.0.0",
4849
"color": "^3.1.2",
4950
"date-fns": "^2.16.1",
5051
"dateformat": "^3.0.3",
52+
"expo-av": "~13.0.3",
5153
"lodash.isnumber": "^3.0.3",
5254
"lodash.omit": "^4.5.0",
5355
"lodash.tonumber": "^4.0.3",
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { AVPlaybackSource } from "expo-av";
2+
import { StyleProp, ViewStyle, TextStyle } from "react-native";
3+
import type { Theme } from "../../styles/DefaultTheme";
4+
5+
export type AudioInterruptionMode = "lower volume" | "stop";
6+
7+
export interface AudioPlayerStatus {
8+
isPlaying: boolean;
9+
isLoading: boolean;
10+
isBuffering: boolean;
11+
currentPositionMillis: number;
12+
durationMillis: number;
13+
bufferedDurationMillis: number;
14+
isError: boolean;
15+
error?: string;
16+
}
17+
18+
export interface HeadlessAudioPlayerRef {
19+
seekToPosition: (positionMillis: number) => void;
20+
togglePlayback: () => void;
21+
}
22+
23+
export interface HeadlessAudioPlayerProps {
24+
onPlaybackStatusUpdate?: (status: AudioPlayerStatus) => void;
25+
onPlaybackFinish?: () => void;
26+
source: AVPlaybackSource;
27+
interruptionMode?: AudioInterruptionMode;
28+
playsInBackground?: boolean;
29+
playsInSilentModeIOS?: boolean;
30+
playThroughEarpieceAndroid?: boolean;
31+
}
32+
33+
export interface AudioPlayerInterfaceProps {
34+
style?: StyleProp<ViewStyle & TextStyle>;
35+
thumbColor?: string;
36+
completedTrackColor?: string;
37+
remainingTrackColor?: string;
38+
togglePlaybackIconSize?: number;
39+
togglePlaybackIconColor?: string;
40+
hidePlaybackIcon?: boolean;
41+
hideDuration?: boolean;
42+
hideSlider?: boolean;
43+
theme: Theme;
44+
}

0 commit comments

Comments
 (0)