PHP

Создание скрипта для замены звуковой дорожки в видео с произвольного момента с использованием PHP и FFMPEG

59 / 100

Создание скрипта для замены звуковой дорожки в видео

Сегодня автоматизация работы с мультимедийными файлами играет важную роль для разработчиков, особенно когда речь идет о видео и звуке. Один из распространенных сценариев — это замена звуковой дорожки в видео на другую, при этом аудиофайл может начинаться с произвольного момента. В данной статье мы рассмотрим, как это реализовать с помощью PHP и FFMPEG, включая случайный старт аудиофайла.

Мы создадим PHP-скрипт, который:

  1. Находит видеофайлы с определенным шаблоном имен.
  2. Находит соответствующий аудиофайл.
  3. Случайным образом выбирает стартовую точку для аудио.
  4. Использует FFMPEG для замены звуковой дорожки в видео.

Основные компоненты

1. FFMPEG и FFPROBE

FFMPEG — это бесплатный инструмент с открытым исходным кодом для обработки видео и аудио. Он поддерживает множество функций, таких как конвертация форматов, редактирование видео, добавление и удаление звуковых дорожек. FFPROBE — это компонент FFMPEG, который позволяет получать информацию о мультимедийных файлах, например, продолжительность видео или аудио.

2. PHP для автоматизации

PHP — мощный язык серверной разработки, который можно использовать для выполнения команд FFMPEG и автоматизации обработки файлов на хостинге. Мы будем использовать PHP для поиска видео и аудио файлов, а также для выполнения команд FFMPEG через exec().

Подготовка окружения

Перед тем как приступить к написанию скрипта, убедитесь, что:

  • FFMPEG и FFPROBE установлены на вашем сервере или локальной машине.
  • PHP настроен для выполнения команд через exec().
  • Имеются видеофайлы (с расширением .mp4 или .MP4) и аудиофайлы (с расширением .mp3), которые будут использоваться для замены звуковой дорожки.

Пример структуры файлов:

  • Каталог audio/ содержит аудиофайлы.
  • Видео лежат в корневом каталоге.

Шаги реализации скрипта

1. Получение списка видеофайлов

Сначала необходимо получить список всех видеофайлов с расширением .mp4 или .MP4. Мы используем функцию glob() для поиска всех видеофайлов.

php
// Получаем все видеофайлы с расширениями .mp4 или .MP4 из корневого каталога
$videos = glob("*.mp4");
$videos = array_merge($videos, glob("*.MP4")); // добавляем файлы с заглавными буквами в расширении

2. Поиск соответствующего аудиофайла

Затем мы используем регулярное выражение для извлечения цифры в конце имени файла (перед расширением). Эта цифра используется для поиска соответствующего аудиофайла с таким же номером.

php
preg_match('/-(\d+)\.(mp4|MP4)$/', $video, $matches);
if (isset($matches[1])) {
$video_number = $matches[1]; // цифра из имени видеофайла
// Ищем соответствующий аудиофайл в каталоге /audio/
$audio_files = glob($audio_dir . "*.mp3"); // предположим, что аудиофайлы имеют расширение .mp3
$audio_file = null;
foreach ($audio_files as $audio) {
preg_match(‘/-(\d+)\.mp3$/’, $audio, $audio_matches);
if (isset($audio_matches[1]) && $audio_matches[1] == $video_number) {
$audio_file = $audio; // нашли нужный аудиофайл
break;
}
}
}

3. Получение длины аудиофайла

Для того чтобы выбрать случайное место начала аудиофайла, необходимо узнать его продолжительность. Для этого мы используем FFPROBE, который возвращает длину файла в секундах.

php
function getAudioDuration($audio_file, $ffprobe_path) {
$command = "$ffprobe_path -v error -show_entries format=duration -of csv=p=0 $audio_file";
$duration = exec($command);
return (float)$duration;
}

4. Выбор случайного времени старта

После того как мы получили длину аудиофайла, можем выбрать случайную точку старта с учётом того, что длина оставшейся части аудио должна покрыть длительность видео.

php
$audio_duration = getAudioDuration($audio_file, $ffprobe_path);
$random_start = 0;
if ($audio_duration > 5) { // минимальная длина аудио 5 секунд для случайного старта
$random_start = rand(0, (int)($audio_duration - 5)); // случайное время старта, чтобы остатка аудио хватило
}

5. Замена звуковой дорожки

Для замены звуковой дорожки мы используем FFMPEG. Параметр -ss указывает FFMPEG, с какого места аудиофайла начать проигрывание.

