Skip to content

Commit 22b4213

Browse files
committed
feat: add player ref to the audio-player class
1 parent 86d55c3 commit 22b4213

File tree

3 files changed

+121
-119
lines changed

3 files changed

+121
-119
lines changed

package/src/components/Attachment/AudioAttachment.tsx

Lines changed: 16 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { useAudioPlayerControl } from '../../hooks/useAudioPlayerControl';
1616
import { Audio, Pause, Play } from '../../icons';
1717
import {
1818
NativeHandlers,
19-
PlaybackStatus,
2019
SoundReturnType,
2120
VideoPayloadData,
2221
VideoProgressData,
@@ -61,39 +60,41 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
6160
testID,
6261
titleMaxLength,
6362
} = props;
63+
const isVoiceRecording = isVoiceRecordingAttachment(item);
6464

6565
const { audioPlayer, toggleAudio, playAudio, pauseAudio } = useAudioPlayerControl({
6666
duration: item.duration ?? 0,
6767
mimeType: item.mime_type ?? '',
68-
playerRef: soundRef,
68+
type: isVoiceRecording ? 'voiceRecording' : 'audio',
6969
uri: item.asset_url ?? '',
7070
});
7171
const { duration, isPlaying, position, progress, currentPlaybackRate } = useStateStore(
7272
audioPlayer.state,
7373
audioPlayerSelector,
7474
);
75-
const isExpoCLI = NativeHandlers.SDK === 'stream-chat-expo';
76-
const isVoiceRecording = isVoiceRecordingAttachment(item);
75+
76+
// Initialize the player for native cli apps
77+
useEffect(() => {
78+
if (soundRef.current) {
79+
audioPlayer.initPlayer({ playerRef: soundRef.current });
80+
}
81+
}, [audioPlayer]);
7782

7883
/** This is for Native CLI Apps */
7984
const handleLoad = (payload: VideoPayloadData) => {
8085
// The duration given by the rn-video is not same as the one of the voice recording, so we take the actual duration for voice recording.
81-
if (isVoiceRecording && item.duration) {
82-
audioPlayer.duration = item.duration;
83-
} else {
84-
audioPlayer.duration = item.duration || payload.duration;
85-
}
86+
audioPlayer.duration = payload.duration * 1000;
8687
};
8788

8889
/** This is for Native CLI Apps */
8990
const handleProgress = (data: VideoProgressData) => {
9091
const { currentTime } = data;
91-
audioPlayer.position = currentTime;
92+
audioPlayer.position = currentTime * 1000;
9293
};
9394

9495
/** This is for Native CLI Apps */
9596
const onSeek = (seekResponse: VideoSeekResponse) => {
96-
audioPlayer.position = seekResponse.currentTime;
97+
audioPlayer.position = seekResponse.currentTime * 1000;
9798
};
9899

99100
const handlePlayPause = () => {
@@ -113,87 +114,11 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
113114
};
114115

115116
const dragEnd = async (progress: number) => {
116-
const position = isExpoCLI ? (progress * duration) / 1000 : progress * duration;
117+
const position = (progress * duration) / 1000;
117118
await audioPlayer.seek(position);
118119
playAudio(audioPlayer.id);
119120
};
120121

