Конвертер видео в gif с помощью Wasm

Добро пожаловать в очередной блог.
Этот блог будет очень интересным!

Сегодня мы будем создавать конвертер видео в .gif с помощью Wasm.
Это может быть использовано как ваш проект wasm или мини-проект.

WebAssembly сделал все настолько простым, поскольку традиционно мы загружали наши приложения на облачный сервер, где сервер работал на задней стороне. Но wasm позволяет нам выполнять работу, требующую больших затрат процессора, прямо в браузере.

Здесь мы будем использовать библиотеку FFmpeg (написанную на языке c) для преобразования видео в gif. Мы загрузим бинарные файлы wasm для ffmpeg прямо в приложение react, что позволит нам разгрузить работу по редактированию видео в нашей системе непосредственно через браузер.

Итак, приступим.

1. Создание каталога

a. Создайте новую директорию wasm-gif.
b. Переместитесь в каталог cd wasm-gif/.

2. Генерируем новое приложение react с помощью snowpack:

npx create-snowpack-app gifmakr --template @snowpack/app-template-react

Войдите в полноэкранный режим Выйдите из полноэкранного режима

Будет автоматически получены файлы для приложения react.

3. Установите FFmpeg

npm install @ffmpeg/ffmpeg @ffmpeg/core
Войдите в полноэкранный режим Выйдите из полноэкранного режима

4. Запустите приложение

npm start
Войдите в полноэкранный режим Выйти из полноэкранного режима

Эта команда позволит запустить приложение react по умолчанию в браузере.

Если мы проверим вкладку Sources в elements/developer tools браузера, то увидим код, преобразованный в WebAssembly Text.

5. Написание кода react.

a. Перейдите в src/ и откройте App.jsx и удалите шаблон.
b. Добавьте

(i), работая с этой библиотекой, мы установим опцию log в true, чтобы мы могли видеть все, что она делает, прямо в консоли. Сейчас важно понять, что бинарный файл webassembly не был включен в наше приложение.

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({ log: true });
Вход в полноэкранный режим Выход из полноэкранного режима

(ii) Для отслеживания состояния загрузки мы добавим свойство состояния ready с помощью функции use state hook, которое по умолчанию имеет значение false, а затем создадим асинхронную функцию load, которая переключит его на true после загрузки бинарного файла.

function App() {
  const [ready, setReady] = useState(false);

  const load = async () => {
    await ffmpeg.load();
    setReady(true);
  }
Вход в полноэкранный режим Выход из полноэкранного режима

(iii) Теперь нам просто нужно место для вызова этой функции в react, поэтому мы можем сделать это с помощью хука use effect, чтобы запустить эту функцию при первой инициализации компонента use effect принимает функцию в качестве аргумента, затем обратите внимание, как я добавляю пустой массив в качестве второго аргумента, это гарантирует, что функция будет вызвана только один раз при первой инициализации или установке компонента, затем внутри эффекта мы можем просто вызвать нашу функцию load.

 useEffect(() => {
    load();
  }, [])


  return ready ? () : ( <p> Loading...</p> );
}

export default App;
Вход в полноэкранный режим Выйти из полноэкранного режима

6. Загрузка видеофайла в приложение

a. Первым шагом будет добавление дополнительного состояния в компонент, в данном случае видео файла, который изначально будет начинаться неопределенно в html мы можем добавить элемент ввода с типом файла, когда этот ввод изменится мы запустим обработчик события, который установит состояние видео и он получит фактический файл из события событие выдает список файлов, а затем мы используем элемент 0(FILE Object) для выбора первого файла из этого списка.

function App() {
  const [ready, setReady] = useState(false);
  const [video, setVideo] = useState();
  const [gif, setGif] = useState();

  const load = async () => {
    await ffmpeg.load();
    setReady(true);
  }

  useEffect(() => {
    load();
  }, [])
Вход в полноэкранный режим Выход из полноэкранного режима

b. Теперь, когда у нас есть доступ к видео файлу, мы хотим отобразить его в html видео элементе, мы будем использовать логический оператор and, чтобы показывать видео только тогда, когда видео файл определен, элемент имеет элементы управления шириной 250, но сложность здесь в том, что мы не можем просто передать необработанный файл в атрибут source, нам нужно преобразовать его в url, который браузер может получить.
браузер может получить, поэтому назначьте файл URL.

 <div className="App">
      { video && <video
        controls
        width="250"
        src={URL.createObjectURL(video)}>

      </video>}


      <input type="file" onChange={(e) => setVideo(e.target.files?.item(0))} />

      <h3>Result</h3>

      <button onClick={convertToGif}>Convert</button>

      { gif && <img src={gif} width="250" />}

    </div>
  )
    :
    (
      <p>Loading...</p>
    );
}