php
$command = "$ffmpeg_path -i $video -ss $random_start -i $audio_file -c:v copy -map 0:v:0 -map 1:a:0 -shortest $output_video";
exec($command, $output, $return_var);

6. Вывод результата

После выполнения команды FFMPEG проверяем, успешно ли была заменена звуковая дорожка, и выводим соответствующее сообщение.

php
if ($return_var === 0) {
echo "Звуковая дорожка для $video успешно заменена на $audio_file, начиная с $random_start секунд, и сохранена как $output_video.<br>";
} else {
echo "Ошибка при замене звуковой дорожки для $video.<br>";
}

Полный код скрипта

php
<?php
$audio_dir = 'audio/';
$ffmpeg_path = '/usr/bin/ffmpeg';
$ffprobe_path = '/usr/bin/ffprobe';
$videos = glob(«*.mp4»);
$videos = array_merge($videos, glob(«*.MP4»));function getAudioDuration($audio_file, $ffprobe_path) {
$command = «$ffprobe_path -v error -show_entries format=duration -of csv=p=0 $audio_file«;
$duration = exec($command);
return (float)$duration;
}foreach ($videos as $video) {
preg_match(‘/-(\d+)\.(mp4|MP4)$/’, $video, $matches);
if (isset($matches[1])) {
$video_number = $matches[1];
$audio_files = glob($audio_dir . «*.mp3»);
$audio_file = null;

foreach ($audio_files as $audio) {
preg_match(‘/-(\d+)\.mp3$/’, $audio, $audio_matches);
if (isset($audio_matches[1]) && $audio_matches[1] == $video_number) {
$audio_file = $audio;
break;
}
}

if ($audio_file) {
$audio_duration = getAudioDuration($audio_file, $ffprobe_path);
$random_start = 0;
if ($audio_duration > 5) {
$random_start = rand(0, (int)($audio_duration5));
}
$output_video = ‘output_’ . $video;
$command = «$ffmpeg_path -i $video -ss $random_start -i $audio_file -c:v copy -map 0:v:0 -map 1:a:0 -shortest $output_video«;
exec($command, $output, $return_var);

if ($return_var === 0) {
echo «Звуковая дорожка для $video успешно заменена на $audio_file, начиная с $random_start секунд, и сохранена как $output_video.<br>»;
} else {
echo «Ошибка при замене звуковой дорожки для $video.<br>»;
}
} else {
echo «Соответствующий аудиофайл для видео $video не найден.<br>»;
}
}
}
?>

Используя PHP и FFMPEG, вы можете легко автоматизировать процесс замены звуковых дорожек в видеофайлах. В данном скрипте применены такие возможности, как случайный старт аудиофайла и динамическая генерация выходных видео. Этот скрипт может быть полезен для обработки множества видео одновременно и добавления случайных элементов к звуковым эффектам.

Скачать готовый php файл

Как настроить соответствие номеров между видео и аудио файлами

В данном коде мы используем систематический подход к замене звуковых дорожек в видеофайлах на соответствующие аудиофайлы. Ключевым моментом является соответствие номеров в названиях файлов. Вот подробное объяснение того, как это устроено:

1. Структура файлов

  • Видео файлы: Имя видеофайла заканчивается на дефис и цифру перед расширением. Например: video-1.mp4, video-23.MP4.
  • Аудиофайлы: Имя аудиофайла также заканчивается на дефис и цифру перед расширением. Например: audio-1.mp3, audio-23.mp3.

2. Процесс соответствия

Шаг 1: Извлечение цифры из имени файла

Для каждого видеофайла и аудиофайла извлекается цифра, которая находится перед расширением файла. Это делается с помощью регулярных выражений.

php
preg_match('/-(\d+)\.(mp4|MP4)$/', $video, $matches);
if (isset($matches[1])) {
$video_number = $matches[1]; // цифра из имени видеофайла
}

Аналогично для аудиофайлов:

php
preg_match('/-(\d+)\.mp3$/', $audio, $audio_matches);
if (isset($audio_matches[1]) && $audio_matches[1] == $video_number) {
$audio_file = $audio; // нашли нужный аудиофайл
break;
}

Шаг 2: Соответствие аудио и видео файлов

Когда цифра из имени видеофайла совпадает с цифрой из имени аудиофайла, это означает, что данный аудиофайл предназначен для замены звуковой дорожки в этом видеофайле. Этот процесс обеспечивает, что аудиофайл будет правильно сопоставлен с видеофайлом на основе их номеров.

