Passed
Push — main ( 49af41...041b68 )
by Chris
39:03 queued 24:02
created

MediaConvert::saveTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Meema\MediaConverter\Converters;
4
5
use Aws\Credentials\Credentials;
6
use Aws\MediaConvert\MediaConvertClient;
7
use Meema\MediaConverter\Contracts\Converter;
8
9
class MediaConvert implements Converter
10
{
11
    /**
12
     * Client instance of AWS MediaConvert.
13
     *
14
     * @var \Aws\MediaConvert\MediaConvertClient
15
     */
16
    protected $client;
17
18
    /**
19
     * The MediaConvert job's settings.
20
     *
21
     * @var array
22
     */
23
    public array $jobSettings;
24
25
    /**
26
     * Construct converter.
27
     *
28
     * @param \Aws\MediaConvert\MediaConvertClient $client
29
     */
30
    public function __construct(MediaConvertClient $client)
0 ignored issues
show
Unused Code introduced by
The parameter $client 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

30
    public function __construct(/** @scrutinizer ignore-unused */ MediaConvertClient $client)

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...
31
    {
32
        $config = config('media-converter');
33
34
        $this->jobSettings = (new $config['job_settings'])::get();
35
36
        $this->client = new MediaConvertClient([
37
            'version' => $config['version'],
38
            'region' => $config['region'],
39
            'credentials' => new Credentials($config['credentials']['key'], $config['credentials']['secret']),
40
            'endpoint' => $config['url'],
41
        ]);
42
    }
43
44
    /**
45
     * Get the MediaConvert Client.
46
     *
47
     * @return \Aws\MediaConvert\MediaConvertClient
48
     */
49
    public function getClient(): MediaConvertClient
50
    {
51
        return $this->client;
52
    }
53
54
    /**
55
     * Sets the path of the file input.
56
     *
57
     * @param string $path - represents the S3 path, e.g path/to/file.mp4
58
     * @param string|null $bucket - reference to the S3 Bucket name. Defaults to config value.
59
     * @return \Meema\MediaConverter\Converters\MediaConvert
60
     */
61
    public function path(string $path, $bucket = null): MediaConvert
62
    {
63
        $this->setFileInput($path, $bucket);
64
65
        return $this;
66
    }
67
68
    /**
69
     * Generates a web optimized MP4.
70
     *
71
     * @return \Meema\MediaConverter\Converters\MediaConvert
72
     */
73
    public function optimizeForWeb(): MediaConvert
74
    {
75
        // At the moment, we can simply return $this, because this method is simply used for readability purposes.
76
        // The "default job" has all the proper settings already to generate a web optimized mp4.
77
        return $this;
78
    }
79
80
    /**
81
     * Sets the settings required to generate the proper amount of thumbnails.
82
     *
83
     * @param int $framerateNumerator
84
     * @param int $framerateDenominator
85
     * @param int $maxCaptures
86
     * @param int|null $width
87
     * @param string|null $nameModifier
88
     * @param int $imageQuality
89
     * @return \Meema\MediaConverter\Converters\MediaConvert
90
     */
91
    public function withThumbnails(int $framerateNumerator, int $framerateDenominator, int $maxCaptures, $width = null, $nameModifier = null, $imageQuality = 80): MediaConvert
92
    {
93
        $this->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['CodecSettings']['FrameCaptureSettings'] = [
94
            'FramerateNumerator' => $framerateNumerator,
95
            'FramerateDenominator' => $framerateDenominator,
96
            'MaxCaptures' => $maxCaptures,
97
            'Quality' => $imageQuality,
98
        ];
99
100
        if ($width) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $width of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
101
            $this->jobSettings['OutputGroups'][0]['Outputs'][0]['VideoDescription']['Width'] = $width;
102
        }
103
104
        if ($nameModifier) {
105
            $this->jobSettings['OutputGroups'][0]['Outputs'][0]['NameModifier'] = $nameModifier;
106
        }
107
108
        return $this;
109
    }
110
111
    /**
112
     * Sets the S3 path & executes the job.
113
     *
114
     * @param string $s3Path
115
     * @param string|null $s3bucket
116
     * @return \Meema\MediaConverter\Converters\MediaConvert
117
     */
118
    public function saveTo(string $s3Path, $s3bucket = null): MediaConvert
119
    {
120
        $destination = 's3://'.($s3bucket ?? config('filesystems.disks.s3.bucket'));
121
122
        $this->jobSettings['OutputGroups'][0]['OutputGroupSettings']['FileGroupSettings']['Destination'] = $destination.'/thumbnails/';
123
        $this->jobSettings['OutputGroups'][1]['OutputGroupSettings']['FileGroupSettings']['Destination'] = $destination.'/mp4/';
124
125
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Meema\MediaConverter\Converters\MediaConvert which is incompatible with the return type mandated by Meema\MediaConverter\Contracts\Converter::saveTo() of Aws\Result.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
126
    }
127
128
    /**
129
     * Cancels an active job.
130
     *
131
     * @param string $id
132
     * @return \Aws\Result
133
     */
134
    public function cancelJob(string $id)
135
    {
136
        return $this->client->cancelJob([
137
            'Id' => $id,
138
        ]);
139
    }
140
141
    /**
142
     * Creates a new job based on the settings passed.
143
     *
144
     * @param array $settings
145
     * @param array $metaData
146
     * @param int $priority
147
     * @return \Aws\Result
148
     */
149
    public function createJob(array $settings, array $metaData = [], int $priority = 0)
150
    {
151
        return $this->client->createJob([
152
            'Role' => config('media-converter.iam_arn'),
153
            'Settings' => $settings,
154
            'Queue' => config('media-converter.queue_arn'),
155
            'UserMetadata' => $metaData,
156
            'StatusUpdateInterval' => $this->getStatusUpdateInterval(),
157
            'Priority' => $priority,
158
        ]);
159
    }
160
161
    /**
162
     * Gets the job.
163
     *
164
     * @param string $id
165
     * @return \Aws\Result
166
     */
167
    public function getJob(string $id)
168
    {
169
        return $this->client->getJob([
170
            'Id' => $id,
171
        ]);
172
    }
173
174
    /**
175
     * Lists all of the jobs based on your options provided.
176
     *
177
     * @param array $options
178
     * @return \Aws\Result
179
     */
180
    public function listJobs(array $options)
181
    {
182
        return $this->client->listJobs($options);
183
    }
184
185
    protected function getStatusUpdateInterval(): string
186
    {
187
        $webhookInterval = config('media-converter.webhook_interval');
188
        $allowedValues = [10, 12, 15, 20, 30, 60, 120, 180, 240, 300, 360, 420, 480, 540, 600];
189
190
        if (in_array($webhookInterval, [$allowedValues])) {
191
            return 'SECONDS_'.$webhookInterval;
192
        }
193
194
        return 'SECONDS_60'; // gracefully default to this value, in case the config value is missing or incorrect
195
    }
196
197
    /**
198
     * Sets the S3 input file path.
199
     *
200
     * @param string $path
201
     * @param string|null $bucket
202
     */
203
    protected function setFileInput(string $path, $bucket = null)
204
    {
205
        $fileInput = 's3://'.($bucket ?? config('filesystems.disks.s3.bucket')).'/'.$path;
206
207
        $this->jobSettings['Inputs'][0]['FileInput'] = $fileInput;
208
    }
209
}
210