Passed
Push — master ( 4d4fc5...4bc7af )
by Amin
03:11
created

AutoRepresentations::getSideValues()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the PHP-FFmpeg-video-streaming package.
5
 *
6
 * (c) Amin Yazdanpanah <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Streaming;
13
14
use FFMpeg\Coordinate\Dimension;
15
use FFMpeg\Exception\ExceptionInterface;
16
use Streaming\Exception\InvalidArgumentException;
17
use Streaming\Exception\RuntimeException;
18
19
class AutoRepresentations
20
{
21
    /** @var \FFMpeg\FFProbe\DataMapping\Stream $video */
22
    private $video;
23
24
    /** @var \FFMpeg\FFProbe\DataMapping\Format $format */
25
    private $format;
26
27
    /**
28
     * regular video's heights
29
     *
30
     * @var array side_values
31
     */
32
    private $side_values = [144, 240, 360, 480, 720, 1080, 1440, 2160];
33
34
    /** @var array $k_bitrate_values */
35
    private $k_bitrate;
36
37
    /**
38
     * AutoRepresentations constructor.
39
     * @param Media $media
40
     * @param array|null $sides
41
     * @param array|null $k_bitrate
42
     */
43
    public function __construct(Media $media, array $sides = null, array $k_bitrate = null)
44
    {
45
        $this->video = $media->getStreams()->videos()->first();
46
        $this->format = $media->getFormat();
47
        $this->getSideValues($sides);
48
        $this->getKiloBitrateValues($k_bitrate);
49
    }
50
51
    /**
52
     * @return Dimension
53
     */
54
    private function getDimensions(): Dimension
55
    {
56
        try {
57
            return $this->video->getDimensions();
58
        } catch (ExceptionInterface $e) {
59
            throw new RuntimeException("Unable to extract dimensions.: " . $e->getMessage(), $e->getCode(), $e);
60
        }
61
    }
62
63
    /**
64
     * @return mixed
65
     * @throws InvalidArgumentException
66
     */
67
    private function getKiloBitRate(): int
68
    {
69
        if (!$this->video->has('bit_rate')) {
70
            if (!$this->format->has('bit_rate')) {
71
                throw new InvalidArgumentException("Unable to extract bitrate.");
72
            }
73
74
            return intval(($this->format->get('bit_rate') / 1024) * .9);
75
        }
76
77
        return (int)$this->video->get('bit_rate') / 1024;
78
    }
79
80
    /**
81
     * @return array
82
     */
83
    public function get(): array
84
    {
85
        $reps = [];
86
        $dimension = $this->getDimensions();
87
        $ratio = $dimension->getRatio()->getValue();
88
89
        foreach ($this->side_values as $key => $height) {
90
            array_push($reps, $this->addRep($this->k_bitrate[$key], Utiles::RTE($height * $ratio), $height));
91
        }
92
93
        return array_merge($reps, [$this->addRep($this->getKiloBitRate(), $dimension->getWidth(), $dimension->getHeight())]);
94
    }
95
96
    /**
97
     * @param $width
98
     * @param $k_bitrate
99
     * @param $height
100
     * @return Representation
101
     * @throws InvalidArgumentException
102
     */
103
    private function addRep($k_bitrate, $width, $height): Representation
104
    {
105
        return (new Representation)->setKiloBitrate($k_bitrate)->setResize($width, $height);
106
    }
107
108
    /**
109
     * @param array|null $k_bitrate_values
110
     */
111
    private function getKiloBitrateValues(?array $k_bitrate_values): void
112
    {
113
        $k_bit_rates = [];
114
115
        $count_sides = count($this->side_values);
116
117
        if (!empty($k_bitrate_values)) {
118
            if ($count_sides !== count($k_bitrate_values)) {
119
                throw new InvalidArgumentException("The count of side value array must be the same as the count of kilo bitrate array");
120
            }
121
122
            $this->k_bitrate = $k_bitrate_values;
123
            return;
124
        }
125
126
        $k_bitrate_value = $this->getKiloBitRate();
127
        $divided_by = 1.5;
128
129
        while ($count_sides) {
130
            $k_bit_rates[] = (($k_bitrate = intval($k_bitrate_value / $divided_by)) < 64) ? 64 : $k_bitrate;
131
            $divided_by += .5;
132
            $count_sides--;
133
        }
134
135
        $this->k_bitrate = array_reverse($k_bit_rates);
136
    }
137
138
    /**
139
     * @param int $height
140
     * @return bool
141
     */
142
    private function sideFilter(int $height): bool
143
    {
144
        return $height < $this->getDimensions()->getHeight();
145
    }
146
147
    /**
148
     * @param array|null $side_values
149
     */
150
    private function getSideValues(?array $side_values): void
151
    {
152
        if (!is_null($side_values)) {
0 ignored issues
show
introduced by
The condition is_null($side_values) is always false.
Loading history...
153
            $this->side_values = $side_values;
154
            return;
155
        }
156
157
        $this->side_values = array_values(array_filter($this->side_values, [$this, 'sideFilter']));
158
    }
159
}