Шаг 3: Замена звуковой дорожки

После нахождения соответствующего аудиофайла для видеофайла, мы используем FFMPEG для замены звуковой дорожки, начиная с произвольного места в аудиофайле. Это выполняется с помощью команды:

php
$command = "$ffmpeg_path -i $video -ss $random_start -i $audio_file -c:v copy -map 0:v:0 -map 1:a:0 -shortest $output_video";

Здесь -ss $random_start указывает FFMPEG, с какого момента начать воспроизведение аудиофайла, что добавляет элемент случайности.

Полный процесс в коде

  1. Получение списка видеофайлов:
    • Функция glob() используется для получения всех видеофайлов в каталоге с расширениями .mp4 и .MP4.
  2. Поиск соответствующих аудиофайлов:
    • Для каждого видеофайла определяется соответствующий аудиофайл по совпадению цифры в названии. Аудиофайлы находятся в каталоге audio/ и проверяются на соответствие по номеру.
  3. Получение длины аудиофайла:
    • Используется ffprobe для определения длительности аудиофайла, чтобы правильно выбрать случайный стартовый момент.
  4. Выполнение команды FFMPEG:
    • Создаётся команда для замены звуковой дорожки, используя случайное время начала аудиофайла. Результат сохраняется в новый видеофайл.

Пример полного кода

php
<?php
// Каталог с аудиофайлами
$audio_dir = 'audio/';
// Путь к FFMPEG и FFPROBE
$ffmpeg_path = '/usr/bin/ffmpeg'; // проверьте, что путь к FFMPEG корректен
$ffprobe_path = '/usr/bin/ffprobe'; // проверьте, что путь к FFPROBE корректен
// Получаем все видеофайлы с расширениями .mp4 или .MP4 из корневого каталога
$videos = glob(«*.mp4»);
$videos = array_merge($videos, glob(«*.MP4»)); // добавляем файлы с заглавными буквами в расширении// Функция для получения длины аудиофайла в секундах с помощью ffprobe
function getAudioDuration($audio_file, $ffprobe_path) {
$command = «$ffprobe_path -v error -show_entries format=duration -of csv=p=0 $audio_file«;
$duration = exec($command);
return (float)$duration;
}

foreach ($videos as $video) {
// Извлекаем цифру с дефисом перед расширением видеофайла
preg_match(‘/-(\d+)\.(mp4|MP4)$/’, $video, $matches);
if (isset($matches[1])) {
$video_number = $matches[1]; // цифра из имени видеофайла

// Ищем соответствующий аудиофайл в каталоге /audio/
$audio_files = glob($audio_dir . «*.mp3»); // предположим, что аудиофайлы имеют расширение .mp3
$audio_file = null;

foreach ($audio_files as $audio) {
// Извлекаем цифру с дефисом перед расширением аудиофайла
preg_match(‘/-(\d+)\.mp3$/’, $audio, $audio_matches);
if (isset($audio_matches[1]) && $audio_matches[1] == $video_number) {
$audio_file = $audio; // нашли нужный аудиофайл
break;
}
}

// Если нашли соответствующий аудиофайл
if ($audio_file) {
// Получаем длину аудиофайла
$audio_duration = getAudioDuration($audio_file, $ffprobe_path);

// Получаем случайное время старта аудиофайла, чтобы хватило на видео (минус длина видео)
$random_start = 0;
if ($audio_duration > 5) { // минимальная длина аудио 5 секунд для случайного старта
$random_start = rand(0, (int)($audio_duration5)); // случайное время старта, чтобы остатка аудио хватило
}

// Генерируем имя для нового видео с замененной звуковой дорожкой
$output_video = ‘output_’ . $video;

// Формируем команду для FFMPEG, используя -ss для аудио, чтобы начать с произвольного места
$command = «$ffmpeg_path -i $video -ss $random_start -i $audio_file -c:v copy -map 0:v:0 -map 1:a:0 -shortest $output_video«;

// Выполняем команду
exec($command, $output, $return_var);

// Проверяем, успешно ли выполнена команда
if ($return_var === 0) {
echo «Звуковая дорожка для $video успешно заменена на $audio_file, начиная с $random_start секунд, и сохранена как $output_video.<br>»;
} else {
echo «Ошибка при замене звуковой дорожки для $video.<br>»;
}
} else {
echo «Соответствующий аудиофайл для видео $video не найден.<br>»;
}
}
}
?>

Заключение

Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
Кнопка «Наверх»