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

Export::getFilePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
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\Filters\FilterStreamingInterface;
20
use Streaming\Traits\Formats;
21
22
23
abstract class Export
24
{
25
    use Formats;
26
27
    /** @var object */
28
    protected $media;
29
30
    /** @var string */
31
    protected $path;
32
33
    /** @var string */
34
    protected $tmp_dir;
35
36
    /** @var string */
37
    protected $uri;
38
39
    /**
40
     * Export constructor.
41
     * @param Media $media
42
     */
43
    public function __construct(Media $media)
44
    {
45
        $this->media = $media;
46
        $this->path = $media->getPath();
47
    }
48
49
    /**
50
     * @return object|Media
51
     */
52
    public function getMedia(): Media
53
    {
54
        return $this->media;
55
    }
56
57
    /**
58
     * @return bool
59
     */
60
    public function isTmpDir(): bool
61
    {
62
        return (bool)$this->tmp_dir;
63
    }
64
65
    /**
66
     * @param int $option
67
     * @return array | string
68
     */
69
    public function getPathInfo(int $option)
70
    {
71
        return pathinfo($this->path, $option);
72
    }
73
74
    /**
75
     * @param string|null $path
76
     */
77
    private function moveTmp(?string $path): void
78
    {
79
        if ($this->isTmpDir() && !is_null($path)) {
80
            File::move($this->tmp_dir, dirname($path));
81
            $this->path = $path;
82
            $this->tmp_dir = '';
83
        }
84
    }
85
86
    /**
87
     * @param array $clouds
88
     * @param string $path
89
     */
90
    private function clouds(array $clouds, ?string $path): void
91
    {
92
        if (!empty($clouds)) {
93
            Cloud::uploadDirectory($clouds, $this->tmp_dir);
94
            $this->moveTmp($path);
95
        }
96
    }
97
98
    /**
99
     * @return string
100
     */
101
    protected function getFilePath(): string
102
    {
103
        return str_replace(
104
            "\\",
105
            "/",
106
            $this->getPathInfo(PATHINFO_DIRNAME) . "/" . $this->getPathInfo(PATHINFO_FILENAME)
0 ignored issues
show
Bug introduced by
Are you sure $this->getPathInfo(Streaming\PATHINFO_DIRNAME) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

106
            /** @scrutinizer ignore-type */ $this->getPathInfo(PATHINFO_DIRNAME) . "/" . $this->getPathInfo(PATHINFO_FILENAME)
Loading history...
Bug introduced by
Are you sure $this->getPathInfo(Streaming\PATHINFO_FILENAME) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

106
            $this->getPathInfo(PATHINFO_DIRNAME) . "/" . /** @scrutinizer ignore-type */ $this->getPathInfo(PATHINFO_FILENAME)
Loading history...
107
        );
108
    }
109
110
    /**
111
     * @return string
112
     */
113
    abstract protected function getPath(): string;
114
115
    /**
116
     * @return Filter
117
     */
118
    abstract protected function getFilter(): FilterStreamingInterface;
119
120
    /**
121
     * Run FFmpeg to package media content
122
     */
123
    private function run(): void
124
    {
125
        try {
126
            $this->media
127
                ->addFilter($this->getFilter())
128
                ->save($this->getFormat(), $this->getPath());
129
        } catch (ExceptionInterface $e) {
130
            throw new RuntimeException("An error occurred while saving files: " . $e->getMessage(), $e->getCode(), $e);
131
        }
132
    }
133
134
    /**
135
     * @param $path
136
     * @param $clouds
137
     */
138
    private function paths(?string $path, array $clouds): void
139
    {
140
        if (!empty($clouds)) {
141
            $this->tmp_dir = File::tmpDir();
142
            $this->path = $this->tmp_dir . basename($path ?? $this->path);
143
        } elseif (!is_null($path)) {
144
            if (strlen($path) > PHP_MAXPATHLEN) {
145
                throw new InvalidArgumentException("The path is too long");
146
            }
147
148
            File::makeDir(dirname($path));
149
            $this->path = $path;
150
        } elseif ($this->media->isTmp()) {
151
            throw new InvalidArgumentException("You need to specify a path. It is not possible to save to a tmp directory");
152
        }
153
    }
154
155
    /**
156
     * @param string $path
157
     * @param array $clouds
158
     * @return mixed
159
     */
160
    public function save(string $path = null, array $clouds = [])
161
    {
162
        $this->paths($path, $clouds);
163
        $this->run();
164
        $this->clouds($clouds, $path);
165
166
        return $this;
167
    }
168
169
    /**
170
     * @param string $url
171
     */
172
    public function live(string $url): void
173
    {
174
        $this->path = $this->uri = $url;
175
        $this->run();
176
    }
177
178
    /**
179
     * @return Metadata
180
     */
181
    public function metadata(): Metadata
182
    {
183
        return new Metadata($this);
184
    }
185
186
    /**
187
     * clear tmp files
188
     */
189
    public function __destruct()
190
    {
191
        // make sure that FFmpeg process has benn terminated
192
        sleep(1);
193
194
        if ($this->media->isTmp()) {
195
            File::remove($this->media->getPath());
196
        }
197
198
        if ($this->tmp_dir) {
199
            File::remove($this->tmp_dir);
200
        }
201
202
        if ($this instanceof HLS && $this->tmp_key_info_file) {
203
            File::remove($this->getHlsKeyInfoFile());
204
        }
205
    }
206
}