export default App;

Вход в полноэкранный режим Выход из полноэкранного режима

c. Теперь мы добавим еще одну часть состояния компонента под названием gif, и она будет использоваться для хранения конечного результата, которым является url файла изображения, а затем мы создадим функцию convert to gif, которую пользователь сможет запустить, когда будет готов выполнить преобразование.
в памяти файловой системой и для того, чтобы запустить ffmpeg на этом файле, нам нужно сделать его известным этой файловой системе, мы можем сделать это, вызвав fs или filesystem вместе с методом write file вместе с именем файла, а затем мы получаем фактический видео файл, который мы собрали от конечного пользователя, что мы сделали, это взяли видео файл и сохранили его в памяти как test. mp4, теперь к нему может обратиться webassembly, пока он находится в памяти, и он остается в памяти только до тех пор, пока браузер не обновится, после чего мы можем запустить фактическую команду ffmpeg.
команда.

import React, { useState, useEffect } from 'react';
import './App.css';

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({ log: true });

function App() {
  const [ready, setReady] = useState(false);
  const [video, setVideo] = useState();
  const [gif, setGif] = useState();

  const load = async () => {
    await ffmpeg.load();
    setReady(true);
  }

  useEffect(() => {
    load();
  }, [])

  const convertToGif = async () => {
    // Write the file to memory 
    ffmpeg.FS('writeFile', 'test.mp4', await fetchFile(video));

    // Run the FFMpeg command
    await ffmpeg.run('-i', 'test.mp4', '-t', '2.5', '-ss', '2.0', '-f', 'gif', 'out.gif');

    // Read the result
    const data = ffmpeg.FS('readFile', 'out.gif');

    // Create a URL
    const url = URL.createObjectURL(new Blob([data.buffer], { type: 'image/gif' }));
    setGif(url)
  }

  return ready ? (

    <div className="App">
      { video && <video
        controls
        width="250"
        src={URL.createObjectURL(video)}>

      </video>}


      <input type="file" onChange={(e) => setVideo(e.target.files?.item(0))} />

      <h3>Result</h3>

      <button onClick={convertToGif}>Convert</button>

      { gif && <img src={gif} width="250" />}

    </div>
  )
    :
    (
      <p>Loading...</p>
    );
}

export default App;

Вход в полноэкранный режим Выход из полноэкранного режима

Наконец, теперь мы можем открыть демо-версию и выбрать видеофайл, затем, когда вы нажмете кнопку convert, он использует webassembly для преобразования этого файла в анимированный gif-файл, и он должен регистрировать весь процесс здесь, в консоли. Затем вы можете взять этот файл и загрузить его на giphy или использовать его в twitter или как угодно, и вот как легко начать внедрять webassembly в ваши веб-приложения.

Мы также можем использовать CSS, чтобы сделать это приложение более интерактивным и красивым.

Отказ от ответственности: Это приложение будет работать только в тех браузерах, которые поддерживают SharedArrayBuffer.

Попробуйте установить предыдущую версию браузеров, если у вас не получается создать это приложение.

Ссылка:

  1. https://ffmpeg.org/documentation.html
  2. https://github.com/fireship-io/react-wasm-gif-maker/
  3. https://codeburst.io/getting-started-with-react-and-webassembly-using-hooks-441818c91608
  4. https://medium.com/@anksaiki/using-web-assembly-in-a-react-app-8b59e5e9f5aa

Оставляйте свои идеи и предложения, связанные с этим блогом, и поделитесь с нами, если вы нашли его полезным.
Пишите ваши вопросы в разделе комментариев, мы поможем вам решить ваши ошибки.

Оцените статью
Procodings.ru
Добавить комментарий