Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Record and send audio via Chrome microphone #1996

Merged
merged 26 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0ac7d03
audio recording basics
namanagar Jan 13, 2025
03f1fe1
minor ui fixes
namanagar Jan 13, 2025
ec5c7dd
refactor
namanagar Jan 13, 2025
45cc045
fix logic
namanagar Jan 13, 2025
59f0e59
Merge branch 'main' into naman/playground-microphone
namanagar Jan 13, 2025
c5fe7f6
audio controls + backend mime type
namanagar Jan 14, 2025
714fa29
Merge branch 'main' into naman/playground-microphone
namanagar Jan 14, 2025
fa1e217
cleanup + hook up backend mimetype
namanagar Jan 14, 2025
ce075d7
lint fixes
namanagar Jan 14, 2025
9d48268
add todo
namanagar Jan 14, 2025
def5310
cleaner
namanagar Jan 14, 2025
5c31751
more cleanup
namanagar Jan 14, 2025
a724ea8
tiny copy edit
namanagar Jan 14, 2025
3cb2f2d
Merge branch 'main' into naman/playground-microphone
namanagar Jan 14, 2025
96afbbf
small controls update
namanagar Jan 14, 2025
8aa06fd
iconoir -> lucide, one bug with invalid files
namanagar Jan 14, 2025
9c3bba3
remove stringtype changes
namanagar Jan 14, 2025
a075b30
Merge branch 'main' into naman/playground-microphone
namanagar Jan 14, 2025
5406b4d
remove string + mimetype on frontend
namanagar Jan 14, 2025
bd82d05
Merge branch 'main' into naman/playground-microphone
namanagar Jan 15, 2025
dc00c6b
address comments
namanagar Jan 15, 2025
ca005e1
Merge branch 'main' into naman/playground-microphone
namanagar Jan 15, 2025
a11d543
fix compile breaks
RohinBhargava Jan 15, 2025
8837793
Merge branch 'main' into naman/playground-microphone
namanagar Jan 15, 2025
16f1a5d
prettier
namanagar Jan 15, 2025
f93ad11
Merge branch 'naman/playground-microphone' of github.com:fern-api/fer…
namanagar Jan 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fern/apis/fdr/definition/api/v1/read/type.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ types:
Base64Type:
properties:
default: optional<base64>
mimeType: optional<string>

DateType:
properties:
Expand Down
1 change: 1 addition & 0 deletions fern/apis/fdr/definition/api/v1/register/type.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ types:
Base64Type:
properties:
default: optional<base64>
mimeType: optional<string>

DateType:
properties:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/fern-docs/bundle/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vercel
2 changes: 2 additions & 0 deletions packages/fern-docs/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"jotai-location": "^0.5.5",
"jsonpath": "^1.1.1",
"launchdarkly-react-client-sdk": "^3.6.0",
"lucide-react": "^0.460.0",
"mdx-bundler": "^10.0.2",
"mermaid": "^11.2.1",
"moment": "^2.30.1",
Expand Down Expand Up @@ -122,6 +123,7 @@
"unist-util-visit": "^5.0.0",
"url-join": "5.0.0",
"use-memo-one": "^1.1.3",
"webm-duration-fix": "^1.0.4",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny package that helps w/ the blob data from the media recorder api — without this, the <audio> element after recording has incorrect metadata (duration: Infinity) which messes with the playback

"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { FernButton, FernButtonGroup } from "@fern-docs/components";
import { Download, Octagon, Play } from "lucide-react";
import { useEffect, useRef, useState } from "react";

interface PlaygroundAudioControlsProps {
audioUrl: string | null;
fileName?: string;
}

export function PlaygroundAudioControls({
audioUrl,
fileName = "recording.webm",
}: PlaygroundAudioControlsProps) {
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [isLoaded, setIsLoaded] = useState(false);
const audioRef = useRef<HTMLAudioElement | null>(null);

useEffect(() => {
if (audioRef.current) {
audioRef.current.onended = () => setIsPlaying(false);
audioRef.current.onloadedmetadata = () => {
const audioDuration = audioRef.current?.duration;
if (audioDuration && !isNaN(audioDuration) && isFinite(audioDuration)) {
setDuration(Math.round(audioDuration));
setIsLoaded(true);
}
};
audioRef.current.ontimeupdate = () => {
const currentTime = audioRef.current?.currentTime;
if (currentTime && !isNaN(currentTime) && isFinite(currentTime)) {
setCurrentTime(Math.round(currentTime));
}
};
}
}, []);

const formatTime = (seconds: number) => {
const mins = Math.floor(seconds / 60)
.toString()
.padStart(2, "0");
const secs = (seconds % 60).toString().padStart(2, "0");
return `${mins}:${secs}`;
};

const handlePlayPause = async () => {
if (!audioRef.current || !audioUrl) return;

if (isPlaying) {
audioRef.current.pause();
audioRef.current.currentTime = 0;
setCurrentTime(0);
} else {
await audioRef.current.play();
}
setIsPlaying(!isPlaying);
};

const handleDownload = () => {
if (!audioUrl) return;
const a = document.createElement("a");
a.href = audioUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};

if (!audioUrl) return null;

return (
<div className="flex items-center gap-2">
<audio ref={audioRef} src={audioUrl} preload="metadata" />
{isLoaded && (
<span className="font-mono text-xs">
{`${formatTime(currentTime)}/${formatTime(duration)}`}
</span>
)}
<FernButtonGroup>
<FernButton
icon={isPlaying ? <Octagon /> : <Play />}
onClick={handlePlayPause}
size="small"
variant="minimal"
disabled={!audioUrl}
/>
<FernButton
icon={<Download />}
onClick={handleDownload}
size="small"
variant="minimal"
disabled={!audioUrl}
/>
</FernButtonGroup>
</div>
);
}
Loading
Loading