Failed Conditions
Push — master ( c7d56e...346462 )
by Sébastien
05:11
created

ScanCommand::execute()   C

Complexity

Conditions 11
Paths 71

Size

Total Lines 81
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 53
CRAP Score 11.0007

Importance

Changes 0
Metric Value
cc 11
eloc 55
nc 71
nop 2
dl 0
loc 81
ccs 53
cts 54
cp 0.9815
crap 11.0007
rs 6.8351
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @see       https://github.com/soluble-io/soluble-mediatools-cli for the canonical repository
7
 *
8
 * @copyright Copyright (c) 2018-2019 Sébastien Vanvelthem. (https://github.com/belgattitude)
9
 * @license   https://github.com/soluble-io/soluble-mediatools-cli/blob/master/LICENSE.md MIT
10
 */
11
12
namespace Soluble\MediaTools\Cli\Command;
13
14
use ScriptFUSION\Byte\ByteFormatter;
15
use Soluble\MediaTools\Cli\Exception\MissingFFProbeBinaryException;
16
use Soluble\MediaTools\Cli\FileSystem\DirectoryScanner;
17
use Soluble\MediaTools\Video\Exception as VideoException;
18
use Soluble\MediaTools\Video\SeekTime;
19
use Soluble\MediaTools\Video\VideoInfoReaderInterface;
20
use Symfony\Component\Console\Command\Command;
21
use Symfony\Component\Console\Helper\ProgressBar;
22
use Symfony\Component\Console\Helper\Table;
23
use Symfony\Component\Console\Helper\TableCell;
24
use Symfony\Component\Console\Helper\TableSeparator;
25
use Symfony\Component\Console\Helper\TableStyle;
26
use Symfony\Component\Console\Input\InputDefinition;
27
use Symfony\Component\Console\Input\InputInterface;
28
use Symfony\Component\Console\Input\InputOption;
29
use Symfony\Component\Console\Output\OutputInterface;
30
31
class ScanCommand extends Command
32
{
33
    /** @var VideoInfoReaderInterface */
34
    private $reader;
35
36
    /** @var string[] */
37
    private $supportedVideoExtensions = [
38
        'mov',
39
        'mp4',
40
        'm4v',
41
        'mkv',
42
        'flv',
43
        'webm',
44
    ];
45
46 4
    public function __construct(VideoInfoReaderInterface $videoInfoReader)
47
    {
48 4
        $this->reader = $videoInfoReader;
49 4
        parent::__construct();
50 4
    }
51
52
    /**
53
     * Configures the command.
54
     */
55 4
    protected function configure(): void
56
    {
57
        $this
58 4
            ->setName('scan:videos')
59 4
            ->setDescription('Scan for video')
60 4
            ->setDefinition(
61 4
                new InputDefinition([
62 4
                    new InputOption('dir', 'd', InputOption::VALUE_REQUIRED),
63
                ])
64
            );
65 4
    }
66
67 4
    protected function execute(InputInterface $input, OutputInterface $output): int
68
    {
69 4
        if (!$input->hasOption('dir')) {
70
            throw new \InvalidArgumentException('Missing dir argument, use <command> <dir>');
71
        }
72 4
        $videoPath = $input->hasOption('dir') ? $input->getOption('dir') : null;
73 4
        if (!is_string($videoPath) || !is_dir($videoPath)) {
74 2
            throw new \InvalidArgumentException(sprintf(
75 2
                'Video dir %s does not exists',
76 2
                is_string($videoPath) ? $videoPath : json_encode($videoPath)
77
            ));
78
        }
79
80 2
        $output->writeln(sprintf('* Scanning %s for files...', $videoPath));
81
82
        // Get the videos in path
83 2
        $videos = (new DirectoryScanner())->findFiles($videoPath, $this->supportedVideoExtensions);
84
85 2
        $output->writeln('* Reading metadata...');
86
87 2
        $progressBar = new ProgressBar($output, count($videos));
88 2
        $progressBar->start();
89
90 2
        $bitRateFormatter = new ByteFormatter();
91 2
        $sizeFormatter    = new ByteFormatter();
92
93 2
        $rows      = [];
94 2
        $warnings  = [];
95 2
        $totalSize = 0;
96
97
        /** @var \SplFileInfo $video */
98 2
        foreach ($videos as $video) {
99 2
            $videoFile = $video->getPathname();
100
            try {
101 2
                $info     = $this->reader->getInfo($videoFile);
102 1
                $vStream  = $info->getVideoStreams()->getFirst();
103 1
                $aStream  = $info->getAudioStreams()->getFirst();
104 1
                $pixFmt   = $vStream->getPixFmt();
105 1
                $bitRate  = $vStream->getBitRate();
106 1
                $fileSize = (int) filesize($videoFile);
107
                $row      = [
108 1
                    $video,
109 1
                    preg_replace('/\.([0-9])+$/', '', SeekTime::convertSecondsToHMSs(round($info->getDuration(), 1))),
110 1
                    sprintf('%s/%s', $vStream->getCodecName(), $aStream->getCodecName()),
111 1
                    sprintf('%sx%s', $vStream->getWidth(), $vStream->getHeight()),
112 1
                    ($bitRate > 0 ? $bitRateFormatter->format((int) $bitRate) . '/s' : ''),
113 1
                    $sizeFormatter->format($fileSize),
114 1
                    $pixFmt,
115
                ];
116 1
                $rows[] = $row;
117 1
                $totalSize += $fileSize;
118 2
            } catch (VideoException\MissingFFProbeBinaryException $e) {
119 1
                throw new MissingFFProbeBinaryException('Unable to run ffprobe binary, check your config and ensure it\'s properly installed');
120 1
            } catch (VideoException\InfoReaderExceptionInterface $e) {
121 1
                $warnings[] = [$videoFile];
122
            }
123
124 1
            $progressBar->advance();
125
        }
126 1
        $progressBar->finish();
127
128 1
        $output->writeln('');
129 1
        $output->writeln('* Available media files:');
130
131 1
        $this->renderResultsTable($output, $rows, $totalSize);
132
133
        // display warnings
134 1
        if (count($warnings) > 0) {
135 1
            $output->writeln('* The following files were not detected as valid medias:');
136 1
            $table = new Table($output);
137 1
            $table->setHeaders([
138 1
                'Unsupported files',
139
            ]);
140 1
            $table->setStyle('box-double');
141 1
            $table->setRows($warnings);
142 1
            $table->render();
143
        }
144
145 1
        $output->writeln('');
146
147 1
        return 0;
148
    }
149
150 1
    private function renderResultsTable(OutputInterface $output, array $rows, int $totalSize, array $columns = []): void
0 ignored issues
show
Unused Code introduced by
The parameter $columns is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

150
    private function renderResultsTable(OutputInterface $output, array $rows, int $totalSize, /** @scrutinizer ignore-unused */ array $columns = []): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
151
    {
152 1
        $sizeFormatter = new ByteFormatter();
153
154 1
        $table = new Table($output);
155
156 1
        $rightAlignstyle = new TableStyle();
157 1
        $rightAlignstyle->setPadType(STR_PAD_LEFT);
158
159
        //$table->setStyle($tableStyle);
160 1
        $table->setStyle('box');
161 1
        $table->setHeaders([
162 1
            'file',
163
            'duration',
164
            'codec',
165
            'size',
166
            'bitrate',
167
            'filesize',
168
            'pix_fmt',
169
        ]);
170
171 1
        foreach ($colIndexes = [1, 2, 3, 4, 5, 6] as $idx) {
0 ignored issues
show
Unused Code introduced by
The assignment to $colIndexes is dead and can be removed.
Loading history...
172 1
            $table->setColumnStyle($idx, $rightAlignstyle);
173
        }
174
175 1
        $previousPath = null;
176 1
        $first        = true;
177
178 1
        foreach ($rows as $row) {
179
            /** @var \SplFileInfo $file */
180 1
            $file   = $row[0];
181 1
            $fileName = $file->getBasename();
182 1
            $fileName = strlen($fileName) > 30 ? substr($file->getBasename(),0,30)."[...].".$file->getExtension() : $fileName;
183 1
            $row[0] = $fileName;
184 1
            if ($previousPath !== $file->getPath()) {
185 1
                if (!$first) {
186
                    $table->addRow(new TableSeparator(['colspan' => count($row)]));
187
                }
188 1
                $table->addRow([new TableCell(sprintf('<fg=yellow>%s</>', $file->getPath()), ['colspan' => count($row)])]);
189 1
                $table->addRow(new TableSeparator(['colspan' => count($row)]));
190 1
                $previousPath = $file->getPath();
191
            }
192 1
            $table->addRow($row);
193 1
            $first = false;
194
        }
195
196 1
        $table->addRow(new TableSeparator());
197 1
        $table->addRow(['<fg=cyan>Total</>', '', '', '', '', sprintf('<fg=cyan>%s</>', $sizeFormatter->format($totalSize))]);
198
199 1
        $table->render();
200 1
    }
201
}
202