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
The method
getPathfile() does not exist on Streaming\Media . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||||
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()); |
||||||||||
0 ignored issues
–
show
The method
addFilter() does not exist on Streaming\Media . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||||
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
![]() The method
getFFProbe() does not exist on Streaming\Media . Since you implemented __call , consider adding a @method annotation.
(
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); |
||||||||||
0 ignored issues
–
show
The method
command() does not exist on Streaming\Media . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() The method
getFFMpegDriver() does not exist on Streaming\Media . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() The method
command() does not exist on FFMpeg\Media\Video .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||||||
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..