Passed
Push — master ( c37170...fb5355 )
by Amin
02:31
created

Export::clouds()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 5
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\Cloud;
16
use Streaming\Exception\InvalidArgumentException;
17
use Streaming\Exception\RuntimeException;
18
use Streaming\Filters\Filter;
19
use Streaming\Traits\Formats;
20
21
22
abstract class Export
23
{
24
    use Formats;
25
26
    /** @var object */
27
    protected $media;
28
29
    /** @var array */
30
    protected $path_info;
31
32
    /** @var string */
33
    protected $strict = "-2";
34
35
    /** @var string */
36
    protected $tmp_dir;
37
38
    /**
39
     * Export constructor.
40
     * @param Media $media
41
     */
42
    public function __construct(Media $media)
43
    {
44
        $this->media = $media;
45
        $this->path_info = pathinfo($media->getPath());
46
    }
47
48
    /**
49
     * @return object|Media
50
     */
51
    public function getMedia(): Media
52
    {
53
        return $this->media;
54
    }
55
56
    /**
57
     * @param string $strict
58
     * @return Export
59
     */
60
    public function setStrict(string $strict): Export
61
    {
62
        $this->strict = $strict;
63
        return $this;
64
    }
65
66
    /**
67
     * @return string
68
     */
69
    public function getStrict(): string
70
    {
71
        return $this->strict;
72
    }
73
74
    /**
75
     * @return bool
76
     */
77
    public function isTmpDir(): bool
78
    {
79
        return (bool)$this->tmp_dir;
80
    }
81
82
    /**
83
     * @return array
84
     */
85
    public function getPathInfo(): array
86
    {
87
        return $this->path_info;
88
    }
89
90
    /**
91
     * @param string|null $path
92
     */
93
    private function moveTmp(?string $path): void
94
    {
95
        if ($this->isTmpDir() && !is_null($path)) {
96
            File::moveDir($this->tmp_dir, dirname($path));
97
            $this->path_info = pathinfo($path);
98
            $this->tmp_dir = '';
99
        }
100
    }
101
102
103
    /**
104
     * @param array $clouds
105
     * @param string $path
106
     */
107
    private function clouds(array $clouds, ?string $path): void
108
    {
109
        if (!empty($clouds)) {
110
            Cloud::uploadDirectory($clouds, $this->tmp_dir);
111
            $this->moveTmp($path);
112
        }
113
    }
114
115
    /**
116
     * @return string
117
     */
118
    private function getPath(): string
119
    {
120
        $path = str_replace("\\", "/", $this->path_info["dirname"] . "/" . $this->path_info["filename"]);
121
122
        if ($this instanceof DASH) {
123
            $path .= ".mpd";
124
        } elseif ($this instanceof HLS) {
125
            $reps = $this->getRepresentations();
126
            HLSPlaylist::save($path . ".m3u8", $reps);
127
            $path .= "_" . end($reps)->getHeight() . "p.m3u8";
128
        }
129
130
        return $path;
131
    }
132
133
    /**
134
     * @return Filter
135
     */
136
    abstract protected function getFilter(): Filter;
137
138
    /**
139
     * Run FFmpeg to package media content
140
     */
141
    private function run(): void
142
    {
143
        try {
144
            $this->media
145
                ->addFilter($this->getFilter())
146
                ->save($this->getFormat(), $this->getPath());
147
        } catch (ExceptionInterface $e) {
148
            throw new RuntimeException("An error occurred while saving files: " . $e->getMessage(), $e->getCode(), $e);
149
        }
150
    }
151
152
    /**
153
     * @param string|null $path
154
     */
155
    private function tmpDirectory(?string $path): void
156
    {
157
        $basename = $path ? basename($path) : Utilities::randomString();
158
159
        $this->tmp_dir = File::tmpDir();
160
        $this->path_info = pathinfo($this->tmp_dir . $basename);
161
    }
162
163
    /**
164
     * @param $path
165
     * @param $clouds
166
     */
167
    private function makePaths(?string $path, array $clouds): void
168
    {
169
        if ($clouds) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $clouds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
170
            $this->tmpDirectory($path);
171
        } elseif (!is_null($path)) {
172
            if (strlen($path) > PHP_MAXPATHLEN) {
173
                throw new InvalidArgumentException("The path is too long");
174
            }
175
176
            File::makeDir(dirname($path));
177
            $this->path_info = pathinfo($path);
178
        } elseif ($this->media->isTmp()) {
179
            throw new InvalidArgumentException("You need to specify a path. It is not possible to save to a tmp directory");
180
        }
181
    }
182
183
    /**
184
     * @param string $path
185
     * @param array $clouds
186
     * @param bool $metadata
187
     * @return mixed
188
     */
189
    public function save(string $path = null, array $clouds = [], bool $metadata = true)
190
    {
191
        $this->makePaths($path, $clouds);
192
        $this->run();
193
        $this->clouds($clouds, $path);
194
195
        return $metadata ? (new Metadata($this))->extract() : $this;
196
    }
197
198
    /**
199
     * clear tmp files
200
     */
201
    public function __destruct()
202
    {
203
        sleep(1);
204
205
        if ($this->media->isTmp()) {
206
            @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

206
            /** @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...
207
        }
208
209
        if ($this->tmp_dir) {
210
            File::deleteDirectory($this->tmp_dir);
211
        }
212
213
        if ($this instanceof HLS && $this->tmp_key_info_file) {
214
            @unlink($this->getHlsKeyInfoFile());
215
        }
216
    }
217
}