121-
/** For Expo CLI */
122-
const onPlaybackStatusUpdate = (playbackStatus: PlaybackStatus) => {
123-
if (!playbackStatus.isLoaded) {
124-
// Update your UI for the unloaded state
125-
if (playbackStatus.error) {
126-
console.log(`Encountered a fatal error during playback: ${playbackStatus.error}`);
127-
}
128-
} else {
129-
const { durationMillis, positionMillis } = playbackStatus;
130-
// Update your UI for the loaded state
131-
// This is done for Expo CLI where we don't get file duration from file picker
132-
if (item.duration === 0) {
133-
audioPlayer.duration = durationMillis;
134-
} else {
135-
// The duration given by the expo-av is not same as the one of the voice recording, so we take the actual duration for voice recording.
136-
if (isVoiceRecording && item.duration) {
137-
audioPlayer.duration = item.duration * 1000;
138-
} else {
139-
audioPlayer.duration = durationMillis;
140-
}
141-
}
142-
143-
// Update the position of the audio player when it is playing
144-
if (playbackStatus.isPlaying) {
145-
if (isVoiceRecording && item.duration) {
146-
if (positionMillis <= item.duration * 1000) {
147-
audioPlayer.position = positionMillis;
148-
}
149-
} else {
150-
if (positionMillis <= durationMillis) {
151-
audioPlayer.position = positionMillis;
152-
}
153-
}
154-
} else {
155-
// Update your UI for the paused state
156-
}
157-
158-
if (playbackStatus.isBuffering) {
159-
// Update your UI for the buffering state
160-
}
161-
162-
// Update the UI when the audio is finished playing
163-
if (playbackStatus.didJustFinish && !playbackStatus.isLooping) {
164-
handleEnd();
165-
}
166-
}
167-
};
168-
169-
// This is for Expo CLI, sound initialization is done here.
170-
useEffect(() => {
171-
if (isExpoCLI) {
172-
const initiateSound = async () => {
173-
if (item && item.asset_url && NativeHandlers.Sound?.initializeSound) {
174-
soundRef.current = await NativeHandlers.Sound.initializeSound(
175-
{ uri: item.asset_url },
176-
{
177-
pitchCorrectionQuality: 'high',
178-
progressUpdateIntervalMillis: 100,
179-
shouldCorrectPitch: true,
180-
},
181-
onPlaybackStatusUpdate,
182-
);
183-
}
184-
};
185-
initiateSound();
186-
}
187-
188-
return () => {
189-
if (soundRef.current?.stopAsync && soundRef.current.unloadAsync) {
190-
soundRef.current.stopAsync();
191-
soundRef.current.unloadAsync();
192-
}
193-
};
194-
// eslint-disable-next-line react-hooks/exhaustive-deps
195-
}, []);
196-
197122
const onSpeedChangeHandler = async () => {
198123
await audioPlayer.changePlaybackRate();
199124
};
@@ -217,15 +142,15 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
217142
},
218143
} = useTheme();
219144

220-
const positionInSeconds = isExpoCLI ? position / 1000 : position;
145+
const positionInSeconds = position / 1000;
221146
const progressDuration = useMemo(
222147
() =>
223148
positionInSeconds
224149
? positionInSeconds / 3600 >= 1
225150
? dayjs.duration(positionInSeconds, 'second').format('HH:mm:ss')
226151
: dayjs.duration(positionInSeconds, 'second').format('mm:ss')
227-
: dayjs.duration(isExpoCLI ? duration / 1000 : duration, 'second').format('mm:ss'),
228-
[duration, isExpoCLI, positionInSeconds],
152+
: dayjs.duration(duration / 1000, 'second').format('mm:ss'),
153+
[duration, positionInSeconds],
229154
);
230155

231156
return (

package/src/hooks/useAudioPlayerControl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ const makeAudioPlayerId = ({
3232
export const useAudioPlayerControl = ({
3333
duration,
3434
mimeType,
35-
playerRef,
3635
playbackRates,
3736
requester = '',
37+
type,
3838
uri,
3939
id: fileId,
4040
}: UseAudioPlayerControlProps) => {
@@ -47,10 +47,10 @@ export const useAudioPlayerControl = ({
4747
id,
4848
mimeType: mimeType ?? '',
4949
playbackRates,
50-
playerRef: playerRef ?? null,
50+
type: type ?? 'audio',
5151
uri: uri ?? '',
5252
}),
53-
[audioPlayerPool, duration, id, mimeType, playbackRates, playerRef, uri],
53+
[audioPlayerPool, duration, id, mimeType, playbackRates, type, uri],
5454
);
5555

5656
return {

0 commit comments

Comments
 (0)