Failed Conditions
Push — master ( df4f19...50f2bb )
by Sébastien
02:46 queued 13s
created

ConverterService   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 88.46%

Importance

Changes 0
Metric Value
wmc 8
eloc 26
dl 0
loc 74
ccs 23
cts 26
cp 0.8846
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A convert() 0 11 4
A getConversionProcess() 0 28 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools\Video;
6
7
use Soluble\MediaTools\Config\FFMpegConfig;
8
use Soluble\MediaTools\Exception\FileNotFoundException;
9
use Soluble\MediaTools\Exception\ProcessConversionException;
10
use Soluble\MediaTools\Util\Assert\PathAssertionsTrait;
11
use Soluble\MediaTools\Video\Converter\ParamsInterface;
12
use Symfony\Component\Process\Exception as ProcessException;
13
use Symfony\Component\Process\Process;
14
15
class ConverterService implements ConverterServiceInterface
16
{
17
    use PathAssertionsTrait;
18
19
    /** @var FFMpegConfig */
20
    protected $ffmpegConfig;
21
22 5
    public function __construct(FFMpegConfig $ffmpegConfig)
23
    {
24 5
        $this->ffmpegConfig = $ffmpegConfig;
25 5
        $this->ffmpegConfig->getProcess()->ensureBinaryExists();
26 5
    }
27
28
    /**
29
     * Return ready-to-run symfony process object that you can use
30
     * to `run()` or `start()` programmatically. Useful if you want to make
31
     * things async...
32
     *
33
     * @see https://symfony.com/doc/current/components/process.html
34
     *
35
     * @throws FileNotFoundException when inputFile does not exists
36
     */
37 5
    public function getConversionProcess(string $inputFile, string $outputFile, ConvertParams $convertParams): Process
38
    {
39 5
        $this->ensureFileExists($inputFile);
40
41 4
        $process = $this->ffmpegConfig->getProcess();
42
43 4
        if (!$convertParams->hasOption(ParamsInterface::PARAM_THREADS) && $this->ffmpegConfig->getThreads() !== null) {
44
            $convertParams = $convertParams->withThreads($this->ffmpegConfig->getThreads());
45
        }
46
47 4
        $ffmpegCmd = $process->buildCommand(
48 4
            array_merge(
49
                [
50 4
                    sprintf('-i %s', escapeshellarg($inputFile)), // input filename
51
                ],
52 4
                $convertParams->getFFMpegArguments(),
53
                [
54 4
                    '-y', // tell to overwrite
55 4
                    sprintf('%s', escapeshellarg($outputFile)),
56
                ]
57
            )
58
        );
59
60 4
        $process = new Process($ffmpegCmd);
61 4
        $process->setTimeout($this->ffmpegConfig->getConversionTimeout());
62 4
        $process->setIdleTimeout($this->ffmpegConfig->getConversionIdleTimeout());
63
64 4
        return $process;
65
    }
66
67
    /**
68
     * Run a conversion, throw exception on error.
69
     *
70
     * @param callable|null                 $callback A PHP callback to run whenever there is some
71
     *                                                output available on STDOUT or STDERR
72
     * @param array<string,string|int>|null $env      An array of env vars to set
73
     *                                                when running the process
74
     *
75
     * @throws FileNotFoundException      When inputFile does not exists
76
     * @throws ProcessConversionException When the ffmpeg process conversion failed
77
     */
78 5
    public function convert(string $inputFile, string $outputFile, ConvertParams $convertParams, ?callable $callback = null, ?array $env = null): void
79
    {
80 5
        $process = $this->getConversionProcess($inputFile, $outputFile, $convertParams);
81
82
        try {
83 4
            $process->mustRun($callback, (is_array($env) ? $env : $this->ffmpegConfig->getConversionEnv()));
84 2
        } catch (ProcessException\RuntimeException $symfonyProcessException) {
85
            // will include: ProcessFailedException|ProcessTimedOutException|ProcessSignaledException
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
86 2
            throw new ProcessConversionException($process, $symfonyProcessException);
87
        } catch (FileNotFoundException $e) {
88
            throw $e;
89
        }
90 2
    }
91
92
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
93
     * FOR LATER REFERENCE !!!
94
    public function convertMultiPass(string $videoFile, string $outputFile, ConvertParams $convertParams, VideoFilterInterface $videoFilter=null): void {
95
96
        $this->ensureFileExists($videoFile);
97
        if ($videoFilter === null) {
98
            $videoFilter = new EmptyVideoFilter();
99
        }
100
101
102
        $threads = $convertParams->getOption(ConvertParams::OPTION_THREADS, $this->ffmpegConfig->getThreads());
103
104
        $ffmpegBin = $this->ffmpegConfig->getBinary();
105
106
        $commonArgs = array_merge([
107
                $ffmpegBin,
108
                sprintf('-i %s', escapeshellarg($videoFile)), // input filename
109
                $videoFilter->getFFMpegCliArgument(), // add -vf yadif,nlmeans
110
                ($threads === null) ? '' : sprintf('-threads %s', $threads),
111
        ], $convertParams->getFFMpegArguments());
112
113
        $pass1Cmd = implode(' ', array_merge(
114
            $commonArgs,
115
            [
116
                '-pass 1',
117
                // tells VP9 to encode really fast, sacrificing quality. Useful to speed up the first pass.
118
                '-speed 4',
119
                '-y /dev/null',
120
            ]
121
        ));
122
123
        $pass2Cmd = implode( ' ', array_merge(
124
            $commonArgs,
125
            [
126
                '-pass 2',
127
                // speed 1 is a good speed vs. quality compromise.
128
                // Produces output quality typically very close to speed 0, but usually encodes much faster.
129
                '-speed 1',
130
                '-y',
131
                sprintf("%s", escapeshellarg($outputFile))
132
            ]
133
        ));
134
135
136
        $process = new Process($pass1Cmd);
137
        $process->setTimeout(null);
138
        $process->setIdleTimeout(60); // 60 seconds without output will stop the process
139
        $process->start();
140
        foreach ($process as $type => $data) {
141
            if ($process::OUT === $type) {
142
                echo "\nRead from stdout: ".$data;
143
            } else { // $process::ERR === $type
144
                echo "\nRead from stderr: ".$data;
145
            }
146
        }
147
148
        $process = new Process($pass2Cmd);
149
        $process->setTimeout(null);
150
        $process->setIdleTimeout(60); // 60 seconds without output will stop the process
151
        $process->start();
152
        foreach ($process as $type => $data) {
153
            if ($process::OUT === $type) {
154
                echo "\nRead from stdout: ".$data;
155
            } else { // $process::ERR === $type
156
                echo "\nRead from stderr: ".$data;
157
            }
158
        }
159
160
    }
161
    */
162
}
163