diff --git a/src/plugins/audioPlaybackSpeed/README.md b/src/plugins/audioPlaybackSpeed/README.md
new file mode 100644
index 000000000..f49f9cf53
--- /dev/null
+++ b/src/plugins/audioPlaybackSpeed/README.md
@@ -0,0 +1,5 @@
+# AudioPlaybackSpeed
+
+Adds an icon to change the playback speed of voice message and audio embeds
+
+![New icon with menu to change the playback speed](https://github.com/Vendicated/Vencord/assets/24937357/21792b09-8d6a-45be-a6e8-916cdd67a477)
diff --git a/src/plugins/audioPlaybackSpeed/components/SpeedIcon.tsx b/src/plugins/audioPlaybackSpeed/components/SpeedIcon.tsx
new file mode 100644
index 000000000..a59cbb094
--- /dev/null
+++ b/src/plugins/audioPlaybackSpeed/components/SpeedIcon.tsx
@@ -0,0 +1,21 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+function SpeedIcon() {
+ return (
+
+ );
+}
+
+export default SpeedIcon;
diff --git a/src/plugins/audioPlaybackSpeed/index.tsx b/src/plugins/audioPlaybackSpeed/index.tsx
new file mode 100644
index 000000000..03739f2dc
--- /dev/null
+++ b/src/plugins/audioPlaybackSpeed/index.tsx
@@ -0,0 +1,91 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import "./styles.css";
+
+import { classNameFactory } from "@api/Styles";
+import { makeRange } from "@components/PluginSettings/components";
+import { Devs } from "@utils/constants";
+import definePlugin from "@utils/types";
+import { ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
+import { RefObject } from "react";
+
+import SpeedIcon from "./components/SpeedIcon";
+
+const cl = classNameFactory("vc-audio-playback-speed-");
+
+const speeds = makeRange(0.25, 3.5, 0.25);
+
+export default definePlugin({
+ name: "AudioPlaybackSpeed",
+ description: "Adds an icon to change the playback speed of voice message and audio embeds",
+ authors: [Devs.D3SOX],
+
+ playbackSpeedComponent(audioRef: RefObject) {
+ const changeSpeed = (speed: number) => {
+ const audio = audioRef.current;
+ if (audio) {
+ audio.playbackRate = speed;
+ }
+ };
+
+ return (
+
+ );
+ },
+
+ patches: [
+ // voice message embeds
+ {
+ find: "ComponentActions.VOICE_MESSAGE_PLAYBACK_STARTED",
+ replacement: {
+ match: /useCallback\(\(\)=>\{let \i=(\i).current;.{2300,2800}onVolumeShow:\i,onVolumeHide:\i\}\)/,
+ replace: "$&,$self.playbackSpeedComponent($1)"
+ }
+ },
+ // audio embeds
+ {
+ // need to pass media ref via props to make it easily accessible from inside controls
+ find: "renderControls(){",
+ replacement: {
+ match: /onToggleMuted:this.toggleMuted,/,
+ replace: "$&mediaRef:this.mediaRef,"
+ }
+ },
+ {
+ find: "AUDIO:\"AUDIO\"",
+ replacement: {
+ match: /onVolumeHide:\i,iconClassName:\i.controlIcon,sliderWrapperClassName:\i.volumeSliderWrapper\}\)\}\),/,
+ replace: "$&$self.playbackSpeedComponent(this.props.mediaRef),"
+ }
+ }
+ ]
+});
diff --git a/src/plugins/audioPlaybackSpeed/styles.css b/src/plugins/audioPlaybackSpeed/styles.css
new file mode 100644
index 000000000..98fff293e
--- /dev/null
+++ b/src/plugins/audioPlaybackSpeed/styles.css
@@ -0,0 +1,5 @@
+.vc-audio-playback-speed-icon {
+ background-color: transparent;
+ height: 100%;
+ z-index: 2;
+}