fix(core): audio player ux (#11685)

This commit is contained in:
pengx17
2025-04-15 07:31:06 +00:00
committed by Peng Xiao
parent 793d084077
commit 46f3dfc64c
3 changed files with 12 additions and 20 deletions

View File

@@ -111,7 +111,7 @@ export const AudioPlayer = ({
waveform={waveform || []} waveform={waveform || []}
progress={progressPercentage} progress={progressPercentage}
onManualSeek={handleProgressClick} onManualSeek={handleProgressClick}
loading={loading} loading={!waveform || waveform.length === 0}
/> />
<div className={styles.timeDisplay}>{formatTime(duration)}</div> <div className={styles.timeDisplay}>{formatTime(duration)}</div>
</div> </div>

View File

@@ -27,7 +27,6 @@ const AttachmentAudioPlayer = ({ block }: { block: AudioAttachmentBlock }) => {
const audioMedia = block.audioMedia; const audioMedia = block.audioMedia;
const playbackState = useLiveData(audioMedia.playbackState$); const playbackState = useLiveData(audioMedia.playbackState$);
const stats = useLiveData(audioMedia.stats$); const stats = useLiveData(audioMedia.stats$);
const loading = useLiveData(audioMedia.loading$);
const expanded = useLiveData(block.expanded$); const expanded = useLiveData(block.expanded$);
const [preflightChecking, setPreflightChecking] = useState(false); const [preflightChecking, setPreflightChecking] = useState(false);
const transcribing = const transcribing =
@@ -184,7 +183,7 @@ const AttachmentAudioPlayer = ({ block }: { block: AudioAttachmentBlock }) => {
<AudioPlayer <AudioPlayer
name={block.props.props.name} name={block.props.props.name}
size={sizeEntry} size={sizeEntry}
loading={loading} loading={stats.duration === 0}
playbackState={playbackState?.state || 'idle'} playbackState={playbackState?.state || 'idle'}
waveform={stats.waveform} waveform={stats.waveform}
seekTime={seekTime} seekTime={seekTime}

View File

@@ -156,20 +156,7 @@ export class AudioMedia extends Entity<AudioSource> {
private async loadAudioBuffer() { private async loadAudioBuffer() {
const uint8Array = await this.getBuffer(); const uint8Array = await this.getBuffer();
return new Blob([uint8Array]);
// Create a blob from the uint8Array
const blob = new Blob([uint8Array]);
const startTime = performance.now();
// calculating audio stats is expensive. Maybe persist the result in cache?
const stats = await this.calculateStatsFromBuffer(blob);
logger.debug(
`Calculate audio stats time: ${performance.now() - startTime}ms`
);
return {
blob,
...stats,
};
} }
readonly revalidateBuffer = effect( readonly revalidateBuffer = effect(
@@ -177,11 +164,10 @@ export class AudioMedia extends Entity<AudioSource> {
return fromPromise(async () => { return fromPromise(async () => {
return this.loadAudioBuffer(); return this.loadAudioBuffer();
}).pipe( }).pipe(
mergeMap(({ blob, waveform }) => { mergeMap(async blob => {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
// Set the audio element source // Set the audio element source
this.audioElement.src = url; this.audioElement.src = url;
this.waveform$.setValue(waveform);
// If the media is playing, resume the playback // If the media is playing, resume the playback
if (this.playbackState$.getValue().state === 'playing') { if (this.playbackState$.getValue().state === 'playing') {
this.play(true); this.play(true);
@@ -189,8 +175,15 @@ export class AudioMedia extends Entity<AudioSource> {
this.audioElement.onloadedmetadata = () => { this.audioElement.onloadedmetadata = () => {
this.duration$.setValue(this.audioElement.duration); this.duration$.setValue(this.audioElement.duration);
}; };
return EMPTY; const startTime = performance.now();
// calculating audio stats is expensive. Maybe persist the result in cache?
const stats = await this.calculateStatsFromBuffer(blob);
this.waveform$.setValue(stats.waveform);
logger.debug(
`Calculate audio stats time: ${performance.now() - startTime}ms`
);
}), }),
mergeMap(() => EMPTY),
onStart(() => this.loading$.setValue(true)), onStart(() => this.loading$.setValue(true)),
onComplete(() => { onComplete(() => {
this.loading$.setValue(false); this.loading$.setValue(false);