Tools to transcoding/encoding audio or video, inspect and convert media formats., (*1)
ΠΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π΄Π»Ρ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π°ΡΠ΄ΠΈΠΎ ΠΈΠ»ΠΈ Π²ΠΈΠ΄Π΅ΠΎ, ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΈ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΎΡΠΌΠ°ΡΡ., (*2)
Π‘ΠΎΠ΄Π΅ΡΠΆΠ°Π½ΠΈΠ΅
Π‘ ΡΠ΅Π³ΠΎ Π½Π°ΡΠ°ΡΡ
Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ°, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Audio
Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π°ΡΠ΄ΠΈΠΎ-ΡΠ°ΠΉΠ»Π°ΠΌΠΈ, Frame
Π΄Π»Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, Π° Video
ΠΈ Subtitle
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π²ΠΈΠ΄Π΅ΠΎ-ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΠΈ ΡΡΠ±ΡΠΈΡΡΠ°ΠΌΠΈ., (*3)
use Arhitector\Transcoder\Audio;
use Arhitector\Transcoder\Video;
use Arhitector\Transcoder\Frame;
use Arhitector\Transcoder\Subtitle;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Π² ΠΎΠ±ΡΠ΅ΠΌ Π²ΠΈΠ΄Π΅ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:, (*4)
public < ... >::__construct(string $filePath, ServiceFactoryInterface $service = null)
$filePath
- ΡΡΡΠΎΠΊΠ°, ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°., (*5)
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΠΈΡΡΠΎΡΠ½ΠΈΠΊ ΠΈΠ»ΠΈ ΡΠΈΠΌΠ²ΠΎΠ»ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ., (*6)
$service
- ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ Π½Π΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»Π΅Π½. ΠΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ServiceFactory
., (*7)
$audio = new Audio('sample.mp3');
$video = new Video('sample.avi');
$frame = new Frame('sample.jpg');
$subtitle = new Subtitle('sample.srt');
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ²ΠΎΡ ΡΠ΅ΡΠ²ΠΈΡ-ΡΠ°Π±ΡΠΈΠΊΡ ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠΏΡΠΈΠΈ., (*8)
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., (*9)
$format = new VideoFormat();
$format->addListener('*', function ($event) {
// "*" - ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° Π»ΡΠ±ΠΎΠ΅ ΡΠΎΠ±ΡΡΠΈΠ΅
});
Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΎΠ±ΡΡΠΈΡ, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠ²Π»ΠΈΡΡΡ Π½Π° Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠΈΠΉ Ρ
ΠΎΠ΄ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ., (*10)
$format->addListener('before', function ($event) {
$event->stopPropagation(); // Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ before
ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠ΅ΡΠ΅Π΄ Π½Π°ΡΠ°Π»ΠΎΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΠ°Π»ΡΠ½Π΅ΠΉΡΠ΅Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ., (*11)
$format->addListener('before', function ($event, $media, $format, $filePath) {
// ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΏΠΎΡΠ»Π΅ Π²ΡΠ·ΠΎΠ²Π° `$media->save($format, ...`
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ before.pass
ΠΡΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡ
ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ ΠΏΠ΅ΡΠ΅Π΄ ΠΊΠ°ΠΆΠ΄ΡΠΌ ΠΏΡΠΎΡ
ΠΎΠ΄ΠΎΠΌ.
Π‘ΠΎΠ±ΡΡΠΈΠ΅ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ 1 ΡΠ°Π·., (*12)
Π‘ΠΎΠ±ΡΡΠΈΠ΅ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΠΎΡΠ»Π΅ before
ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΎΡΠΌΠ΅Π½ΠΈΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ., (*13)
use Symfony\Component\Process\Process;
$format->addListener('before.pass', function ($event, $media, $format, Process $process) {
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ before.queue
Π‘ΠΎΠ±ΡΡΠΈΠ΅ successful
Π‘ΠΎΠ±ΡΡΠΈΠ΅ Π½Π°ΡΡΡΠΏΠ°Π΅Ρ Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠΈΠ½ΠΎ Π±Π΅Π· ΠΎΡΠΈΠ±ΠΎΠΊ.
ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΡΠ΅ΡΠ΅Π΄Π΅ΠΉ - Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ., (*14)
$format->addListener('successful', function ($event, $media, $format, $filePath) {
// ΡΠ°Π±ΠΎΡΠ° Π·Π°Π²Π΅ΡΡΠ΅Π½Π° Π±Π΅Π· ΠΎΡΠΈΠ±ΠΎΠΊ
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ failure
ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π·Π°Π²Π΅ΡΡΠΈΠ»Π°ΡΡ Ρ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ ΠΈΠ»ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ Π·Π°Π²Π΅ΡΡΠΈΡΡΡΡ., (*15)
use Symfony\Component\Process\Exception\ProcessFailedException;
$format->addListener('failure', function ($event, ProcessFailedException $exception) {
// ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΎ ΠΈΠ·-Π·Π° Π²ΠΎΠ·Π½ΠΈΠΊΡΠ΅ΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ failure.codec
Π‘ΠΎΠ±ΡΡΠΈΠ΅ after
ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ ΠΊΠΎΠ³Π΄Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π·Π°Π²Π΅ΡΡΠΈΡΡΡ, Π½Π΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΡΠΎΠ³ΠΎ Π±ΡΠ»Π° Π»ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π·Π°Π²Π΅ΡΡΠ΅Π½Π° ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΈΠ»ΠΈ Π½Π΅Ρ., (*16)
$format->addListener('after', function ($event, $media, $format, $filePath) {
// ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π·Π°Π²Π΅ΡΡΠΈΠ»Π°ΡΡ, Π½ΠΎ ΠΌΡ Π½Π΅ Π·Π½Π°Π΅ΠΌ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΈΠ»ΠΈ Π½Π΅Ρ
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ after.pass
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΡ
ΠΎΠ΄Π° ΠΏΡΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡ
ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ. ΠΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ΠΎ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ 1 ΡΠ°Π·., (*17)
use Symfony\Component\Process\Process;
$format->addListener('after.pass', function ($event, $media, $format, Process $process) {
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ after.queue
Π‘ΠΎΠ±ΡΡΠΈΠ΅ progress
Π‘ΠΎΠ±ΡΡΠΈΠ΅ Π½Π°ΡΡΡΠΏΠ°Π΅Ρ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ., (*18)
use Arhitector/Transcoder/Event/EventProgress;
$format->addListener('progress', function (EventProgress $event) {
// $event->getPercent();
});
Π‘ΠΎΠ±ΡΡΠΈΠ΅ stream
ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° ΠΎΡΠ΅ΡΠ΅Π΄Π΅ΠΉ
ΠΠΌΠ΅ΡΡΠΎ ΠΏΡΡΠΌΠΎΠ³ΠΎ ΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ Π·Π°Π΄Π°ΡΠΈ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π° ΡΠ΅ΡΠ²Π΅Ρ ΠΎΡΠ΅ΡΠ΅Π΄Π΅ΠΉ. Π’Π°ΠΊΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»
Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΠΏΡΡΠΌΠΎ ΠΈΠ· ΠΊΠΎΡΠΎΠ±ΠΊΠΈ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠΏΡΠΈΡ ServiceFactoryInterface::OPTION_USE_QUEUE
ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠ΅ΡΠ²ΠΈΡ-ΡΠ°Π±ΡΠΈΠΊΠΈ.
Π§ΠΈΡΠ°ΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ SimpleQueue., (*19)
ΠΡΠΈΠΌΠ΅Ρ, (*20)
$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
., (*21)
ServiceFactory
ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΎΠΏΡΠΈΠΈ:, (*22)
-
ffmpeg.path
- ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ffmpeg, (*23)
-
ffmpeg.threads
- FFMpeg-ΠΎΠΏΡΠΈΡ threads. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ 0
., (*24)
-
ffprobe.path
- ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ffprobe, (*25)
-
timeout
- Π·Π°Π΄Π°ΡΡ ΡΠ°ΠΉΠΌΠ°ΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ., (*26)
-
use_queue
- ΠΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ Π·Π°Π΄Π°ΡΡ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΠΈΠΌ SimpleQueue\QueueAdapterInterface
., (*27)
ΠΡΠΈΠΌΠ΅ΡΡ
ΠΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΈΠ· Π²ΠΈΠ΄Π΅ΠΎ ΡΠ°ΠΉΠ»Π°, Π°ΡΠ΄ΠΈΠΎ ΡΠ°ΠΉΠ»Π° ΠΈ Ρ.Π΄.
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-ΡΠ°ΠΉΠ»Π° ΠΈ Ρ.Π΄., (*28)
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 ΠΈ Ρ.Π΄.) ΡΠΎΠ·Π΄Π°Π½Ρ Π΄Π»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π°., (*29)
ΠΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
ΠΡΠ΄ΠΈΠΎ-ΡΠΎΡΠΌΠ°ΡΡ
ΠΠΈΠ΄Π΅ΠΎ-ΡΠΎΡΠΌΠ°ΡΡ
Π€ΠΈΠ»ΡΡΡΡ
Π€ΠΈΠ»ΡΡΡΡ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡ Π΄Π»Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅Π΄ΠΈΠ° ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ°. ΠΠΎΠ³ΡΡ ΠΈΠΌΠ΅ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Ρ
ΠΎΠ΄ΠΎΠ² ΠΈ Π²ΡΡ
ΠΎΠ΄ΠΎΠ², Π° ΡΠ°ΠΊΠΆΠ΅ Π±ΡΡΡ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°Π½Ρ Π² ΡΠ΅ΠΏΠΎΡΠΊΠΈ Π΄Π»Ρ ΠΈΠ·ΠΎΠ»ΡΡΠΈΠΈ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΡΠΈΠ»ΡΡΡΠΎΠ² Π΄ΡΡΠ³ ΠΎΡ Π΄ΡΡΠ³Π°., (*30)
public TranscodeInterface::addFilter(FilterInterface $filter, $priority = 0);
ΠΡΠ΄ΠΈΠΎ ΡΠΈΠ»ΡΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ AudioFilterInterface
ΠΈ ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Ρ Audio
ΠΈΠ»ΠΈ Video
., (*31)
ΠΠΈΠ΄Π΅ΠΎ ΡΠΈΠ»ΡΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ FrameFilterInterface
ΠΈΠ»ΠΈ VideoFilterInterface
, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π»ΠΈΠ±ΠΎ Ρ Frame
Π»ΠΈΠ±ΠΎ Ρ Video
., (*32)
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π»ΡΠ±ΠΎΠΉ ΡΠΈΠ»ΡΡΡ
$video->addFilter($filter);
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠΈΠ»ΡΡΡ Ρ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠΎΠΌ = 99.
$audio->addFilter($filter, 99);
ΠΡΠΎΡΡΠΎΠΉ ΡΠΈΠ»ΡΡΡ, SimpleFilter
ΠΡΠΎ ΡΠ°ΠΌΡΠΉ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΈΠ»ΡΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ ΡΠ²ΠΎΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄Π»Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ffmpeg
., (*33)
use Arhitector\Transcoder\Filter\SimpleFilter;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*34)
public SimpleFilter::__construct(array $parameters = [])
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ 'video_codec'., (*35)
$filter = new SimpleFilter([
'video_codec' => 'h264'
]);
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠ΅Ρ ΡΠ°Π½Π΅Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ., (*36)
$filter->setParameters([
'video_codec' => 'libx264'
]);
// ArrayAccess
$filter['video_codec'] = 'x264';
Π€ΠΈΠ»ΡΡΡ Cut
ΠΡΠ΄ΠΈΠΎ ΡΠΈΠ»ΡΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ±ΡΠ΅Π·Π°ΡΡ ΠΌΠ΅Π΄ΠΈΠ°-ΡΠ°ΠΉΠ» Π΄ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΡ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ., (*37)
use Arhitector\Transcoder\Filter\Cut;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*38)
public Cut::__construct(TimeInterval|int $start [, TimeInterval $duration = null])
ΠΡΠΈΠΌΠ΅Ρ β1, (*39)
ΠΡΠΎΠΏΡΡΡΠΈΡΡ 20 ΡΠ΅ΠΊΡΠ½Π΄ ΠΎΡ Π½Π°ΡΠ°Π»Π° ΠΈ ΡΠΎΡ
ΡΠ°Π½ΠΈΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ 60 ΡΠ΅ΠΊΡΠ½Π΄., (*40)
$filter = new Cut(new TimeInterval(20), new TimeInterval(60));
Π€ΠΈΠ»ΡΡΡ Volume
ΠΡΠ΄ΠΈΠΎ ΡΠΈΠ»ΡΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅Ρ Π³ΡΠΎΠΌΠΊΠΎΡΡΡ Π°ΡΠ΄ΠΈΠΎ ΠΏΠΎΡΠΎΠΊΠ°., (*41)
use \Arhitector\Transcoder\Filter\Volume;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*42)
public Volume::__construct(float $volume [, string $precision = null])
ΠΡΠΈΠΌΠ΅Ρ β1, (*43)
ΠΡΠΈΠΌΠ΅Ρ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΊΠ°ΠΊ ΡΠΌΠ΅Π½ΡΡΠΈΡΡ Π³ΡΠΎΠΌΠΊΠΎΡΡΡ Π°ΡΠ΄ΠΈΠΎ., (*44)
$filter = new Volume(0.5);
$filter = new Volume(1/2);
$filter = new Volume('6.0206dB');
ΠΡΠΈΠΌΠ΅Ρ β2, (*45)
Π£Π²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ ΠΌΠΎΡΠ½ΠΎΡΡΠΈ Π·Π²ΡΠΊΠ° Π½Π° 6 Π΄Π Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΠΎΡΠ½ΠΎΡΡΡΡ., (*46)
$filter = new Volume('6dB', Volume::PRECISION_FIXED);
Π€ΠΈΠ»ΡΡΡ Fade
Π€ΠΈΠ»ΡΡΡ Π½Π°ΠΊΠ»Π°Π΄ΡΠ²Π°Π΅Ρ ΡΡΡΠ΅ΠΊΡ Π·Π°ΡΡΡ
Π°Π½ΠΈΡ Π·Π²ΡΠΊΠ° Π½Π° Π°ΡΠ΄ΠΈΠΎ Π΄ΠΎΡΠΎΠΆΠΊΡ., (*47)
use \Arhitector\Transcoder\Filter\Fade;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*48)
public Fade::__construct(TimeInterval|int $startTime = 0 [, TimeInterval|int $duration = null [, string $effectType = null]])
ΠΡΠΈΠΌΠ΅Ρ β1, (*49)
new Fade(2, 10, Fade::FADE_OUT)
Π€ΠΈΠ»ΡΡΡ AudioDelay
use \Arhitector\Transcoder\Filter\AudioDelay;
Π€ΠΈΠ»ΡΡΡ Rotate
use \Arhitector\Transcoder\Filter\Rotate;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*50)
public Rotate::__construct($angle = null)
Π€ΠΈΠ»ΡΡΡ Crop
use \Arhitector\Transcoder\Filter\Crop;
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, (*51)
public Crop::__construct(Point $start, Dimension $dimension)
ΠΠΈΡΠ΅Π½Π·ΠΈΡ
Π Π°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ Π»ΠΈΡΠ΅Π½Π·ΠΈΠ΅ΠΉ MIT., (*52)
Copyright (c) 2017 Dmitry Arhitector
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.