Completed
Push — master ( e0e3f0...3077c0 )
by Sébastien
04:19
created

VideoInfoService   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 85.19%

Importance

Changes 0
Metric Value
wmc 6
eloc 30
dl 0
loc 67
ccs 23
cts 27
cp 0.8519
rs 10
c 0
b 0
f 0

3 Methods

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