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\StreamFilterInterface; |
||||
19 | use Streaming\Traits\Formats; |
||||
20 | |||||
21 | |||||
22 | abstract class Stream implements StreamInterface |
||||
23 | { |
||||
24 | use Formats; |
||||
25 | |||||
26 | /** @var Media */ |
||||
27 | private $media; |
||||
28 | |||||
29 | /** @var string */ |
||||
30 | protected $path; |
||||
31 | |||||
32 | /** @var string */ |
||||
33 | private $tmp_dir = ''; |
||||
34 | |||||
35 | /** |
||||
36 | * Stream constructor. |
||||
37 | * @param Media $media |
||||
38 | */ |
||||
39 | public function __construct(Media $media) |
||||
40 | { |
||||
41 | $this->media = $media; |
||||
42 | $this->path = $media->getPathfile(); |
||||
0 ignored issues
–
show
|
|||||
43 | } |
||||
44 | |||||
45 | /** |
||||
46 | * @return Media |
||||
47 | */ |
||||
48 | public function getMedia(): Media |
||||
49 | { |
||||
50 | return $this->media; |
||||
51 | } |
||||
52 | |||||
53 | /** |
||||
54 | * @return bool |
||||
55 | */ |
||||
56 | public function isTmpDir(): bool |
||||
57 | { |
||||
58 | return (bool)$this->tmp_dir; |
||||
59 | } |
||||
60 | |||||
61 | /** |
||||
62 | * @param int $option |
||||
63 | * @return string |
||||
64 | */ |
||||
65 | public function pathInfo(int $option): string |
||||
66 | { |
||||
67 | return pathinfo($this->path, $option); |
||||
68 | } |
||||
69 | |||||
70 | /** |
||||
71 | * @param string|null $path |
||||
72 | */ |
||||
73 | private function moveTmp(?string $path): void |
||||
74 | { |
||||
75 | if ($this->isTmpDir() && !is_null($path)) { |
||||
76 | File::move($this->tmp_dir, dirname($path)); |
||||
77 | $this->path = $path; |
||||
78 | $this->tmp_dir = ''; |
||||
79 | } |
||||
80 | } |
||||
81 | |||||
82 | /** |
||||
83 | * @param array $clouds |
||||
84 | * @param string $path |
||||
85 | */ |
||||
86 | private function clouds(array $clouds, ?string $path): void |
||||
87 | { |
||||
88 | if (!empty($clouds)) { |
||||
89 | Cloud::uploadDirectory($clouds, $this->tmp_dir); |
||||
90 | $this->moveTmp($path); |
||||
91 | } |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * @return string |
||||
96 | */ |
||||
97 | protected function getFilePath(): string |
||||
98 | { |
||||
99 | return str_replace( |
||||
100 | "\\", |
||||
101 | "/", |
||||
102 | $this->pathInfo(PATHINFO_DIRNAME) . "/" . $this->pathInfo(PATHINFO_FILENAME) |
||||
103 | ); |
||||
104 | } |
||||
105 | |||||
106 | /** |
||||
107 | * @return string |
||||
108 | */ |
||||
109 | abstract protected function getPath(): string; |
||||
110 | |||||
111 | /** |
||||
112 | * @return StreamFilterInterface |
||||
113 | */ |
||||
114 | abstract protected function getFilter(): StreamFilterInterface; |
||||
115 | |||||
116 | /** |
||||
117 | * Run FFmpeg to package media content |
||||
118 | */ |
||||
119 | private function run(): void |
||||
120 | { |
||||
121 | $this->media->addFilter($this->getFilter()); |
||||
122 | |||||
123 | $commands = (new CommandBuilder($this->media, $this->getFormat()))->build($this->getFormat(), $this->getPath()); |
||||
124 | $pass = $this->format->getPasses(); |
||||
125 | $listeners = $this->format->createProgressListener($this->media->baseMedia(), $this->media->getFFProbe(), 1, $pass); |
||||
0 ignored issues
–
show
$this->media->getFFProbe() of type FFMpeg\Media\Video|Streaming\Media is incompatible with the type FFMpeg\FFProbe expected by parameter $ffprobe of FFMpeg\Format\Video\Defa...reateProgressListener() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
126 | |||||
127 | try { |
||||
128 | $this->media->getFFMpegDriver()->command($commands, false, $listeners); |
||||
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($clouds['options']['filename'] ?? $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 = []): Stream |
||||
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 = $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(.5); |
||||
0 ignored issues
–
show
0.5 of type double is incompatible with the type integer expected by parameter $seconds of sleep() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
193 | File::remove($this->tmp_dir); |
||||
194 | |||||
195 | if ($this->media->isTmp()) { |
||||
196 | File::remove($this->media->getPathfile()); |
||||
0 ignored issues
–
show
$this->media->getPathfile() of type FFMpeg\Media\Video|Streaming\Media is incompatible with the type string expected by parameter $dir of Streaming\File::remove() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
197 | } |
||||
198 | } |
||||
199 | } |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..