Failed Conditions
Push — master ( 85c284...561f65 )
by Sébastien
02:44
created

FFMpegAdapter::getMappedConversionParams()   B

Complexity

Conditions 9
Paths 7

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9.732

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 35
ccs 19
cts 24
cp 0.7917
rs 8.0555
c 0
b 0
f 0
cc 9
nc 7
nop 1
crap 9.732
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools\Video\Converter;
6
7
use Soluble\MediaTools\Config\FFMpegConfig;
8
use Soluble\MediaTools\Exception\InvalidArgumentException;
9
use Soluble\MediaTools\Exception\UnsupportedParamException;
10
use Soluble\MediaTools\Exception\UnsupportedParamValueException;
11
use Soluble\MediaTools\Util\PlatformNullFile;
12
use Soluble\MediaTools\Video\ConversionParamsInterface;
13
use Soluble\MediaTools\Video\Filter\Type\FFMpegVideoFilterInterface;
14
15
class FFMpegAdapter implements AdapterInterface
16
{
17
    /** @var FFMpegConfig */
18
    protected $ffmpegConfig;
19
20 13
    public function __construct(FFMpegConfig $ffmpegConfig)
21
    {
22 13
        $this->ffmpegConfig = $ffmpegConfig;
23 13
    }
24
25
    /**
26
     * @return array<string, array<string, string>>
27
     */
28 10
    public function getParamsOptions(): array
29
    {
30
        return [
31 10
            ConversionParamsInterface::PARAM_OUTPUT_FORMAT => [
32
                'cli_pattern' => '-f %s',
33
            ],
34
35 10
            ConversionParamsInterface::PARAM_VIDEO_CODEC => [
36
                'cli_pattern' => '-c:v %s',
37
            ],
38 10
            ConversionParamsInterface::PARAM_VIDEO_BITRATE => [
39
                'cli_pattern' => '-b:v %s',
40
            ],
41 10
            ConversionParamsInterface::PARAM_VIDEO_MIN_BITRATE => [
42
                'cli_pattern' => '-minrate %s',
43
            ],
44 10
            ConversionParamsInterface::PARAM_VIDEO_MAX_BITRATE => [
45
                'cli_pattern' => '-maxrate %s',
46
            ],
47
48 10
            ConversionParamsInterface::PARAM_AUDIO_CODEC => [
49
                'cli_pattern' => '-c:a %s',
50
            ],
51 10
            ConversionParamsInterface::PARAM_AUDIO_BITRATE => [
52
                'cli_pattern' => '-b:a %s',
53
            ],
54 10
            ConversionParamsInterface::PARAM_PIX_FMT => [
55
                'cli_pattern' => '-pix_fmt %s',
56
            ],
57 10
            ConversionParamsInterface::PARAM_PRESET => [
58
                'cli_pattern' => '-preset %s',
59
            ],
60 10
            ConversionParamsInterface::PARAM_SPEED => [
61
                'cli_pattern' => '-speed %d',
62
            ],
63 10
            ConversionParamsInterface::PARAM_THREADS => [
64
                'cli_pattern' => '-threads %d',
65
            ],
66 10
            ConversionParamsInterface::PARAM_KEYFRAME_SPACING => [
67
                'cli_pattern' => '-g %d',
68
            ],
69 10
            ConversionParamsInterface::PARAM_QUALITY => [
70
                'cli_pattern' => '-quality %s',
71
            ],
72
73 10
            ConversionParamsInterface::PARAM_VIDEO_QUALITY_SCALE => [
74
                'cli_pattern' => '-qscale:v %d',
75
            ],
76
77 10
            ConversionParamsInterface::PARAM_CRF => [
78
                'cli_pattern' => '-crf %d',
79
            ],
80 10
            ConversionParamsInterface::PARAM_STREAMABLE => [
81
                'cli_pattern' => '-movflags +faststart',
82
            ],
83
84 10
            ConversionParamsInterface::PARAM_FRAME_PARALLEL => [
85
                'cli_pattern' => '-frame-parallel %s',
86
            ],
87 10
            ConversionParamsInterface::PARAM_TILE_COLUMNS => [
88
                'cli_pattern' => '-tile-columns %s',
89
            ],
90 10
            ConversionParamsInterface::PARAM_TUNE => [
91
                'cli_pattern' => '-tune %s',
92
            ],
93 10
            ConversionParamsInterface::PARAM_VIDEO_FILTER => [
94
                'cli_pattern' => '-vf %s',
95
            ],
96 10
            ConversionParamsInterface::PARAM_OVERWRITE_FILE => [
97
                'cli_pattern' => '-y',
98
            ],
99 10
            ConversionParamsInterface::PARAM_VIDEO_FRAMES => [
100
                'cli_pattern' => '-frames:v %d',
101
            ],
102 10
            ConversionParamsInterface::PARAM_FILTER => [
103
                'cli_pattern' => '-filter %s',
104
            ],
105 10
            ConversionParamsInterface::PARAM_NOAUDIO => [
106
                'cli_pattern' => '-an',
107
            ],
108
109 10
            ConversionParamsInterface::PARAM_SEEK_START => [
110
                'cli_pattern' => '-ss %s',
111
            ],
112
113 10
            ConversionParamsInterface::PARAM_SEEK_END => [
114
                'cli_pattern' => '-to %s',
115
            ],
116
        ];
117
    }
118
119
    /**
120
     * @return array<string, string>
121
     *
122
     * @throws UnsupportedParamException
123
     * @throws UnsupportedParamValueException
124
     */
125 10
    public function getMappedConversionParams(ConversionParamsInterface $conversionParams): array
126
    {
127 10
        $args             = [];
128 10
        $supportedOptions = $this->getParamsOptions();
129
130 10
        foreach ($conversionParams->toArray() as $paramName => $value) {
131 10
            if (!array_key_exists($paramName, $supportedOptions)) {
132
                throw new UnsupportedParamException(
133
                    sprintf(
134
                        'FFMpegAdapter does not support param \'%s\'',
135
                        $paramName
136
                    )
137
                );
138
            }
139 10
            $ffmpeg_pattern = $supportedOptions[$paramName]['cli_pattern'];
140 10
            if (is_bool($value)) {
141 3
                $args[$paramName] = $ffmpeg_pattern;
142 10
            } elseif ($value instanceof FFMpegCLIValueInterface) {
143 6
                $args[$paramName] = sprintf($ffmpeg_pattern, $value->getFFmpegCLIValue());
144 8
            } elseif ($value instanceof FFMpegVideoFilterInterface) {
145
                $args[$paramName] = sprintf($ffmpeg_pattern, $value->getFFmpegCLIValue());
146 8
            } elseif (is_string($value) || is_int($value)) {
147 7
                $args[$paramName] = sprintf($ffmpeg_pattern, $value);
148
            } else {
149 1
                throw new UnsupportedParamValueException(
150 1
                    sprintf(
151 1
                        'Param \'%s\' has an unsupported type: \'%s\'',
152 1
                        $paramName,
153 10
                        is_object($value) ? get_class($value) : gettype($value)
154
                    )
155
                );
156
            }
157
        }
158
159 9
        return $args;
160
    }
161
162
    /**
163
     * @param array<int|string, string>    $arguments
164
     * @param string|null                  $inputFile  if <null> will not prepend '-i inputFile' in args
165
     * @param null|string|PlatformNullFile $outputFile
166
     *
167
     * @throws InvalidArgumentException
168
     */
169 6
    public function getCliCommand(array $arguments, ?string $inputFile, $outputFile = null): string
170
    {
171 6
        $inputArg = ($inputFile !== null && $inputFile !== '')
172 6
                        ? sprintf('-i %s', escapeshellarg($inputFile))
173 6
                        : '';
174
175 6
        $outputArg = '';
176 6
        if ($outputFile instanceof PlatformNullFile) {
177 1
            $outputArg = $outputFile->getNullFile();
178 5
        } elseif (is_string($outputFile)) {
179 5
            $outputArg = sprintf('%s', escapeshellarg($outputFile));
180
        } elseif ($outputFile !== null) {
0 ignored issues
show
introduced by
The condition $outputFile !== null is always false.
Loading history...
181
            throw new InvalidArgumentException(sprintf(
182
                'Output file must be either a non empty string, null or PlatformNullFile (type %s)',
183
                gettype($outputFile)
184
            ));
185
        }
186
187 6
        $ffmpegCmd = trim(sprintf(
188 6
            '%s %s %s %s',
189 6
            $this->ffmpegConfig->getBinary(),
190 6
            $inputArg,
191 6
            implode(' ', $arguments),
192 6
            $outputArg
193
        ));
194
195 6
        return $ffmpegCmd;
196
    }
197
}
198