Passed
Push — master ( 19041b...a0a10b )
by Sébastien
05:41 queued 03:16
created

VideoInfo   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 78.18%

Importance

Changes 0
Metric Value
wmc 21
eloc 48
dl 0
loc 123
ccs 43
cts 55
cp 0.7818
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getFile() 0 3 1
A __construct() 0 4 1
A createFromFFProbeJson() 0 11 3
A getVideoStreamInfo() 0 3 1
A countStreams() 0 3 1
A getStreamsByType() 0 21 5
A getDimensions() 0 5 1
A getMetadata() 0 3 1
A getWidth() 0 5 1
A getDuration() 0 3 1
A getNbFrames() 0 5 1
A getFormatName() 0 3 1
A getHeight() 0 5 1
A getAudioStreamInfo() 0 3 1
A getBitrate() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools\Video;
6
7
use Soluble\MediaTools\Common\Exception\JsonParseException;
8
9
class VideoInfo implements VideoInfoInterface
10
{
11
    public const STREAM_TYPE_AUDIO = 'audio';
12
    public const STREAM_TYPE_VIDEO = 'video';
13
    public const STREAM_TYPE_DATA  = 'data';
14
15
    /** @var array */
16
    protected $metadata;
17
18
    /** @var string */
19
    protected $file;
20
21 1
    public function __construct(string $file, array $metadata)
22
    {
23 1
        $this->metadata = $metadata;
24 1
        $this->file     = $file;
25 1
    }
26
27 1
    public static function createFromFFProbeJson(string $file, string $ffprobeJson): self
28
    {
29 1
        if (trim($ffprobeJson) === '') {
30
            throw new JsonParseException('Cannot parse empty json string');
31
        }
32 1
        $decoded = json_decode($ffprobeJson, true);
33 1
        if ($decoded === null) {
34
            throw new JsonParseException('Cannot parse json');
35
        }
36
37 1
        return new self($file, $decoded);
38
    }
39
40 1
    public function getFile(): string
41
    {
42 1
        return $this->file;
43
    }
44
45 1
    public function getFormatName(): string
46
    {
47 1
        return $this->metadata['format']['format_name'];
48
    }
49
50 1
    public function countStreams(): int
51
    {
52 1
        return $this->metadata['format']['nb_streams'];
53
    }
54
55
    public function getMetadata(): array
56
    {
57
        return $this->metadata;
58
    }
59
60 1
    public function getDuration(): float
61
    {
62 1
        return (float) ($this->metadata['format']['duration'] ?? 0.0);
63
    }
64
65 1
    public function getDimensions(): array
66
    {
67
        return [
68 1
            'width'  => $this->getWidth(),
69 1
            'height' => $this->getHeight(),
70
        ];
71
    }
72
73 1
    public function getWidth(): int
74
    {
75 1
        $videoStream = $this->getVideoStreamInfo();
76
77 1
        return (int) ($videoStream['width'] ?? 0);
78
    }
79
80 1
    public function getHeight(): int
81
    {
82 1
        $videoStream = $this->getVideoStreamInfo();
83
84 1
        return (int) ($videoStream['height'] ?? 0);
85
    }
86
87 1
    public function getNbFrames(): int
88
    {
89 1
        $videoStream = $this->getVideoStreamInfo();
90
91 1
        return (int) ($videoStream['nb_frames'] ?? 0);
92
    }
93
94
    public function getBitrate(): int
95
    {
96
        $videoStream = $this->getVideoStreamInfo();
97
98
        return (int) ($videoStream['bit_rate'] ?? 0);
99
    }
100
101
    public function getAudioStreamInfo(): ?array
102
    {
103
        return $this->getStreamsByType()[self::STREAM_TYPE_AUDIO] ?? null;
104
    }
105
106 1
    public function getVideoStreamInfo(): ?array
107
    {
108 1
        return $this->getStreamsByType()[self::STREAM_TYPE_VIDEO] ?? null;
109
    }
110
111 1
    protected function getStreamsByType(): array
112
    {
113 1
        $streams = $this->metadata['streams'] ?? [];
114 1
        foreach ($streams as $stream) {
115 1
            $type = mb_strtolower($stream['codec_type']);
116
            switch ($type) {
117 1
                case self::STREAM_TYPE_VIDEO:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
118 1
                    $streams['video'] = $stream;
119 1
                    break;
120 1
                case self::STREAM_TYPE_AUDIO:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
121 1
                    $streams['audio'] = $stream;
122 1
                    break;
123
                case self::STREAM_TYPE_DATA:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
124
                    $streams['data'] = $stream;
125
                    break;
126
                default:
0 ignored issues
show
Coding Style introduced by
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
127 1
                    throw new \Exception(sprintf('Does not support codec_type "%s"', $type));
128
            }
129
        }
130
131 1
        return $streams;
132
    }
133
}
134