Issues (12)

src/Converters/MediaConvert.php (3 issues)

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
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')).'/'.$s3Path;
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 = [], array $tags = [], int $priority = 0)
150
    {
151
        if (empty($settings)) {
152
            $settings = $this->jobSettings;
153
        }
154
155
        return $this->client->createJob([
156
            'Role' => config('media-converter.iam_arn'),
157
            'Settings' => $settings,
158
            'Queue' => config('media-converter.queue_arn'),
159
            'UserMetadata' => $metaData,
160
            'Tags' => $tags,
161
            'StatusUpdateInterval' => $this->getStatusUpdateInterval(),
162
            'Priority' => $priority,
163
        ]);
164
    }
165
166
    /**
167
     * Gets the job.
168
     *
169
     * @param  string  $id
170
     * @return \Aws\Result
171
     */
172
    public function getJob(string $id)
173
    {
174
        return $this->client->getJob([
175
            'Id' => $id,
176
        ]);
177
    }
178
179
    /**
180
     * Lists all of the jobs based on your options provided.
181
     *
182
     * @param  array  $options
183
     * @return \Aws\Result
184
     */
185
    public function listJobs(array $options)
186
    {
187
        return $this->client->listJobs($options);
188
    }
189
190
    protected function getStatusUpdateInterval(): string
191
    {
192
        $webhookInterval = config('media-converter.webhook_interval');
193
        $allowedValues = [10, 12, 15, 20, 30, 60, 120, 180, 240, 300, 360, 420, 480, 540, 600];
194
195
        if (in_array($webhookInterval, [$allowedValues])) {
196
            return 'SECONDS_'.$webhookInterval;
197
        }
198
199
        return 'SECONDS_60'; // gracefully default to this value, in case the config value is missing or incorrect
200
    }
201
202
    /**
203
     * Sets the S3 input file path.
204
     *
205
     * @param  string  $path
206
     * @param  string|null  $bucket
207
     */
208
    protected function setFileInput(string $path, $bucket = null)
209
    {
210
        $fileInput = 's3://'.($bucket ?? config('filesystems.disks.s3.bucket')).'/'.$path;
211
212
        $this->jobSettings['Inputs'][0]['FileInput'] = $fileInput;
213
    }
214
}
215