Remotion.cool

Audiogram

Create beautiful audiogram videos with waveforms

#audiogram
#audio-visualization
#waveform
#template
1import React from "react";
2import { AbsoluteFill, Img, Sequence, useVideoConfig } from "remotion";
3import { Audio } from "@remotion/media";
4import { PaginatedCaptions } from "./Captions";
5import { Spectrum } from "./Spectrum";
6import {
7  BASE_SIZE,
8  CAPTIONS_FONT_SIZE,
9  CAPTIONS_FONT_WEIGHT,
10  LINE_HEIGHT,
11  LINES_PER_PAGE,
12} from "./constants";
13import { Oscilloscope } from "./Oscilloscope";
14import { FONT_FAMILY } from "./font";
15import { WaitForFonts } from "./WaitForFonts";
16import { AudiogramCompositionSchemaType } from "./schema";
17
18export const Audiogram: React.FC<AudiogramCompositionSchemaType> = ({
19  visualizer,
20  audioFileUrl,
21  coverImageUrl,
22  titleText,
23  titleColor,
24  captionsTextColor,
25  onlyDisplayCurrentSentence,
26  audioOffsetInSeconds,
27  captions,
28}) => {
29  const { durationInFrames, fps, width } = useVideoConfig();
30
31  if (!captions) {
32    throw new Error(
33      "subtitles should have been provided through calculateMetadata",
34    );
35  }
36
37  const audioOffsetInFrames = Math.round(audioOffsetInSeconds * fps);
38  const baseNumberOfSamples = Number(visualizer.numberOfSamples);
39
40  const textBoxWidth = width - BASE_SIZE * 2;
41
42  return (
43    <AbsoluteFill>
44      <Sequence from={-audioOffsetInFrames}>
45        <Audio src={audioFileUrl} />
46        <div
47          style={{
48            display: "flex",
49            flexDirection: "column",
50            width: "100%",
51            height: "100%",
52            color: "white",
53            padding: "48px",
54            backgroundColor: "black",
55            fontFamily: FONT_FAMILY,
56          }}
57        >
58          <div
59            style={{
60              display: "flex",
61              flexDirection: "row",
62              alignItems: "center",
63            }}
64          >
65            <Img
66              style={{
67                borderRadius: "6px",
68                maxHeight: "250px",
69              }}
70              src={coverImageUrl}
71            />
72            <div
73              style={{
74                marginLeft: "48px",
75                lineHeight: "1.25",
76                fontWeight: 800,
77                color: titleColor,
78                fontSize: "48px",
79              }}
80            >
81              {titleText}
82            </div>
83          </div>
84          <div>
85            {visualizer.type === "oscilloscope" ? (
86              <Oscilloscope
87                waveColor={visualizer.color}
88                padding={visualizer.padding}
89                audioSrc={audioFileUrl}
90                key={audioFileUrl}
91                numberOfSamples={baseNumberOfSamples}
92                windowInSeconds={visualizer.windowInSeconds}
93                posterization={visualizer.posterization}
94                amplitude={visualizer.amplitude}
95              />
96            ) : visualizer.type === "spectrum" ? (
97              <Spectrum
98                barColor={visualizer.color}
99                audioSrc={audioFileUrl}
100                key={audioFileUrl}
101                mirrorWave={visualizer.mirrorWave}
102                numberOfSamples={baseNumberOfSamples * 4} // since fft is used, we need to increase the number of samples to get a better resolution
103                freqRangeStartIndex={visualizer.freqRangeStartIndex}
104                waveLinesToDisplay={visualizer.linesToDisplay}
105              />
106            ) : null}
107          </div>
108          <WaitForFonts>
109            <div
110              style={{
111                lineHeight: `${LINE_HEIGHT}px`,
112                width: textBoxWidth,
113                fontWeight: CAPTIONS_FONT_WEIGHT,
114                fontSize: CAPTIONS_FONT_SIZE,
115                marginTop: BASE_SIZE * 0.5,
116              }}
117            >
118              <PaginatedCaptions
119                captions={captions}
120                startFrame={audioOffsetInFrames}
121                endFrame={audioOffsetInFrames + durationInFrames}
122                linesPerPage={LINES_PER_PAGE}
123                subtitlesTextColor={captionsTextColor}
124                onlyDisplayCurrentSentence={onlyDisplayCurrentSentence}
125                textBoxWidth={textBoxWidth}
126              />
127            </div>
128          </WaitForFonts>
129        </div>
130      </Sequence>
131    </AbsoluteFill>
132  );
133};
134

Author

r

remotion.cool

Official Account

Statistics

Views

83

Likes

0

Favorites

0

Technical Info

Composition

Audiogram

Resolution

1080x1080

FPS

30

Duration

N/A

Remotion Version

4.0.0

Published January 28, 2026

Projects

webcc.dev - Web Claude Codeviho.fun - AI CLI Toolremotion.cool - Video Creationmcp-servers.online - MCP Server Collectionaibaiban.com - AI Whiteboardaitubiao.online - AI Chart Generator

Open Source

qiao-z - Node.js Web Frameworkqiao-ui - React UI Libraryqiao-webpack - Webpack Scaffoldingqiao-project - Monorepo Toolingqiao-electron-cli - Electron Packaging CLIMore 50+ npm packages →

© 2026 Vincent. All rights reserved.