Passed
Push — main ( 42ad98...b86851 )
by Daniel
04:42
created

FfmpegTranscoder   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 69
rs 10
ccs 25
cts 25
cp 1
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setFilePath() 0 4 1
A getHandle() 0 31 5
A __construct() 0 6 1
A __invoke() 0 9 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Uxmp\Core\Component\Io\Transcoder;
6
7
use RuntimeException;
8
use Uxmp\Core\Component\Config\ConfigProviderInterface;
9
use Uxmp\Core\Component\Io\Lib\PopenWrapperInterface;
10
11
final class FfmpegTranscoder implements TranscoderInterface
12
{
13
    /** @var null|resource  */
14
    private $handle;
15
16
    private ?string $file_path = null;
17
18 3
    public function __construct(
19
        private readonly ConfigProviderInterface $configProvider,
20
        private readonly PopenWrapperInterface $popenWrapper,
21
        private string $codec,
22
        private int $bitrate,
23
    ) {
24
    }
25
26 2
    public function setFilePath(string $file_path): self
27
    {
28 2
        $this->file_path = $file_path;
29 2
        return $this;
30
    }
31
32
    /**
33
     * @return resource
34
     */
35 2
    private function getHandle()
36
    {
37 2
        if ($this->handle === null) {
38 2
            $transcodingConfig = $this->configProvider->getTranscodingConfig();
39
40 2
            if (!in_array($this->bitrate, $transcodingConfig['allowed_bitrates'], true)) {
41 1
                $this->bitrate = $transcodingConfig['bitrate'];
42
            }
43
44 2
            if (!in_array($this->codec, $transcodingConfig['allowed_codecs'], true)) {
45 1
                $this->codec = $transcodingConfig['codec'];
46
            }
47
48 2
            $command = sprintf(
49
                'ffmpeg -i %s -vn -nostats -ar 44100 -ac 2 -b:a %dk -f %s pipe:1 2>/dev/null',
50 2
                escapeshellarg((string)$this->file_path),
51 2
                $this->bitrate,
52 2
                escapeshellarg($this->codec),
53
            );
54
55 2
            $handle = $this->popenWrapper->run($command);
56
57 2
            if ($handle === null) {
58
                // throw dedicated exception
59 1
                throw new RuntimeException();
60
            }
61
62 1
            $this->handle = $handle;
63
        }
64
65 1
        return $this->handle;
66
    }
67
68
    /**
69
     * @param int<0, max> $length
70
     */
71 2
    public function __invoke(int $length): string|false
72
    {
73 2
        $chunk = fread($this->getHandle(), $length);
74
75 1
        if ($chunk !== false && $chunk !== '') {
76 1
            return $chunk;
77
        }
78
79 1
        return false;
80
    }
81
}
82