Создание скрипта для замены звуковой дорожки в видео
Сегодня автоматизация работы с мультимедийными файлами играет важную роль для разработчиков, особенно когда речь идет о видео и звуке. Один из распространенных сценариев — это замена звуковой дорожки в видео на другую, при этом аудиофайл может начинаться с произвольного момента. В данной статье мы рассмотрим, как это реализовать с помощью PHP и FFMPEG, включая случайный старт аудиофайла.
Мы создадим PHP-скрипт, который:
- Находит видеофайлы с определенным шаблоном имен.
- Находит соответствующий аудиофайл.
- Случайным образом выбирает стартовую точку для аудио.
- Использует 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()
для поиска всех видеофайлов.
// Получаем все видеофайлы с расширениями .mp4 или .MP4 из корневого каталога
$videos = glob("*.mp4");
$videos = array_merge($videos, glob("*.MP4")); // добавляем файлы с заглавными буквами в расширении
2. Поиск соответствующего аудиофайла
Затем мы используем регулярное выражение для извлечения цифры в конце имени файла (перед расширением). Эта цифра используется для поиска соответствующего аудиофайла с таким же номером.
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, который возвращает длину файла в секундах.
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. Выбор случайного времени старта
После того как мы получили длину аудиофайла, можем выбрать случайную точку старта с учётом того, что длина оставшейся части аудио должна покрыть длительность видео.
$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, с какого места аудиофайла начать проигрывание.
$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 проверяем, успешно ли была заменена звуковая дорожка, и выводим соответствующее сообщение.
if ($return_var === 0) {
echo "Звуковая дорожка для $video успешно заменена на $audio_file, начиная с $random_start секунд, и сохранена как $output_video.<br>";
} else {
echo "Ошибка при замене звуковой дорожки для $video.<br>";
}
Полный код скрипта
$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_duration — 5));
}
$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: Извлечение цифры из имени файла
Для каждого видеофайла и аудиофайла извлекается цифра, которая находится перед расширением файла. Это делается с помощью регулярных выражений.
preg_match('/-(\d+)\.(mp4|MP4)$/', $video, $matches);
if (isset($matches[1])) {
$video_number = $matches[1]; // цифра из имени видеофайла
}
Аналогично для аудиофайлов:
preg_match('/-(\d+)\.mp3$/', $audio, $audio_matches);
if (isset($audio_matches[1]) && $audio_matches[1] == $video_number) {
$audio_file = $audio; // нашли нужный аудиофайл
break;
}
Шаг 2: Соответствие аудио и видео файлов
Когда цифра из имени видеофайла совпадает с цифрой из имени аудиофайла, это означает, что данный аудиофайл предназначен для замены звуковой дорожки в этом видеофайле. Этот процесс обеспечивает, что аудиофайл будет правильно сопоставлен с видеофайлом на основе их номеров.
Шаг 3: Замена звуковой дорожки
После нахождения соответствующего аудиофайла для видеофайла, мы используем FFMPEG для замены звуковой дорожки, начиная с произвольного места в аудиофайле. Это выполняется с помощью команды:
$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, с какого момента начать воспроизведение аудиофайла, что добавляет элемент случайности.
Полный процесс в коде
- Получение списка видеофайлов:
- Функция
glob()
используется для получения всех видеофайлов в каталоге с расширениями.mp4
и.MP4
.
- Функция
- Поиск соответствующих аудиофайлов:
- Для каждого видеофайла определяется соответствующий аудиофайл по совпадению цифры в названии. Аудиофайлы находятся в каталоге
audio/
и проверяются на соответствие по номеру.
- Для каждого видеофайла определяется соответствующий аудиофайл по совпадению цифры в названии. Аудиофайлы находятся в каталоге
- Получение длины аудиофайла:
- Используется
ffprobe
для определения длительности аудиофайла, чтобы правильно выбрать случайный стартовый момент.
- Используется
- Выполнение команды FFMPEG:
- Создаётся команда для замены звуковой дорожки, используя случайное время начала аудиофайла. Результат сохраняется в новый видеофайл.
Пример полного кода
// Каталог с аудиофайлами
$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»)); // добавляем файлы с заглавными буквами в расширении
// Функция для получения длины аудиофайла в секундах с помощью ffprobefunction 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_duration — 5)); // случайное время старта, чтобы остатка аудио хватило
}
// Генерируем имя для нового видео с замененной звуковой дорожкой
$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>»;
}
}
}