Passed
Push — master ( bf86e6...5ea322 )
by Sébastien
07:21
created

InfoService   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 67
rs 10
c 0
b 0
f 0
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getFFProbeProcess() 0 20 1
A __construct() 0 3 1
A getInfo() 0 17 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools\Video;
6
7
use Soluble\MediaTools\Common\Assert\PathAssertionsTrait;
8
use Soluble\MediaTools\Common\Exception\FileNotFoundException;
9
use Soluble\MediaTools\Config\FFProbeConfigInterface;
10
use Soluble\MediaTools\Video\Exception\InfoExceptionInterface;
11
use Soluble\MediaTools\Video\Exception\InfoProcessExceptionInterface;
12
use Soluble\MediaTools\Video\Exception\MissingInputFileException;
13
use Soluble\MediaTools\Video\Exception\ProcessFailedException;
14
use Soluble\MediaTools\Video\Exception\RuntimeException;
15
use Symfony\Component\Process\Exception as SPException;
16
use Symfony\Component\Process\Process;
17
18
class InfoService implements InfoServiceInterface
19
{
20
    use PathAssertionsTrait;
21
22
    /** @var FFProbeConfigInterface */
23
    protected $ffprobeConfig;
24
25
    public function __construct(FFProbeConfigInterface $ffProbeConfig)
26
    {
27
        $this->ffprobeConfig = $ffProbeConfig;
28
    }
29
30
    /**
31
     * Return ready-to-run symfony process object that you can use
32
     * to `run()` or `start()` programmatically. Useful if you want to make
33
     * things your way...
34
     *
35
     * @see https://symfony.com/doc/current/components/process.html
36
     *
37
     * @throws FileNotFoundException when inputFile does not exists
38
     */
39
    public function getFFProbeProcess(string $inputFile): Process
40
    {
41
        $ffprobeCmd = trim(sprintf(
42
            '%s %s %s',
43
            $this->ffprobeConfig->getBinary(),
44
            implode(' ', [
45
                '-v quiet',
46
                '-print_format json',
47
                '-show_format',
48
                '-show_streams',
49
            ]),
50
            sprintf('-i %s', escapeshellarg($inputFile))
51
        ));
52
53
        $process = new Process($ffprobeCmd);
54
        $process->setTimeout($this->ffprobeConfig->getTimeout());
55
        $process->setIdleTimeout($this->ffprobeConfig->getIdleTimeout());
56
        $process->setEnv($this->ffprobeConfig->getEnv());
57
58
        return $process;
59
    }
60
61
    /**
62
     * @throws InfoExceptionInterface
63
     * @throws InfoProcessExceptionInterface
64
     * @throws ProcessFailedException
65
     * @throws MissingInputFileException
66
     * @throws RuntimeException
67
     */
68
    public function getInfo(string $file): Info
69
    {
70
        try {
71
            $this->ensureFileExists($file);
72
            $process = $this->getFFProbeProcess($file);
73
74
            $process->mustRun();
75
            $output = $process->getOutput();
76
        } catch (FileNotFoundException $e) {
77
            throw new MissingInputFileException($e->getMessage());
78
        } catch (SPException\ProcessFailedException | SPException\ProcessTimedOutException | SPException\ProcessSignaledException $e) {
79
            throw new ProcessFailedException($e->getProcess(), $e);
80
        } catch (SPException\RuntimeException $e) {
81
            throw new RuntimeException($e->getMessage());
82
        }
83
84
        return Info::createFromFFProbeJson($file, $output);
85
    }
86
}
87