Skip to content

Instantly share code, notes, and snippets.

@diego-miranda-ng
Last active November 22, 2019 18:32
Show Gist options
  • Save diego-miranda-ng/e58228afe459dd65fcc58fb5970d627f to your computer and use it in GitHub Desktop.
Save diego-miranda-ng/e58228afe459dd65fcc58fb5970d627f to your computer and use it in GitHub Desktop.
PHP-FFMPeg exemple in Laravel
<?php
namespace App\Jobs;
require_once __DIR__ . '/../../vendor/autoload.php';
use Illuminate\Support\Facades\Log;
use App\Interfaces\ModelInterface;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\File;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Storage;
/**
* Classe para processamento de vídeos em 480p.
*
* @copyright Grupo Monteiro de Barros
* @version 1.0
* @package \App\Jobs
*/
class ProcessVideo480PJob implements ShouldQueue {
use Dispatchable,
InteractsWithQueue,
Queueable,
SerializesModels;
/**
* Nome do arquivo a ser processado.
*
* @access private
* @var string
*/
private $file;
/**
* Nome da pasta em que os arquivos serão processados e armazenados.
*
* @access private
* @var string
*/
private $folder;
/**
* Instância do vídeo a ser processado.
*
* @access private
* @var ModelInterface
*/
private $model;
/**
* Cria uma nova instância do processo.
*
* @access public
* @param string $file Nome do arquivo.
* @param int $model Código de identificação do registro do video.
* @param string $folder Nome da pasta em que os arquivos serão processados e armazenados.
* @return void
*/
public function __construct (string $file, ModelInterface $model, string $folder = '') {
$this->file = $file;
$this->model = $model;
$this->folder = $folder;
}
/**
* Atualiza o estado de disponibilização do vídeo.
*
* @access private
* @param int $state Código que representa o estado de processamento do vídeo.
* @return void
*/
private function updateStatus (int $state) {
$this->model->state = $state;
$this->model->save();
}
/**
* Processa o arquivo de vídeo para a resolução 480p.
*
* @access private
* @return void
*/
private function process () {
$folder = $this->folder ?? 'videos';
$basePath = Storage::disk(env('FILESYSTEM_DRIVER', 'local'))
->getDriver()
->getAdapter()
->getPathPrefix();
$processPath = $basePath . "public/{$folder}/{$this->model->id}/720p";
$savePath = $basePath . "public/{$folder}";
$ffmpeg = \FFMpeg\FFMpeg::create([
'timeout' => 0,
'ffmpeg.threads' => 12
]);
if(!File::isDirectory("{$savePath}/{$this->model->id}/480p/"))
File::makeDirectory("{$savePath}/{$this->model->id}/480p/", 493, true);
$video = $ffmpeg->open("{$processPath}/{$this->file}");
$video->filters()
->resize(new \FFMpeg\Coordinate\Dimension(854, 480))
->synchronize();
$mp4Format = new \FFMpeg\Format\Video\X264();
$mp4Format->setAudioCodec("aac");
$mp4Format->setAdditionalParameters(['-vprofile', 'baseline', '-level', 3.0, '-movflags', '+faststart']);
$newFileName = explode('.', $this->file)[0] . '.mp4';
$video->save($mp4Format, "{$savePath}/{$this->model->id}/480p/{$newFileName}");
}
/**
* Executa o processo.
*
* @access public
* @return void
*/
public function handle () {
try {
$this->updateStatus(3);
$this->process();
$this->updateStatus(4);
}
catch (\Exception $e) {
Log::error($e->getMessage());
$this->updateStatus(-2);
}
}
}
?>
<?php
namespace App\Jobs;
require_once __DIR__ . '/../../vendor/autoload.php';
use Illuminate\Support\Facades\Log;
use App\Interfaces\ModelInterface;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\File;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Storage;
/**
* Classe para processamento de vídeos em 720p.
*
* @copyright Grupo Monteiro de Barros
* @version 1.0
* @package \App\Jobs
*/
class ProcessVideo720PJob implements ShouldQueue {
use Dispatchable,
InteractsWithQueue,
Queueable,
SerializesModels;
/**
* Nome do arquivo a ser processado.
*
* @access private
* @var string
*/
private $file;
/**
* Nome da pasta em que os arquivos serão processados e armazenados.
*
* @access private
* @var string
*/
private $folder;
/**
* Instância do vídeo a ser processado.
*
* @access private
* @var ModelInterface
*/
private $model;
/**
* Cria uma novainstância do processo.
*
* @access public
* @param string $file Nome do arquivo.
* @param int $model Código de identificação do registro do video.
* @param string $folder Nome da pasta em que os arquivos serão processados e armazenados.
* @return void
*/
public function __construct (string $file, ModelInterface $model, string $folder = '') {
$this->file = $file;
$this->model = $model;
$this->folder = $folder;
}
/**
* Atualiza o estado de disponibilização do vídeo.
*
* @access private
* @param int $state Código que representa o estado de processamento do vídeo.
* @return void
*/
private function updateStatus (int $state) {
$this->model->state = $state;
$this->model->save();
}
/**
* Processa o arquivo de vídeo para a resolução 720p.
*
* @access private
* @return void
*/
private function process () {
$folder = $this->folder ?? 'videos';
$basePath = Storage::disk(env('FILESYSTEM_DRIVER', 'local'))
->getDriver()
->getAdapter()
->getPathPrefix();
$processPath = $basePath . "{$folder}/processing";
$savePath = $basePath . "public/{$folder}";
$ffmpeg = \FFMpeg\FFMpeg::create([
'timeout' => 0,
'ffmpeg.threads' => 12
]);
if(!File::isDirectory("{$savePath}/{$this->model->id}/720p/"))
File::makeDirectory("{$savePath}/{$this->model->id}/720p/", 493, true);
$video = $ffmpeg->open("{$processPath}/{$this->model->id}/{$this->file}");
$video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(1))
->save("{$savePath}/{$this->model->id}/thumb.jpg");
$video->filters()
->resize(new \FFMpeg\Coordinate\Dimension(1280, 720))
->synchronize();
$mp4Format = new \FFMpeg\Format\Video\X264();
$mp4Format->setAudioCodec("aac");
$mp4Format->setAdditionalParameters(['-vprofile', 'baseline', '-level', 3.0, '-movflags', '+faststart']);
$newFileName = explode('.', $this->file)[0] . '.mp4';
$video->save($mp4Format, "{$savePath}/{$this->model->id}/720p/{$newFileName}");
File::deleteDirectory("{$processPath}/{$this->model->id}/");
$this->model->file = $newFileName;
$this->model->save();
}
/**
* Executa o processo.
*
* @access public
* @return void
*/
public function handle () {
try {
$this->updateStatus(2);
$this->process();
}
catch (\Exception $e) {
Log::error($e->getMessage());
$this->updateStatus(-1);
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment