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

VideoThumbService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools;
6
7
use Soluble\MediaTools\Config\FFMpegConfigInterface;
8
use Soluble\MediaTools\Exception\FileNotFoundException;
9
use Soluble\MediaTools\Exception\UnsupportedParamException;
10
use Soluble\MediaTools\Exception\UnsupportedParamValueException;
11
use Soluble\MediaTools\Util\Assert\PathAssertionsTrait;
12
use Soluble\MediaTools\Video\Converter\FFMpegAdapter;
13
use Soluble\MediaTools\Video\Exception\ConversionExceptionInterface;
14
use Soluble\MediaTools\Video\Exception\ConversionProcessExceptionInterface;
15
use Soluble\MediaTools\Video\Exception\InvalidParamException;
16
use Soluble\MediaTools\Video\Exception\MissingInputFileException;
17
use Soluble\MediaTools\Video\Exception\ProcessFailedException;
18
use Soluble\MediaTools\Video\Exception\ProcessSignaledException;
19
use Soluble\MediaTools\Video\Exception\ProcessTimeOutException;
20
use Soluble\MediaTools\Video\Exception\RuntimeException;
21
use Soluble\MediaTools\Video\Filter\Type\VideoFilterInterface;
22
use Soluble\MediaTools\Video\SeekTime;
23
use Soluble\MediaTools\Video\ThumbServiceInterface;
24
use Symfony\Component\Process\Exception as SPException;
25
use Symfony\Component\Process\Process;
26
27
class VideoThumbService implements ThumbServiceInterface
28
{
29
    use PathAssertionsTrait;
30
31
    /** @var FFMpegConfigInterface */
32
    protected $ffmpegConfig;
33
34
    /** @var FFMpegAdapter */
35
    protected $adapter;
36
37 3
    public function __construct(FFMpegConfigInterface $ffmpegConfig)
38
    {
39 3
        $this->ffmpegConfig = $ffmpegConfig;
40 3
        $this->adapter      = new FFMpegAdapter($ffmpegConfig);
41 3
    }
42
43
    /**
44
     * Return ready-to-run symfony process object that you can use
45
     * to `run()` or `start()` programmatically. Useful if you want
46
     * handle the process your way...
47
     *
48
     * @see https://symfony.com/doc/current/components/process.html
49
     *
50
     * @throws UnsupportedParamException
51
     * @throws UnsupportedParamValueException
52
     */
53 2
    public function getSymfonyProcess(string $videoFile, string $thumbnailFile, ?SeekTime $time = null, ?VideoFilterInterface $videoFilter = null): Process
54
    {
55 2
        $params = (new VideoConversionParams());
56
57 2
        if ($time !== null) {
58
            // For performance reasons time seek must be
59
            // made at the beginning of options
60 2
            $params = $params->withSeekStart($time);
61
        }
62 2
        $params = $params->withVideoFrames(1);
63
64 2
        if ($videoFilter !== null) {
65 1
            $params = $params->withVideoFilter($videoFilter);
66
        }
67
68
        // Quality scale for the mjpeg encoder
69 2
        $params->withVideoQualityScale(2);
70
71 2
        $arguments = $this->adapter->getMappedConversionParams($params);
72 2
        $ffmpegCmd = $this->adapter->getCliCommand($arguments, $videoFile, $thumbnailFile);
73
74 2
        $process = new Process($ffmpegCmd);
75 2
        $process->setTimeout($this->ffmpegConfig->getTimeout());
76 2
        $process->setIdleTimeout($this->ffmpegConfig->getIdleTimeout());
77 2
        $process->setEnv($this->ffmpegConfig->getEnv());
78
79 2
        return $process;
80
    }
81
82
    /**
83
     * @throws ConversionExceptionInterface        Base exception class for conversion exceptions
84
     * @throws ConversionProcessExceptionInterface Base exception class for process conversion exceptions
85
     * @throws MissingInputFileException
86
     * @throws ProcessTimeOutException
87
     * @throws ProcessFailedException
88
     * @throws ProcessSignaledException
89
     * @throws RuntimeException
90
     * @throws InvalidParamException
91
     */
92 3
    public function makeThumbnail(string $videoFile, string $thumbnailFile, ?SeekTime $time = null, ?VideoFilterInterface $videoFilter = null, ?callable $callback = null): void
93
    {
94
        try {
95 3
            $this->ensureFileExists($videoFile);
96
97 2
            $process = $this->getSymfonyProcess($videoFile, $thumbnailFile, $time, $videoFilter);
98 2
            $process->mustRun($callback);
99 1
        } catch (FileNotFoundException $e) {
100 1
            throw new MissingInputFileException($e->getMessage());
101
        } catch (UnsupportedParamValueException | UnsupportedParamException $e) {
102
            throw new InvalidParamException($e->getMessage());
103
        } catch (SPException\ProcessTimedOutException $e) {
104
            throw new ProcessTimeOutException($e->getProcess(), $e);
105
        } catch (SPException\ProcessSignaledException $e) {
106
            throw new ProcessSignaledException($e->getProcess(), $e);
107
        } catch (SPException\ProcessFailedException $e) {
108
            throw new ProcessFailedException($e->getProcess(), $e);
109
        } catch (SPException\RuntimeException $e) {
110
            throw new RuntimeException($e->getMessage());
111
        }
112 2
    }
113
}
114