for testing and deploying your application
for finding and fixing issues
for empowering human code reviews
<?php
declare(strict_types=1);
namespace Uxmp\Core\Component\Io\Transcoder;
use RuntimeException;
use Uxmp\Core\Component\Config\ConfigProviderInterface;
use Uxmp\Core\Component\Io\Lib\PopenWrapperInterface;
final class FfmpegTranscoder implements TranscoderInterface
{
private ?string $file_path = null;
public function __construct(
private readonly ConfigProviderInterface $configProvider,
private readonly PopenWrapperInterface $popenWrapper,
private string $codec,
private int $bitrate,
) {
}
public function setFilePath(string $file_path): self
$this->file_path = $file_path;
return $this;
/**
* @return resource
*/
public function getHandle()
$transcodingConfig = $this->configProvider->getTranscodingConfig();
if (!in_array($this->bitrate, $transcodingConfig['allowed_bitrates'], true)) {
$this->bitrate = $transcodingConfig['bitrate'];
if (!in_array($this->codec, $transcodingConfig['allowed_codecs'], true)) {
$this->codec = $transcodingConfig['codec'];
$command = sprintf(
'ffmpeg -i %s -vn -nostats -ar 44100 -ac 2 -b:a %dk -f %s pipe:1 2>/dev/null',
escapeshellarg((string)$this->file_path),
$this->bitrate,
escapeshellarg($this->codec),
);
$handle = $this->popenWrapper->run($command);
if ($handle === null) {
// throw dedicated exception
throw new RuntimeException();
return $handle;