Transcoder
[IN PROGRESS] Tools to transcoding/encoding audio or video, inspect and convert media formats.
Install / Use
/learn @jack-theripper/TranscoderREADME
Transcoder 
Tools to transcoding/encoding audio or video, inspect and convert media formats.
Инструмент для кодирования аудио или видео, получения информации и конвертирования в другие форматы.
Содержание
С чего начать
В зависимости от контента, вы можете использовать Audio для работы с аудио-файлами, Frame для изображений, а Video и Subtitle соответственно для работы с видео-файлами и субтитрами.
use Arhitector\Transcoder\Audio;
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Frame;
use Arhitector\Transcoder\Subtitle;
Конструктор в общем виде выглядит так:
public < ... >::__construct(string $filePath, ServiceFactoryInterface $service = null)
$filePath - строка, путь до исходного файла.
Вы не можете использовать удаленный источник или символические ссылки.
$service - параметр не обязателен. Экземпляр сервиса. По умолчанию ServiceFactory.
$audio = new Audio('sample.mp3');
$video = new Video('sample.avi');
$frame = new Frame('sample.jpg');
$subtitle = new Subtitle('sample.srt');
Вы можете использовать свою сервис-фабрику или изменить некоторые опции.
use Arhitector\Transcoder\Service\ServiceFactory;
$service = new ServiceFactory([
'ffprobe.path' => 'E:\devtools\bin\ffprobe.exe',
'ffmpeg.path' => 'E:\devtools\bin\ffmpeg.exe'
]);
// используем это
$video = new Video('sample.avi', $service);
Установка
$ composer require --prefer-dist arhitector/transcoder dev-master
Требования
- PHP >= 5.6
- Установленный FFMpeg
События
Экземпляр формата регистрирует обработчики, такой обработчик будет выполнен при наступлении определённого события.
Методы addListener или addOneListener регистрируют обработчик на событие. Читать подробнее League\Event.
$format = new VideoFormat();
$format->addListener('*', function ($event) {
// "*" - обработчик сработает на любое событие
});
В зависимости от события, обработчик может повлиять на дальнейший ход выполнения операции.
$format->addListener('before', function ($event) {
$event->stopPropagation(); // дальнейшее выполнение будет остановлено
});
Событие before
Выполняется перед началом кодирования. Дальнейшее выполнение может быть остановлено.
$format->addListener('before', function ($event, $media, $format, $filePath) {
// обработчик сработает после вызова `$media->save($format, ...`
});
Событие before.pass
При многопроходном кодировании обработчик будет вызван перед каждым проходом. Событие срабатывает минимум 1 раз.
Событие срабатывает после before и не может отменить процесс кодирования.
use Symfony\Component\Process\Process;
$format->addListener('before.pass', function ($event, $media, $format, Process $process) {
});
Событие before.queue
Событие successful
Событие наступает в том случае, если кодирование завершино без ошибок. При использовании очередей - в том случае, если задание добавлено в очередь.
$format->addListener('successful', function ($event, $media, $format, $filePath) {
// работа завершена без ошибок
});
Событие failure
Операция завершилась с ошибкой или не может корректно завершиться.
use Symfony\Component\Process\Exception\ProcessFailedException;
$format->addListener('failure', function ($event, ProcessFailedException $exception) {
// кодирование не может быть завершено из-за возникшей ошибки
});
Событие failure.codec
Событие after
Обработчик будет вызван когда операция завершится, не зависимо от того была ли операция завершена успешно или нет.
$format->addListener('after', function ($event, $media, $format, $filePath) {
// операция завершилась, но мы не знаем успешно или нет
});
Событие after.pass
Срабатывает после завершения прохода при многопроходном кодировании. Будет вызвано минимум 1 раз.
use Symfony\Component\Process\Process;
$format->addListener('after.pass', function ($event, $media, $format, Process $process) {
});
Событие after.queue
Событие progress
Событие наступает во время выполнения операции кодирования.
use Arhitector/Transcoder/Event/EventProgress;
$format->addListener('progress', function (EventProgress $event) {
// $event->getPercent();
});
Событие stream
Поддержка очередей
Вместо прямого транскодирования вы можете отправлять задачи в очередь, например, на сервер очередей. Такой функционал
доступен прямо из коробки. Вы можете использовать опцию ServiceFactoryInterface::OPTION_USE_QUEUE при создании сервис-фабрики.
Читать подробнее SimpleQueue.
Пример
$adapter = new SimpleQueue\Adapter\MemoryQueueAdapter();
$queue = new SimpleQueue\Queue($queue);
$service = new Arhitector\Transcoder\Service\ServiceFactory([
Arhitector\Transcoder\Service\ServiceFactory::OPTION_USE_QUEUE => $queue
]);
$audio = new Arhitector\Transcoder\Audio('sample.mp3', $service);
// задача будет отправлена в очередь `$queue`
$audio->save($audio->getFormat(), 'new-sample.mp3');
var_dump($queue->pull()); // запросить задачу из очереди
Что можно настроить? Поддерживаемые опции
Опции сервис-фабрики
Вы можете использовать свою реализацию сервис-фабрики. Для этого необходимо реализовать интерфейс Arhitector\Transcoder\Service\ServiceFactoryInterface.
ServiceFactory поддерживает следующие опции:
-
ffmpeg.path- путь до исполняемого файла ffmpeg -
ffmpeg.threads- FFMpeg-опция threads. По умолчанию0. -
ffprobe.path- путь до исполняемого файла ffprobe -
timeout- задаёт таймаут выполнения команды кодирования. -
use_queue- Отправляет задачу в очередь. Значение должно быть объектом, реализующимSimpleQueue\QueueAdapterInterface.
Примеры
Извлечение информации из видео файла, аудио файла и т.д.
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Audio;
$video = new Video('sample.avi');
var_dump($video->getWidth(), $video->getHeight());
$audio = new Audio(__DIR__.'/audio.mp3', $factory);
var_dump($audio->getAudioChannels());
var_dump($audio->getFormat()->getTags());
Извлечение звука из видео файла с последующим сохранением в формате MP3
Этот простой пример показывает лишь принцип, таким же способом можно сохранить субтитры или обложку из Mp3-файла и т.д.
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Stream\AudioStreamInterface;
use Arhitector\Transcoder\Format\Mp3;
$video = new Video('sample.mp4');
foreach ($video->getStreams() as $stream)
{
// тут выбираем только аудио канал
if ($stream instanceof AudioStreamInterface)
{
$stream->save(new Mp3(), __DIR__.'/only-audio.mp3');
break; // видео может иметь несколько аудио потоков
}
}
Преобразование из одного формата в любой другой
use Arhitector\Transcoder\Audio;
use Arhitector\Transcoder\Format\Mp3;
$audio = new Audio('audio-file.wav');
$audio->save(new Mp3(), 'audio-file.mp3');
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Format\VideoFormat;
$video = new Video('video-file.avi');
$video->save(new VideoFormat('aac', 'h264'), 'video-file.mp4');
Добавление/Изменение мета-информации
use Arhitector\Transcoder\Audio;
$audio = new Audio('file.mp3');
$format = $audio->getFormat();
$format['artist'] = 'Новый артист';
$auiod->save($format, 'new-file.mp3');
Как добавить/изменить обложку MP3-файла?
use Arhitector\Transcoder\Audio;
use Arhitector\Transcoder\Frame;
$audio = new Audio(__DIR__.'/sample.mp3');
$streams = $audio->getStreams();
$new_cover = (new Frame(__DIR__.'/sample.jpg'))
->getStreams()
->getFirst();
// индекс `0` - аудио-дорожка, `1` - обложка.
$streams[1] = $new_cover;
$audio->save($audio->getFormat(), 'sample-with-new-cover.mp3');
Наложение текста
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Filter\Text;
use Arhitector\Transcoder\Point;
$filter = new Text('Наложение текста на кадр');
$filter->setSize(24);
$filter->setColor('red');
$filter->setPosition(new Point(100, 100));
$video = new Video('sample.mp4');
$video->addFilter($filter);
$video->save($video->getFormat(), 'sample-with-text.mp4');
ООП-обёртки над форматами
Такие обёртки (например, Mp3 или Jpeg и т.д.) созданы для удобства.
Изображения
- Png, Jpeg, Ppm, Bmp, Gif
Аудио-форматы
- Aac, Mp3, Oga, Flac
Видео-форматы
- Flv, Mkv
Фильтры
Фильтры необходимы для изменения исходного медиа контента. Могут иметь один или несколько входов и выходов, а также быть организованы в цепочки для изоляции некоторых фильтров друг от друга.
public TranscodeInterface::addFilter(FilterInterface $filter, $priority = 0);
Аудио фильтры реализуют интерфейс AudioFilterInterface и могут использоваться совместно только с Audio или Video.
Видео фильтры реализуют интерфейсы FrameFilterInterface или VideoFilterInterface, используются либо с Frame либо с Video.
// добавляем любой фильтр
$video->addFilter($filter);
// добавляем фильтр с приоритетом = 99.
$audio->a
