Completed
Push — master ( baa637...9b813d )
by Amin
04:08 queued 11s
created

Export::saveToMAS()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 4
dl 0
loc 20
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\Exception\ExceptionInterface;
15
use Streaming\Clouds\AWS;
16
use Streaming\Clouds\Cloud;
17
use Streaming\Clouds\GoogleCloudStorage;
18
use Streaming\Clouds\MicrosoftAzure;
19
use Streaming\Exception\Exception;
20
use Streaming\Exception\InvalidArgumentException;
21
use Streaming\Exception\RuntimeException;
22
use Streaming\Filters\Filter;
23
use Streaming\Traits\Formats;
24
25
abstract class Export
26
{
27
    use Formats;
28
29
    /** @var object */
30
    protected $media;
31
32
    /** @var array */
33
    protected $path_info;
34
35
    /** @var string */
36
    protected $strict = "-2";
37
38
    /** @var string */
39
    protected $tmp_dir;
40
41
    /**
42
     * Export constructor.
43
     * @param Media $media
44
     */
45
    public function __construct(Media $media)
46
    {
47
        $this->media = $media;
48
        $this->path_info = pathinfo($media->getPath());
49
    }
50
51
    /**
52
     * @param string $path
53
     * @param bool $metadata
54
     * @return mixed
55
     * @throws Exception
56
     */
57
    public function save(string $path = null, bool $metadata = true)
58
    {
59
        $path = $this->getPath($path);
60
        try {
61
            $this->media
62
                ->addFilter($this->getFilter())
63
                ->save($this->getFormat(), $path);
64
        } catch (ExceptionInterface $e) {
65
            throw new RuntimeException(sprintf("There was an error saving files: \n\n reason: \n %s", $e->getMessage()),
66
                $e->getCode(),
67
                $e
68
            );
69
        }
70
71
        return ($metadata) ? (new Metadata($this))->extract() : $this;
72
    }
73
74
    /**
75
     * @return Filter
76
     */
77
    abstract protected function getFilter(): Filter;
78
79
    /**
80
     * @param $path
81
     * @return string
82
     * @throws Exception
83
     */
84
    private function getPath($path): string
85
    {
86
        if (null !== $path) {
87
            $this->path_info = pathinfo($path);
88
        }
89
90
        if (null === $path && $this->media->isTmp()) {
91
            throw new InvalidArgumentException("You need to specify a path. It is not possible to save to a tmp directory");
92
        }
93
94
        $dirname = str_replace("\\", "/", $this->path_info["dirname"]);
95
        $filename = substr($this->path_info["filename"], -50);
96
97
        FileManager::makeDir($dirname);
98
99
        if ($this instanceof DASH) {
100
            $path = $dirname . "/" . $filename . ".mpd";
101
        } elseif ($this instanceof HLS) {
102
            $representations = $this->getRepresentations();
103
            $path = $dirname . "/" . $filename . "_" . end($representations)->getHeight() . "p.m3u8";
104
            ExportHLSPlaylist::savePlayList($dirname . DIRECTORY_SEPARATOR . $filename . ".m3u8", $this->getRepresentations(), $filename);
105
        }
106
107
        return $path;
108
    }
109
110
    /**
111
     * @param string $url
112
     * @param string $name
113
     * @param string|null $path
114
     * @param string $method
115
     * @param array $headers
116
     * @param array $options
117
     * @param bool $metadata
118
     * @return mixed
119
     * @throws Exception
120
     */
121
    public function saveToCloud(
122
        string $url,
123
        string $name,
124
        string $path = null,
125
        string $method = 'GET',
126
        array $headers = [],
127
        array $options = [],
128
        bool $metadata = true
129
    )
130
    {
131
        if ($this instanceof HLS && $this->getTsSubDirectory()) {
132
            throw new InvalidArgumentException("It is not possible to create subdirectory in a cloud");
133
        }
134
        $results = $this->saveToTemporaryFolder($path, $metadata);
135
        sleep(1);
136
137
        $cloud = new Cloud($url, $method, $options);
138
        $cloud->uploadDirectory($this->tmp_dir, ['name' => $name, 'headers' => $headers]);
139
140
        $this->moveTmpFolder($path);
141
142
        return $results;
143
    }
144
145
    /**
146
     * @param array $config
147
     * @param string $dest
148
     * @param string|null $path
149
     * @param bool $metadata
150
     * @return mixed
151
     * @throws Exception
152
     */
153
    public function saveToS3(
154
        array $config,
155
        string $dest,
156
        string $path = null,
157
        bool $metadata = true
158
    )
159
    {
160
        $results = $this->saveToTemporaryFolder($path, $metadata);
161
        sleep(1);
162
163
        $aws = new AWS($config);
164
        $aws->uploadDirectory($this->tmp_dir, ['dest' => $dest]);
165
166
        $this->moveTmpFolder($path);
167
168
        return $results;
169
    }
170
171
    /**
172
     * @param array $config
173
     * @param string $bucket
174
     * @param string|null $path
175
     * @param array $options
176
     * @param bool $userProject
177
     * @param bool $metadata
178
     * @return mixed
179
     * @throws Exception
180
     */
181
    public function saveToGCS(
182
        array $config,
183
        string $bucket,
184
        string $path = null,
185
        array $options = [],
186
        bool $userProject = false,
187
        bool $metadata = true
188
    )
189
    {
190
        if ($this instanceof HLS && $this->getTsSubDirectory()) {
191
            throw new InvalidArgumentException("It is not possible to create subdirectory in a cloud");
192
        }
193
194
        $results = $this->saveToTemporaryFolder($path, $metadata);
195
        sleep(1);
196
197
        $google_cloud = new GoogleCloudStorage($config, $bucket, $userProject);
198
        $google_cloud->uploadDirectory($this->tmp_dir, $options);
199
200
        $this->moveTmpFolder($path);
201
202
        return $results;
203
    }
204
205
    /**
206
     * @param string $connectionString
207
     * @param string $container
208
     * @param string|null $path
209
     * @param bool $metadata
210
     * @return mixed
211
     * @throws Exception
212
     */
213
    public function saveToMAS(
214
        string $connectionString,
215
        string $container,
216
        string $path = null,
217
        bool $metadata = true
218
    )
219
    {
220
        if ($this instanceof HLS && $this->getTsSubDirectory()) {
221
            throw new InvalidArgumentException("It is not possible to create subdirectory in a cloud");
222
        }
223
224
        $results = $this->saveToTemporaryFolder($path, $metadata);
225
        sleep(1);
226
227
        $google_cloud = new MicrosoftAzure($connectionString);
228
        $google_cloud->uploadDirectory($this->tmp_dir, ['container' => $container]);
229
230
        $this->moveTmpFolder($path);
231
232
        return $results;
233
    }
234
235
    /**
236
     * @return array
237
     */
238
    public function getPathInfo(): array
239
    {
240
        return $this->path_info;
241
    }
242
243
    /**
244
     * @return object|Media
245
     */
246
    public function getMedia(): Media
247
    {
248
        return $this->media;
249
    }
250
251
    /**
252
     * @param $path
253
     * @param $metadata
254
     * @return array
255
     * @throws Exception
256
     */
257
    private function saveToTemporaryFolder($path, $metadata)
258
    {
259
        $basename = Helper::randomString();
260
261
        if (null !== $path) {
262
            $basename = pathinfo($path, PATHINFO_BASENAME);
263
        }
264
265
        $this->tmp_dir = FileManager::tmpDir();
266
267
        return $this->save($this->tmp_dir . $basename, $metadata);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->save($this.... $basename, $metadata) also could return the type Streaming\Export which is incompatible with the documented return type array.
Loading history...
268
    }
269
270
    /**
271
     * clear tmp files
272
     */
273
    public function __destruct()
274
    {
275
        sleep(1);
276
277
        if ($this->media->isTmp()) {
278
            @unlink($this->media->getPath());
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

278
            /** @scrutinizer ignore-unhandled */ @unlink($this->media->getPath());

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
279
        }
280
281
        if ($this->tmp_dir) {
282
            FileManager::deleteDirectory($this->tmp_dir);
283
        }
284
    }
285
286
    /**
287
     * @param string|null $path
288
     * @throws Exception
289
     */
290
    private function moveTmpFolder(?string $path)
291
    {
292
        if ($path) {
293
            FileManager::moveDir($this->tmp_dir, pathinfo($path, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR);
294
        }
295
    }
296
297
    /**
298
     * @param string $strict
299
     * @return Export
300
     */
301
    public function setStrict(string $strict): Export
302
    {
303
        $this->strict = $strict;
304
        return $this;
305
    }
306
307
    /**
308
     * @return string
309
     */
310
    public function getStrict(): string
311
    {
312
        return $this->strict;
313
    }
314
}