Completed
Push — master ( b27393...e96bfd )
by C
12:21
created

ConvertSoundCommand::execute()   C

Complexity

Conditions 11
Paths 38

Size

Total Lines 64
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 11

Importance

Changes 0
Metric Value
dl 0
loc 64
ccs 36
cts 36
cp 1
rs 6.0563
c 0
b 0
f 0
cc 11
eloc 42
nc 38
nop 2
crap 11

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
namespace Tartana\Console\Command;
3
4
use League\Flysystem\Adapter\Local;
5
use Monolog\Logger;
6
use Symfony\Component\Console\Command\Command as SymfonyCommand;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Output\OutputInterface;
10
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
11
use Tartana\Component\Command\Command;
12
use Tartana\Component\Command\Runner;
13
use Tartana\Event\ProcessingCompletedEvent;
14
use Tartana\Mixins\LoggerAwareTrait;
15
use Tartana\Util;
16
use League\Flysystem\Config;
17
18
class ConvertSoundCommand extends SymfonyCommand
19
{
20
	use LoggerAwareTrait;
21
22
	protected $dispatcher = null;
23
24
	protected $commandRunner = null;
25 9
26
	public function __construct(Runner $commandRunner, EventDispatcherInterface $dispatcher = null)
27 9
	{
28
		parent::__construct('convert:sound');
29 9
30 9
		$this->dispatcher    = $dispatcher;
31 9
		$this->commandRunner = $commandRunner;
32
	}
33 9
34
	protected function configure()
35 9
	{
36
		$this->setDescription('Converts mp4 files to mp3. This command is running in foreground!');
37 9
38 9
		$this->addArgument('source', InputArgument::REQUIRED, 'The folder with files to convert.');
39 9
		$this->addArgument('destination', InputArgument::REQUIRED, 'The folder to convert the files to.');
40
	}
41 7
42
	protected function execute(InputInterface $input, OutputInterface $output)
43 7
	{
44 7
		$source = Util::realPath($input->getArgument('source'));
45
		if (empty($source)) {
46 1
			$this->log('Source directory no found to convert.', Logger::ERROR);
47 1
			return;
48
		}
49 6
		$destination = Util::realPath($input->getArgument('destination'));
50 6
		if (empty($destination)) {
51
			$this->log('Destination directory no found to convert.', Logger::ERROR);
52 1
			return;
53 1
		}
54
55
		$binary = null;
56 5
		if ($this->commandRunner->execute(new Command('which ffmpeg'))) {
57
			$binary = 'ffmpeg';
58 1
			$this->log("FFmpeg found", Logger::INFO);
59 1
		}
60
61
		if (!$binary && $this->commandRunner->execute(new Command('which avconv'))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $binary of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
62 4
			$binary = 'avconv';
63 4
			$this->log("Avconv found", Logger::INFO);
64
		}
65 4
66 4
		if ($binary == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $binary of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
67
			$this->log("FFmpeg and Avconv is not on the path, can't convert video files to mp3", Logger::INFO);
68 4
			return;
69
		}
70 1
71
		$destination = new Local($destination);
72
		$source      = new Local($source);
73 4
74 4
		$success = true;
75 4
		foreach ($source->listContents('', true) as $file) {
76 4
			if (!Util::endsWith($file['path'], '.mp4')) {
77 4
				continue;
78 4
			}
79 4
80 4
			$command = new Command($binary);
81 4
			$command->setAsync(false);
82
			$command->addArgument('-i');
83 4
			$command->addArgument($source->applyPathPrefix($file['path']));
84
			$command->addArgument('-f mp3', false);
85 4
			$command->addArgument('-ab 192k', false);
86 3
			$command->addArgument('-y', false);
87 4
			$command->addArgument('-vn');
88
			$command->addArgument(str_replace('.mp4', '.mp3', $destination->applyPathPrefix($file['path'])));
89 4
90
			$this->log('Running ffmpeg system command: ' . $command);
91 2
92 4
			$output = $this->commandRunner->execute($command, function ($line) use ($output) {
93
				$output->writeln($line);
94
			});
95
96 4
			if (Util::endsWith($output, 'Invalid data found when processing input')) {
97
				$success = false;
98 3
				$source->write($file['path'] . '.out', $output, new Config());
99
			}
100 4
		}
101
102
		if ($this->dispatcher) {
103
			$this->dispatcher->dispatch('processing.completed', new ProcessingCompletedEvent($source, $destination, $success));
104
		}
105
	}
106
}
107