← Все материалы

CanvasTake · Canvas / Web Audio / GIF

Как добавить озвучку к записи canvas с CanvasTake

Автор: Grundy · Проверено: 15 октября 2026

Canvas сам по себе не содержит звук. CanvasTake с версии 0.2.0 может записать изображение canvas вместе с переданными аудиодорожками. Разберём подключение заранее записанной озвучки: Web Audio воспроизводит файл, а MediaRecorder сохраняет его вместе с анимацией.

1. Подготовьте canvas и аудиофайл

Установите @grundyjs/canvas-take версии 0.2.0 или новее. Код выполняется в браузере. Передайте canvas с уже нарисованным первым кадром и narrationBytes — ArrayBuffer аудиофайла, полученный через File.arrayBuffer() или fetch().arrayBuffer(). Размеры canvas задайте до записи и не меняйте до stop().

2. Передайте дорожку в recorder

AudioBufferSource подключается к MediaStreamDestination. Его getAudioTracks() передаём в audioTracks. Вызовите функцию из обработчика кнопки, чтобы audio.resume() мог разблокировать звук. В примере дорожка идёт в запись, но не в динамики; для прослушивания дополнительно подключите source к audio.destination.

import { createCanvasRecorder } from "@grundyjs/canvas-take";

async function recordNarration(canvas, narrationBytes) {
    const audio = new AudioContext();
    let recorder;
    let destination;
    try {
        await audio.resume();
        const buffer = await audio.decodeAudioData(narrationBytes);
        destination = audio.createMediaStreamDestination();
        const source = audio.createBufferSource();
        source.buffer = buffer;
        source.connect(destination);
        recorder = createCanvasRecorder(canvas, {
            fps: 30,
            mimeType: "video/mp4",
            audioTracks: destination.stream.getAudioTracks(),
        });
        const finished = new Promise(resolve => {
            source.addEventListener("ended", resolve, { once: true });
        });
        await recorder.start();
        source.start();
        // Run your canvas animation while the narration plays.
        await finished;
        return await recorder.stop();
    } finally {
        recorder?.dispose();
        destination?.stream.getTracks().forEach(track => track.stop());
        await audio.close();
    }
}

3. Запустите озвучку после старта записи

Сначала дождитесь recorder.start(), затем вызовите source.start() и запустите свою анимацию. CanvasTake не рисует кадры и не запускает плеер. Комментарий Run your canvas animation — место для этого кода. Пример завершает видео по окончании озвучки: если анимация длиннее, выберите другое условие остановки. Это запись в реальном времени, а не гарантия покадровой синхронизации.

4. Проверьте контейнер и кодеки

Явный video/mp4 завершится ошибкой, если браузер его не поддерживает; автоматического перехода на WebM в этом случае нет. MP4 не гарантирует H.264/AAC: при таком требовании площадки используйте video/mp4;codecs=avc1,mp4a.40.2 и обработайте ошибку поддержки. Проверяйте возвращённые mimeType и extension. Для автоматического выбора формата уберите mimeType.

5. Освободите ресурсы и проверьте результат

finally нужен и при ошибке отрисовки или кодирования. CanvasTake останавливает собственные дорожки и клоны; исходные audioTracks и AudioContext остаются ответственностью приложения. Окончание AudioBufferSource не завершает destination-track. Для нескольких звуков сведите их в один destination. Прослушайте начало и конец результата, проверьте совпадение речи с кадрами и воспроизведение после загрузки на целевую площадку. Каждый recorder используется один раз.