├── .gitattributes
├── .gitignore
├── LICENSE
├── Procfile
├── README.md
├── app.json
├── composer.json
├── composer.lock
├── etc
├── links.json
└── youtube_urls.txt
├── phpstan.neon.dist
├── public
├── index.html
├── stream.php
└── video_info.php
├── src
├── Browser.php
├── DownloadOptions.php
├── Exception
│ ├── TooManyRequestsException.php
│ ├── VideoNotFoundException.php
│ ├── VideoPlayerNotFoundException.php
│ └── YouTubeException.php
├── Models
│ ├── AbstractModel.php
│ ├── SplitStream.php
│ ├── StreamFormat.php
│ ├── VideoDetails.php
│ └── VideoInfo.php
├── Responses
│ ├── GetVideoInfo.php
│ ├── HttpResponse.php
│ ├── VideoPlayerJs.php
│ └── WatchVideoPage.php
├── SignatureDecoder.php
├── Utils
│ ├── ITagUtils.php
│ ├── SerializationUtils.php
│ └── Utils.php
├── YouTubeDownloader.php
└── YouTubeStreamer.php
└── tests
├── ArrayTest.php
├── StreamFormatTest.php
├── TestCase.php
├── YouTubePageTest.php
├── YouTubeTest.php
└── YouTubeUrlTest.php
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | .DS_Store
4 | Thumbs.db
5 | /phpunit.xml
6 | /.idea
7 | /.vscode
8 | .phpunit.result.cache
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: vendor/bin/heroku-php-apache2 public/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |   
4 |
5 |
6 |
7 | # youtube-downloader
8 |
9 | This project was inspired by a very popular youtube-dl python package:
10 | https://github.com/rg3/youtube-dl
11 |
12 | Yes, there are multiple other PHP-based youtube downloaders on the Internet,
13 | but most of them haven't been updated in years, or they depend on youtube-dl itself.
14 |
15 | Pure PHP-based youtube downloaders that work, and are **kept-up-to date** just do not exist.
16 |
17 | This script uses no Javascript interpreters, no calls to shell... nothing but pure PHP with no heavy dependencies either.
18 |
19 | 
20 |
21 | That's all there is to it!
22 |
23 | ## :warning: Legal Disclaimer
24 |
25 | This program is for personal use only.
26 | Downloading copyrighted material without permission is against [YouTube's terms of services](https://www.youtube.com/static?template=terms).
27 | By using this program, you are solely responsible for any copyright violations.
28 | We are not responsible for people who attempt to use this program in any way that breaks YouTube's terms of services.
29 |
30 | ## Demo App
31 |
32 | This may not work at all times, because YouTube puts a short ban on the server if it receives too many requests from it.
33 |
34 | - https://youtube-downloader-v3.herokuapp.com/
35 |
36 | 
37 |
38 |
39 | ### Deploy your own App
40 |
41 | on Heroku:
42 |
43 | [](https://heroku.com/deploy)
44 |
45 |
46 | Create a FREE account first if you do not yet have one:
47 | https://signup.heroku.com/
48 |
49 | Installation
50 | -------
51 |
52 | Recommended way of installing this is via [Composer](http://getcomposer.org):
53 |
54 | ```bash
55 | composer require athlon1600/youtube-downloader "^3.0"
56 | ```
57 |
58 | Run locally:
59 |
60 | ```bash
61 | php -S localhost:8000 -t vendor/athlon1600/youtube-downloader/public
62 | ```
63 |
64 | # Previous versions
65 |
66 | Instructions for installing & using Version 2 can be found here:
67 | https://github.com/Athlon1600/youtube-downloader/tree/2.x
68 |
69 | # Usage
70 |
71 |
72 | ```php
73 | use YouTube\YouTubeDownloader;
74 | use YouTube\Exception\YouTubeException;
75 |
76 | $youtube = new YouTubeDownloader();
77 |
78 | try {
79 | $downloadOptions = $youtube->getDownloadLinks("https://www.youtube.com/watch?v=aqz-KE-bpKQ");
80 |
81 | if ($downloadOptions->getAllFormats()) {
82 | echo $downloadOptions->getFirstCombinedFormat()->url;
83 | } else {
84 | echo 'No links found';
85 | }
86 |
87 | } catch (YouTubeException $e) {
88 | echo 'Something went wrong: ' . $e->getMessage();
89 | }
90 | ```
91 |
92 | `getDownloadLinks` method returns a `DownloadOptions` type object, which holds an array of stream links - some that are audio-only, and some that are both audio and video combined into one.
93 |
94 | For typical usage, you are probably interested in dealing with combined streams, for that case, there is the `getCombinedFormats` method.
95 |
96 | ## Other Features
97 |
98 | - Stream YouTube videos directly from your server:
99 |
100 | ```php
101 | $youtube = new \YouTube\YouTubeStreamer();
102 | $youtube->stream('https://r4---sn-n4v7knll.googlevideo.com/videoplayback?...');
103 | ```
104 |
105 | - Pass in your own cookies/user-agent
106 |
107 | If you try downloading age-restricted videos, YouTube will ask you to login. The only way to make this work, is to login to your YouTube account in your own web-browser, export those newly set cookies from your browser into a file, and then pass it all to youtube-downloader for use.
108 |
109 | ```php
110 | $youtube = new YouTubeDownloader();
111 | $youtube->getBrowser()->setCookieFile('./your_cookies.txt');
112 | $youtube->getBrowser()->setUserAgent('Opera 7.6');
113 | ```
114 |
115 | See also:
116 | https://github.com/ytdl-org/youtube-dl/blob/master/README.md#how-do-i-pass-cookies-to-youtube-dl
117 |
118 | - Before you continue to YouTube...
119 |
120 | Depending on your region, you might be force redirected to a [page](https://unblockvideos.com/images/before-you-continue-cookies.jpg) that asks you to agree to Google's cookie policy.
121 | You can programmatically agree to those terms, and bypass that warning permanently via `consentCookies` method on your Browser instance. Example:
122 | ```php
123 | $youtube = new YouTubeDownloader();
124 | $youtube->getBrowser()->consentCookies();
125 | ```
126 |
127 |
128 | ## How does it work
129 |
130 | A more detailed explanation on how to download videos from YouTube will be written soon.
131 | For now, there is this:
132 |
133 | https://github.com/Athlon1600/youtube-downloader/pull/25#issuecomment-439373506
134 |
135 | ## Other Links
136 |
137 | - https://github.com/Athlon1600/php-curl-file-downloader
138 | - https://github.com/TeamNewPipe/NewPipeExtractor/blob/d83787a5ca308c4ca4e86e63a8b63c5e7c4708d6/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java
139 | - https://github.com/ytdl-org/youtube-dl/blob/master/youtube_dl/extractor/youtube.py
140 |
141 | ## To-do list
142 |
143 | - Add ability to solve YouTube Captcha and avoid `HTTP 429 Too Many Requests` errors.
144 | - Add ability to download video and audio streams separately, and merge the two together using ffmpeg. Just like `youtube-dl` does!
145 | - Optional command that finds ALL video formats.
146 | - ~~Fetch additional metadata about the video without using YouTube API.~~
147 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PHP YouTube Downloader",
3 | "description": "PHP powered alternative for youtube-dl",
4 | "repository": "https://github.com/Athlon1600/youtube-downloader/",
5 | "keywords": ["youtube downloader", "download youtube", "download youtube videos"]
6 | }
7 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "athlon1600/youtube-downloader",
3 | "description": "PHP powered alternative for youtube-dl",
4 | "keywords": ["youtube downloader", "download youtube", "download youtube videos"],
5 | "license": "MIT",
6 | "require": {
7 | "php": "^5.6 || ^7.0 || ^8.0",
8 | "ext-curl": "*",
9 | "ext-json": "*",
10 | "athlon1600/php-curl-file-downloader": "^1.0"
11 | },
12 | "require-dev": {
13 | "phpunit/phpunit": "^5.7|6.2|^7.0|^8.0"
14 | },
15 | "autoload": {
16 | "psr-4": {
17 | "YouTube\\": "src/"
18 | }
19 | },
20 | "autoload-dev": {
21 | "psr-4": {
22 | "YouTube\\Tests\\": "tests"
23 | }
24 | },
25 | "scripts": {
26 | "test": "phpunit tests"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "ddc378e0c54e28727731638e63b6c50a",
8 | "packages": [
9 | {
10 | "name": "athlon1600/php-curl-client",
11 | "version": "v1.1.3",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/Athlon1600/php-curl-client.git",
15 | "reference": "2c9a7ac0aea487fcdfc57333dfba6cb684fb64fc"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/Athlon1600/php-curl-client/zipball/2c9a7ac0aea487fcdfc57333dfba6cb684fb64fc",
20 | "reference": "2c9a7ac0aea487fcdfc57333dfba6cb684fb64fc",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "ext-curl": "*",
25 | "ext-json": "*"
26 | },
27 | "require-dev": {
28 | "phpunit/phpunit": "^7.0"
29 | },
30 | "type": "library",
31 | "autoload": {
32 | "psr-4": {
33 | "Curl\\": "src/"
34 | }
35 | },
36 | "notification-url": "https://packagist.org/downloads/",
37 | "license": [
38 | "MIT"
39 | ],
40 | "description": "Simple PHP cURL Client",
41 | "keywords": [
42 | "php curl client"
43 | ],
44 | "support": {
45 | "issues": "https://github.com/Athlon1600/php-curl-client/issues",
46 | "source": "https://github.com/Athlon1600/php-curl-client/tree/v1.1.3"
47 | },
48 | "time": "2021-02-14T17:10:18+00:00"
49 | },
50 | {
51 | "name": "athlon1600/php-curl-file-downloader",
52 | "version": "v1.0.2",
53 | "source": {
54 | "type": "git",
55 | "url": "https://github.com/Athlon1600/php-curl-file-downloader.git",
56 | "reference": "66391a0b89e2ed8b42ed6341e111f180697e0c5f"
57 | },
58 | "dist": {
59 | "type": "zip",
60 | "url": "https://api.github.com/repos/Athlon1600/php-curl-file-downloader/zipball/66391a0b89e2ed8b42ed6341e111f180697e0c5f",
61 | "reference": "66391a0b89e2ed8b42ed6341e111f180697e0c5f",
62 | "shasum": ""
63 | },
64 | "require": {
65 | "athlon1600/php-curl-client": "^1.0",
66 | "ext-curl": "*"
67 | },
68 | "require-dev": {
69 | "phpunit/phpunit": "^7.0"
70 | },
71 | "type": "library",
72 | "autoload": {
73 | "psr-4": {
74 | "CurlDownloader\\": "src/"
75 | }
76 | },
77 | "notification-url": "https://packagist.org/downloads/",
78 | "support": {
79 | "issues": "https://github.com/Athlon1600/php-curl-file-downloader/issues",
80 | "source": "https://github.com/Athlon1600/php-curl-file-downloader/tree/v1.0.2"
81 | },
82 | "time": "2021-02-25T20:29:06+00:00"
83 | }
84 | ],
85 | "packages-dev": [
86 | {
87 | "name": "doctrine/instantiator",
88 | "version": "1.4.0",
89 | "source": {
90 | "type": "git",
91 | "url": "https://github.com/doctrine/instantiator.git",
92 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
93 | },
94 | "dist": {
95 | "type": "zip",
96 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
97 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
98 | "shasum": ""
99 | },
100 | "require": {
101 | "php": "^7.1 || ^8.0"
102 | },
103 | "require-dev": {
104 | "doctrine/coding-standard": "^8.0",
105 | "ext-pdo": "*",
106 | "ext-phar": "*",
107 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
108 | "phpstan/phpstan": "^0.12",
109 | "phpstan/phpstan-phpunit": "^0.12",
110 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
111 | },
112 | "type": "library",
113 | "autoload": {
114 | "psr-4": {
115 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
116 | }
117 | },
118 | "notification-url": "https://packagist.org/downloads/",
119 | "license": [
120 | "MIT"
121 | ],
122 | "authors": [
123 | {
124 | "name": "Marco Pivetta",
125 | "email": "ocramius@gmail.com",
126 | "homepage": "https://ocramius.github.io/"
127 | }
128 | ],
129 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
130 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
131 | "keywords": [
132 | "constructor",
133 | "instantiate"
134 | ],
135 | "support": {
136 | "issues": "https://github.com/doctrine/instantiator/issues",
137 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
138 | },
139 | "funding": [
140 | {
141 | "url": "https://www.doctrine-project.org/sponsorship.html",
142 | "type": "custom"
143 | },
144 | {
145 | "url": "https://www.patreon.com/phpdoctrine",
146 | "type": "patreon"
147 | },
148 | {
149 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
150 | "type": "tidelift"
151 | }
152 | ],
153 | "time": "2020-11-10T18:47:58+00:00"
154 | },
155 | {
156 | "name": "myclabs/deep-copy",
157 | "version": "1.10.2",
158 | "source": {
159 | "type": "git",
160 | "url": "https://github.com/myclabs/DeepCopy.git",
161 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
162 | },
163 | "dist": {
164 | "type": "zip",
165 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
166 | "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
167 | "shasum": ""
168 | },
169 | "require": {
170 | "php": "^7.1 || ^8.0"
171 | },
172 | "replace": {
173 | "myclabs/deep-copy": "self.version"
174 | },
175 | "require-dev": {
176 | "doctrine/collections": "^1.0",
177 | "doctrine/common": "^2.6",
178 | "phpunit/phpunit": "^7.1"
179 | },
180 | "type": "library",
181 | "autoload": {
182 | "psr-4": {
183 | "DeepCopy\\": "src/DeepCopy/"
184 | },
185 | "files": [
186 | "src/DeepCopy/deep_copy.php"
187 | ]
188 | },
189 | "notification-url": "https://packagist.org/downloads/",
190 | "license": [
191 | "MIT"
192 | ],
193 | "description": "Create deep copies (clones) of your objects",
194 | "keywords": [
195 | "clone",
196 | "copy",
197 | "duplicate",
198 | "object",
199 | "object graph"
200 | ],
201 | "support": {
202 | "issues": "https://github.com/myclabs/DeepCopy/issues",
203 | "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
204 | },
205 | "funding": [
206 | {
207 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
208 | "type": "tidelift"
209 | }
210 | ],
211 | "time": "2020-11-13T09:40:50+00:00"
212 | },
213 | {
214 | "name": "phar-io/manifest",
215 | "version": "2.0.1",
216 | "source": {
217 | "type": "git",
218 | "url": "https://github.com/phar-io/manifest.git",
219 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
220 | },
221 | "dist": {
222 | "type": "zip",
223 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
224 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
225 | "shasum": ""
226 | },
227 | "require": {
228 | "ext-dom": "*",
229 | "ext-phar": "*",
230 | "ext-xmlwriter": "*",
231 | "phar-io/version": "^3.0.1",
232 | "php": "^7.2 || ^8.0"
233 | },
234 | "type": "library",
235 | "extra": {
236 | "branch-alias": {
237 | "dev-master": "2.0.x-dev"
238 | }
239 | },
240 | "autoload": {
241 | "classmap": [
242 | "src/"
243 | ]
244 | },
245 | "notification-url": "https://packagist.org/downloads/",
246 | "license": [
247 | "BSD-3-Clause"
248 | ],
249 | "authors": [
250 | {
251 | "name": "Arne Blankerts",
252 | "email": "arne@blankerts.de",
253 | "role": "Developer"
254 | },
255 | {
256 | "name": "Sebastian Heuer",
257 | "email": "sebastian@phpeople.de",
258 | "role": "Developer"
259 | },
260 | {
261 | "name": "Sebastian Bergmann",
262 | "email": "sebastian@phpunit.de",
263 | "role": "Developer"
264 | }
265 | ],
266 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
267 | "support": {
268 | "issues": "https://github.com/phar-io/manifest/issues",
269 | "source": "https://github.com/phar-io/manifest/tree/master"
270 | },
271 | "time": "2020-06-27T14:33:11+00:00"
272 | },
273 | {
274 | "name": "phar-io/version",
275 | "version": "3.1.0",
276 | "source": {
277 | "type": "git",
278 | "url": "https://github.com/phar-io/version.git",
279 | "reference": "bae7c545bef187884426f042434e561ab1ddb182"
280 | },
281 | "dist": {
282 | "type": "zip",
283 | "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
284 | "reference": "bae7c545bef187884426f042434e561ab1ddb182",
285 | "shasum": ""
286 | },
287 | "require": {
288 | "php": "^7.2 || ^8.0"
289 | },
290 | "type": "library",
291 | "autoload": {
292 | "classmap": [
293 | "src/"
294 | ]
295 | },
296 | "notification-url": "https://packagist.org/downloads/",
297 | "license": [
298 | "BSD-3-Clause"
299 | ],
300 | "authors": [
301 | {
302 | "name": "Arne Blankerts",
303 | "email": "arne@blankerts.de",
304 | "role": "Developer"
305 | },
306 | {
307 | "name": "Sebastian Heuer",
308 | "email": "sebastian@phpeople.de",
309 | "role": "Developer"
310 | },
311 | {
312 | "name": "Sebastian Bergmann",
313 | "email": "sebastian@phpunit.de",
314 | "role": "Developer"
315 | }
316 | ],
317 | "description": "Library for handling version information and constraints",
318 | "support": {
319 | "issues": "https://github.com/phar-io/version/issues",
320 | "source": "https://github.com/phar-io/version/tree/3.1.0"
321 | },
322 | "time": "2021-02-23T14:00:09+00:00"
323 | },
324 | {
325 | "name": "phpdocumentor/reflection-common",
326 | "version": "2.2.0",
327 | "source": {
328 | "type": "git",
329 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
330 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
331 | },
332 | "dist": {
333 | "type": "zip",
334 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
335 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
336 | "shasum": ""
337 | },
338 | "require": {
339 | "php": "^7.2 || ^8.0"
340 | },
341 | "type": "library",
342 | "extra": {
343 | "branch-alias": {
344 | "dev-2.x": "2.x-dev"
345 | }
346 | },
347 | "autoload": {
348 | "psr-4": {
349 | "phpDocumentor\\Reflection\\": "src/"
350 | }
351 | },
352 | "notification-url": "https://packagist.org/downloads/",
353 | "license": [
354 | "MIT"
355 | ],
356 | "authors": [
357 | {
358 | "name": "Jaap van Otterdijk",
359 | "email": "opensource@ijaap.nl"
360 | }
361 | ],
362 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
363 | "homepage": "http://www.phpdoc.org",
364 | "keywords": [
365 | "FQSEN",
366 | "phpDocumentor",
367 | "phpdoc",
368 | "reflection",
369 | "static analysis"
370 | ],
371 | "support": {
372 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
373 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
374 | },
375 | "time": "2020-06-27T09:03:43+00:00"
376 | },
377 | {
378 | "name": "phpdocumentor/reflection-docblock",
379 | "version": "5.2.2",
380 | "source": {
381 | "type": "git",
382 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
383 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
384 | },
385 | "dist": {
386 | "type": "zip",
387 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
388 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
389 | "shasum": ""
390 | },
391 | "require": {
392 | "ext-filter": "*",
393 | "php": "^7.2 || ^8.0",
394 | "phpdocumentor/reflection-common": "^2.2",
395 | "phpdocumentor/type-resolver": "^1.3",
396 | "webmozart/assert": "^1.9.1"
397 | },
398 | "require-dev": {
399 | "mockery/mockery": "~1.3.2"
400 | },
401 | "type": "library",
402 | "extra": {
403 | "branch-alias": {
404 | "dev-master": "5.x-dev"
405 | }
406 | },
407 | "autoload": {
408 | "psr-4": {
409 | "phpDocumentor\\Reflection\\": "src"
410 | }
411 | },
412 | "notification-url": "https://packagist.org/downloads/",
413 | "license": [
414 | "MIT"
415 | ],
416 | "authors": [
417 | {
418 | "name": "Mike van Riel",
419 | "email": "me@mikevanriel.com"
420 | },
421 | {
422 | "name": "Jaap van Otterdijk",
423 | "email": "account@ijaap.nl"
424 | }
425 | ],
426 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
427 | "support": {
428 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
429 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
430 | },
431 | "time": "2020-09-03T19:13:55+00:00"
432 | },
433 | {
434 | "name": "phpdocumentor/type-resolver",
435 | "version": "1.4.0",
436 | "source": {
437 | "type": "git",
438 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
439 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
440 | },
441 | "dist": {
442 | "type": "zip",
443 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
444 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
445 | "shasum": ""
446 | },
447 | "require": {
448 | "php": "^7.2 || ^8.0",
449 | "phpdocumentor/reflection-common": "^2.0"
450 | },
451 | "require-dev": {
452 | "ext-tokenizer": "*"
453 | },
454 | "type": "library",
455 | "extra": {
456 | "branch-alias": {
457 | "dev-1.x": "1.x-dev"
458 | }
459 | },
460 | "autoload": {
461 | "psr-4": {
462 | "phpDocumentor\\Reflection\\": "src"
463 | }
464 | },
465 | "notification-url": "https://packagist.org/downloads/",
466 | "license": [
467 | "MIT"
468 | ],
469 | "authors": [
470 | {
471 | "name": "Mike van Riel",
472 | "email": "me@mikevanriel.com"
473 | }
474 | ],
475 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
476 | "support": {
477 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
478 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
479 | },
480 | "time": "2020-09-17T18:55:26+00:00"
481 | },
482 | {
483 | "name": "phpspec/prophecy",
484 | "version": "1.13.0",
485 | "source": {
486 | "type": "git",
487 | "url": "https://github.com/phpspec/prophecy.git",
488 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
489 | },
490 | "dist": {
491 | "type": "zip",
492 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
493 | "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
494 | "shasum": ""
495 | },
496 | "require": {
497 | "doctrine/instantiator": "^1.2",
498 | "php": "^7.2 || ~8.0, <8.1",
499 | "phpdocumentor/reflection-docblock": "^5.2",
500 | "sebastian/comparator": "^3.0 || ^4.0",
501 | "sebastian/recursion-context": "^3.0 || ^4.0"
502 | },
503 | "require-dev": {
504 | "phpspec/phpspec": "^6.0",
505 | "phpunit/phpunit": "^8.0 || ^9.0"
506 | },
507 | "type": "library",
508 | "extra": {
509 | "branch-alias": {
510 | "dev-master": "1.11.x-dev"
511 | }
512 | },
513 | "autoload": {
514 | "psr-4": {
515 | "Prophecy\\": "src/Prophecy"
516 | }
517 | },
518 | "notification-url": "https://packagist.org/downloads/",
519 | "license": [
520 | "MIT"
521 | ],
522 | "authors": [
523 | {
524 | "name": "Konstantin Kudryashov",
525 | "email": "ever.zet@gmail.com",
526 | "homepage": "http://everzet.com"
527 | },
528 | {
529 | "name": "Marcello Duarte",
530 | "email": "marcello.duarte@gmail.com"
531 | }
532 | ],
533 | "description": "Highly opinionated mocking framework for PHP 5.3+",
534 | "homepage": "https://github.com/phpspec/prophecy",
535 | "keywords": [
536 | "Double",
537 | "Dummy",
538 | "fake",
539 | "mock",
540 | "spy",
541 | "stub"
542 | ],
543 | "support": {
544 | "issues": "https://github.com/phpspec/prophecy/issues",
545 | "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
546 | },
547 | "time": "2021-03-17T13:42:18+00:00"
548 | },
549 | {
550 | "name": "phpunit/php-code-coverage",
551 | "version": "7.0.14",
552 | "source": {
553 | "type": "git",
554 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
555 | "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c"
556 | },
557 | "dist": {
558 | "type": "zip",
559 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c",
560 | "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c",
561 | "shasum": ""
562 | },
563 | "require": {
564 | "ext-dom": "*",
565 | "ext-xmlwriter": "*",
566 | "php": ">=7.2",
567 | "phpunit/php-file-iterator": "^2.0.2",
568 | "phpunit/php-text-template": "^1.2.1",
569 | "phpunit/php-token-stream": "^3.1.1 || ^4.0",
570 | "sebastian/code-unit-reverse-lookup": "^1.0.1",
571 | "sebastian/environment": "^4.2.2",
572 | "sebastian/version": "^2.0.1",
573 | "theseer/tokenizer": "^1.1.3"
574 | },
575 | "require-dev": {
576 | "phpunit/phpunit": "^8.2.2"
577 | },
578 | "suggest": {
579 | "ext-xdebug": "^2.7.2"
580 | },
581 | "type": "library",
582 | "extra": {
583 | "branch-alias": {
584 | "dev-master": "7.0-dev"
585 | }
586 | },
587 | "autoload": {
588 | "classmap": [
589 | "src/"
590 | ]
591 | },
592 | "notification-url": "https://packagist.org/downloads/",
593 | "license": [
594 | "BSD-3-Clause"
595 | ],
596 | "authors": [
597 | {
598 | "name": "Sebastian Bergmann",
599 | "email": "sebastian@phpunit.de",
600 | "role": "lead"
601 | }
602 | ],
603 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
604 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
605 | "keywords": [
606 | "coverage",
607 | "testing",
608 | "xunit"
609 | ],
610 | "support": {
611 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
612 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14"
613 | },
614 | "funding": [
615 | {
616 | "url": "https://github.com/sebastianbergmann",
617 | "type": "github"
618 | }
619 | ],
620 | "time": "2020-12-02T13:39:03+00:00"
621 | },
622 | {
623 | "name": "phpunit/php-file-iterator",
624 | "version": "2.0.3",
625 | "source": {
626 | "type": "git",
627 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
628 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357"
629 | },
630 | "dist": {
631 | "type": "zip",
632 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357",
633 | "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357",
634 | "shasum": ""
635 | },
636 | "require": {
637 | "php": ">=7.1"
638 | },
639 | "require-dev": {
640 | "phpunit/phpunit": "^8.5"
641 | },
642 | "type": "library",
643 | "extra": {
644 | "branch-alias": {
645 | "dev-master": "2.0.x-dev"
646 | }
647 | },
648 | "autoload": {
649 | "classmap": [
650 | "src/"
651 | ]
652 | },
653 | "notification-url": "https://packagist.org/downloads/",
654 | "license": [
655 | "BSD-3-Clause"
656 | ],
657 | "authors": [
658 | {
659 | "name": "Sebastian Bergmann",
660 | "email": "sebastian@phpunit.de",
661 | "role": "lead"
662 | }
663 | ],
664 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
665 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
666 | "keywords": [
667 | "filesystem",
668 | "iterator"
669 | ],
670 | "support": {
671 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
672 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3"
673 | },
674 | "funding": [
675 | {
676 | "url": "https://github.com/sebastianbergmann",
677 | "type": "github"
678 | }
679 | ],
680 | "time": "2020-11-30T08:25:21+00:00"
681 | },
682 | {
683 | "name": "phpunit/php-text-template",
684 | "version": "1.2.1",
685 | "source": {
686 | "type": "git",
687 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
688 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
689 | },
690 | "dist": {
691 | "type": "zip",
692 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
693 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
694 | "shasum": ""
695 | },
696 | "require": {
697 | "php": ">=5.3.3"
698 | },
699 | "type": "library",
700 | "autoload": {
701 | "classmap": [
702 | "src/"
703 | ]
704 | },
705 | "notification-url": "https://packagist.org/downloads/",
706 | "license": [
707 | "BSD-3-Clause"
708 | ],
709 | "authors": [
710 | {
711 | "name": "Sebastian Bergmann",
712 | "email": "sebastian@phpunit.de",
713 | "role": "lead"
714 | }
715 | ],
716 | "description": "Simple template engine.",
717 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
718 | "keywords": [
719 | "template"
720 | ],
721 | "support": {
722 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
723 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
724 | },
725 | "time": "2015-06-21T13:50:34+00:00"
726 | },
727 | {
728 | "name": "phpunit/php-timer",
729 | "version": "2.1.3",
730 | "source": {
731 | "type": "git",
732 | "url": "https://github.com/sebastianbergmann/php-timer.git",
733 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
734 | },
735 | "dist": {
736 | "type": "zip",
737 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
738 | "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
739 | "shasum": ""
740 | },
741 | "require": {
742 | "php": ">=7.1"
743 | },
744 | "require-dev": {
745 | "phpunit/phpunit": "^8.5"
746 | },
747 | "type": "library",
748 | "extra": {
749 | "branch-alias": {
750 | "dev-master": "2.1-dev"
751 | }
752 | },
753 | "autoload": {
754 | "classmap": [
755 | "src/"
756 | ]
757 | },
758 | "notification-url": "https://packagist.org/downloads/",
759 | "license": [
760 | "BSD-3-Clause"
761 | ],
762 | "authors": [
763 | {
764 | "name": "Sebastian Bergmann",
765 | "email": "sebastian@phpunit.de",
766 | "role": "lead"
767 | }
768 | ],
769 | "description": "Utility class for timing",
770 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
771 | "keywords": [
772 | "timer"
773 | ],
774 | "support": {
775 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
776 | "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
777 | },
778 | "funding": [
779 | {
780 | "url": "https://github.com/sebastianbergmann",
781 | "type": "github"
782 | }
783 | ],
784 | "time": "2020-11-30T08:20:02+00:00"
785 | },
786 | {
787 | "name": "phpunit/php-token-stream",
788 | "version": "4.0.4",
789 | "source": {
790 | "type": "git",
791 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
792 | "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
793 | },
794 | "dist": {
795 | "type": "zip",
796 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
797 | "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
798 | "shasum": ""
799 | },
800 | "require": {
801 | "ext-tokenizer": "*",
802 | "php": "^7.3 || ^8.0"
803 | },
804 | "require-dev": {
805 | "phpunit/phpunit": "^9.0"
806 | },
807 | "type": "library",
808 | "extra": {
809 | "branch-alias": {
810 | "dev-master": "4.0-dev"
811 | }
812 | },
813 | "autoload": {
814 | "classmap": [
815 | "src/"
816 | ]
817 | },
818 | "notification-url": "https://packagist.org/downloads/",
819 | "license": [
820 | "BSD-3-Clause"
821 | ],
822 | "authors": [
823 | {
824 | "name": "Sebastian Bergmann",
825 | "email": "sebastian@phpunit.de"
826 | }
827 | ],
828 | "description": "Wrapper around PHP's tokenizer extension.",
829 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
830 | "keywords": [
831 | "tokenizer"
832 | ],
833 | "support": {
834 | "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
835 | "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
836 | },
837 | "funding": [
838 | {
839 | "url": "https://github.com/sebastianbergmann",
840 | "type": "github"
841 | }
842 | ],
843 | "abandoned": true,
844 | "time": "2020-08-04T08:28:15+00:00"
845 | },
846 | {
847 | "name": "phpunit/phpunit",
848 | "version": "8.5.17",
849 | "source": {
850 | "type": "git",
851 | "url": "https://github.com/sebastianbergmann/phpunit.git",
852 | "reference": "79067856d85421c56d413bd238d4e2cd6b0e54da"
853 | },
854 | "dist": {
855 | "type": "zip",
856 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/79067856d85421c56d413bd238d4e2cd6b0e54da",
857 | "reference": "79067856d85421c56d413bd238d4e2cd6b0e54da",
858 | "shasum": ""
859 | },
860 | "require": {
861 | "doctrine/instantiator": "^1.3.1",
862 | "ext-dom": "*",
863 | "ext-json": "*",
864 | "ext-libxml": "*",
865 | "ext-mbstring": "*",
866 | "ext-xml": "*",
867 | "ext-xmlwriter": "*",
868 | "myclabs/deep-copy": "^1.10.0",
869 | "phar-io/manifest": "^2.0.1",
870 | "phar-io/version": "^3.0.2",
871 | "php": ">=7.2",
872 | "phpspec/prophecy": "^1.10.3",
873 | "phpunit/php-code-coverage": "^7.0.12",
874 | "phpunit/php-file-iterator": "^2.0.2",
875 | "phpunit/php-text-template": "^1.2.1",
876 | "phpunit/php-timer": "^2.1.2",
877 | "sebastian/comparator": "^3.0.2",
878 | "sebastian/diff": "^3.0.2",
879 | "sebastian/environment": "^4.2.3",
880 | "sebastian/exporter": "^3.1.2",
881 | "sebastian/global-state": "^3.0.0",
882 | "sebastian/object-enumerator": "^3.0.3",
883 | "sebastian/resource-operations": "^2.0.1",
884 | "sebastian/type": "^1.1.3",
885 | "sebastian/version": "^2.0.1"
886 | },
887 | "require-dev": {
888 | "ext-pdo": "*"
889 | },
890 | "suggest": {
891 | "ext-soap": "*",
892 | "ext-xdebug": "*",
893 | "phpunit/php-invoker": "^2.0.0"
894 | },
895 | "bin": [
896 | "phpunit"
897 | ],
898 | "type": "library",
899 | "extra": {
900 | "branch-alias": {
901 | "dev-master": "8.5-dev"
902 | }
903 | },
904 | "autoload": {
905 | "classmap": [
906 | "src/"
907 | ]
908 | },
909 | "notification-url": "https://packagist.org/downloads/",
910 | "license": [
911 | "BSD-3-Clause"
912 | ],
913 | "authors": [
914 | {
915 | "name": "Sebastian Bergmann",
916 | "email": "sebastian@phpunit.de",
917 | "role": "lead"
918 | }
919 | ],
920 | "description": "The PHP Unit Testing framework.",
921 | "homepage": "https://phpunit.de/",
922 | "keywords": [
923 | "phpunit",
924 | "testing",
925 | "xunit"
926 | ],
927 | "support": {
928 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
929 | "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.17"
930 | },
931 | "funding": [
932 | {
933 | "url": "https://phpunit.de/donate.html",
934 | "type": "custom"
935 | },
936 | {
937 | "url": "https://github.com/sebastianbergmann",
938 | "type": "github"
939 | }
940 | ],
941 | "time": "2021-06-23T05:12:43+00:00"
942 | },
943 | {
944 | "name": "sebastian/code-unit-reverse-lookup",
945 | "version": "1.0.2",
946 | "source": {
947 | "type": "git",
948 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
949 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
950 | },
951 | "dist": {
952 | "type": "zip",
953 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
954 | "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
955 | "shasum": ""
956 | },
957 | "require": {
958 | "php": ">=5.6"
959 | },
960 | "require-dev": {
961 | "phpunit/phpunit": "^8.5"
962 | },
963 | "type": "library",
964 | "extra": {
965 | "branch-alias": {
966 | "dev-master": "1.0.x-dev"
967 | }
968 | },
969 | "autoload": {
970 | "classmap": [
971 | "src/"
972 | ]
973 | },
974 | "notification-url": "https://packagist.org/downloads/",
975 | "license": [
976 | "BSD-3-Clause"
977 | ],
978 | "authors": [
979 | {
980 | "name": "Sebastian Bergmann",
981 | "email": "sebastian@phpunit.de"
982 | }
983 | ],
984 | "description": "Looks up which function or method a line of code belongs to",
985 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
986 | "support": {
987 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
988 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
989 | },
990 | "funding": [
991 | {
992 | "url": "https://github.com/sebastianbergmann",
993 | "type": "github"
994 | }
995 | ],
996 | "time": "2020-11-30T08:15:22+00:00"
997 | },
998 | {
999 | "name": "sebastian/comparator",
1000 | "version": "3.0.3",
1001 | "source": {
1002 | "type": "git",
1003 | "url": "https://github.com/sebastianbergmann/comparator.git",
1004 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
1005 | },
1006 | "dist": {
1007 | "type": "zip",
1008 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
1009 | "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
1010 | "shasum": ""
1011 | },
1012 | "require": {
1013 | "php": ">=7.1",
1014 | "sebastian/diff": "^3.0",
1015 | "sebastian/exporter": "^3.1"
1016 | },
1017 | "require-dev": {
1018 | "phpunit/phpunit": "^8.5"
1019 | },
1020 | "type": "library",
1021 | "extra": {
1022 | "branch-alias": {
1023 | "dev-master": "3.0-dev"
1024 | }
1025 | },
1026 | "autoload": {
1027 | "classmap": [
1028 | "src/"
1029 | ]
1030 | },
1031 | "notification-url": "https://packagist.org/downloads/",
1032 | "license": [
1033 | "BSD-3-Clause"
1034 | ],
1035 | "authors": [
1036 | {
1037 | "name": "Sebastian Bergmann",
1038 | "email": "sebastian@phpunit.de"
1039 | },
1040 | {
1041 | "name": "Jeff Welch",
1042 | "email": "whatthejeff@gmail.com"
1043 | },
1044 | {
1045 | "name": "Volker Dusch",
1046 | "email": "github@wallbash.com"
1047 | },
1048 | {
1049 | "name": "Bernhard Schussek",
1050 | "email": "bschussek@2bepublished.at"
1051 | }
1052 | ],
1053 | "description": "Provides the functionality to compare PHP values for equality",
1054 | "homepage": "https://github.com/sebastianbergmann/comparator",
1055 | "keywords": [
1056 | "comparator",
1057 | "compare",
1058 | "equality"
1059 | ],
1060 | "support": {
1061 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1062 | "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
1063 | },
1064 | "funding": [
1065 | {
1066 | "url": "https://github.com/sebastianbergmann",
1067 | "type": "github"
1068 | }
1069 | ],
1070 | "time": "2020-11-30T08:04:30+00:00"
1071 | },
1072 | {
1073 | "name": "sebastian/diff",
1074 | "version": "3.0.3",
1075 | "source": {
1076 | "type": "git",
1077 | "url": "https://github.com/sebastianbergmann/diff.git",
1078 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
1079 | },
1080 | "dist": {
1081 | "type": "zip",
1082 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
1083 | "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
1084 | "shasum": ""
1085 | },
1086 | "require": {
1087 | "php": ">=7.1"
1088 | },
1089 | "require-dev": {
1090 | "phpunit/phpunit": "^7.5 || ^8.0",
1091 | "symfony/process": "^2 || ^3.3 || ^4"
1092 | },
1093 | "type": "library",
1094 | "extra": {
1095 | "branch-alias": {
1096 | "dev-master": "3.0-dev"
1097 | }
1098 | },
1099 | "autoload": {
1100 | "classmap": [
1101 | "src/"
1102 | ]
1103 | },
1104 | "notification-url": "https://packagist.org/downloads/",
1105 | "license": [
1106 | "BSD-3-Clause"
1107 | ],
1108 | "authors": [
1109 | {
1110 | "name": "Sebastian Bergmann",
1111 | "email": "sebastian@phpunit.de"
1112 | },
1113 | {
1114 | "name": "Kore Nordmann",
1115 | "email": "mail@kore-nordmann.de"
1116 | }
1117 | ],
1118 | "description": "Diff implementation",
1119 | "homepage": "https://github.com/sebastianbergmann/diff",
1120 | "keywords": [
1121 | "diff",
1122 | "udiff",
1123 | "unidiff",
1124 | "unified diff"
1125 | ],
1126 | "support": {
1127 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1128 | "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
1129 | },
1130 | "funding": [
1131 | {
1132 | "url": "https://github.com/sebastianbergmann",
1133 | "type": "github"
1134 | }
1135 | ],
1136 | "time": "2020-11-30T07:59:04+00:00"
1137 | },
1138 | {
1139 | "name": "sebastian/environment",
1140 | "version": "4.2.4",
1141 | "source": {
1142 | "type": "git",
1143 | "url": "https://github.com/sebastianbergmann/environment.git",
1144 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
1145 | },
1146 | "dist": {
1147 | "type": "zip",
1148 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
1149 | "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
1150 | "shasum": ""
1151 | },
1152 | "require": {
1153 | "php": ">=7.1"
1154 | },
1155 | "require-dev": {
1156 | "phpunit/phpunit": "^7.5"
1157 | },
1158 | "suggest": {
1159 | "ext-posix": "*"
1160 | },
1161 | "type": "library",
1162 | "extra": {
1163 | "branch-alias": {
1164 | "dev-master": "4.2-dev"
1165 | }
1166 | },
1167 | "autoload": {
1168 | "classmap": [
1169 | "src/"
1170 | ]
1171 | },
1172 | "notification-url": "https://packagist.org/downloads/",
1173 | "license": [
1174 | "BSD-3-Clause"
1175 | ],
1176 | "authors": [
1177 | {
1178 | "name": "Sebastian Bergmann",
1179 | "email": "sebastian@phpunit.de"
1180 | }
1181 | ],
1182 | "description": "Provides functionality to handle HHVM/PHP environments",
1183 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1184 | "keywords": [
1185 | "Xdebug",
1186 | "environment",
1187 | "hhvm"
1188 | ],
1189 | "support": {
1190 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1191 | "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
1192 | },
1193 | "funding": [
1194 | {
1195 | "url": "https://github.com/sebastianbergmann",
1196 | "type": "github"
1197 | }
1198 | ],
1199 | "time": "2020-11-30T07:53:42+00:00"
1200 | },
1201 | {
1202 | "name": "sebastian/exporter",
1203 | "version": "3.1.3",
1204 | "source": {
1205 | "type": "git",
1206 | "url": "https://github.com/sebastianbergmann/exporter.git",
1207 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
1208 | },
1209 | "dist": {
1210 | "type": "zip",
1211 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
1212 | "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
1213 | "shasum": ""
1214 | },
1215 | "require": {
1216 | "php": ">=7.0",
1217 | "sebastian/recursion-context": "^3.0"
1218 | },
1219 | "require-dev": {
1220 | "ext-mbstring": "*",
1221 | "phpunit/phpunit": "^6.0"
1222 | },
1223 | "type": "library",
1224 | "extra": {
1225 | "branch-alias": {
1226 | "dev-master": "3.1.x-dev"
1227 | }
1228 | },
1229 | "autoload": {
1230 | "classmap": [
1231 | "src/"
1232 | ]
1233 | },
1234 | "notification-url": "https://packagist.org/downloads/",
1235 | "license": [
1236 | "BSD-3-Clause"
1237 | ],
1238 | "authors": [
1239 | {
1240 | "name": "Sebastian Bergmann",
1241 | "email": "sebastian@phpunit.de"
1242 | },
1243 | {
1244 | "name": "Jeff Welch",
1245 | "email": "whatthejeff@gmail.com"
1246 | },
1247 | {
1248 | "name": "Volker Dusch",
1249 | "email": "github@wallbash.com"
1250 | },
1251 | {
1252 | "name": "Adam Harvey",
1253 | "email": "aharvey@php.net"
1254 | },
1255 | {
1256 | "name": "Bernhard Schussek",
1257 | "email": "bschussek@gmail.com"
1258 | }
1259 | ],
1260 | "description": "Provides the functionality to export PHP variables for visualization",
1261 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1262 | "keywords": [
1263 | "export",
1264 | "exporter"
1265 | ],
1266 | "support": {
1267 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1268 | "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3"
1269 | },
1270 | "funding": [
1271 | {
1272 | "url": "https://github.com/sebastianbergmann",
1273 | "type": "github"
1274 | }
1275 | ],
1276 | "time": "2020-11-30T07:47:53+00:00"
1277 | },
1278 | {
1279 | "name": "sebastian/global-state",
1280 | "version": "3.0.1",
1281 | "source": {
1282 | "type": "git",
1283 | "url": "https://github.com/sebastianbergmann/global-state.git",
1284 | "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b"
1285 | },
1286 | "dist": {
1287 | "type": "zip",
1288 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b",
1289 | "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b",
1290 | "shasum": ""
1291 | },
1292 | "require": {
1293 | "php": ">=7.2",
1294 | "sebastian/object-reflector": "^1.1.1",
1295 | "sebastian/recursion-context": "^3.0"
1296 | },
1297 | "require-dev": {
1298 | "ext-dom": "*",
1299 | "phpunit/phpunit": "^8.0"
1300 | },
1301 | "suggest": {
1302 | "ext-uopz": "*"
1303 | },
1304 | "type": "library",
1305 | "extra": {
1306 | "branch-alias": {
1307 | "dev-master": "3.0-dev"
1308 | }
1309 | },
1310 | "autoload": {
1311 | "classmap": [
1312 | "src/"
1313 | ]
1314 | },
1315 | "notification-url": "https://packagist.org/downloads/",
1316 | "license": [
1317 | "BSD-3-Clause"
1318 | ],
1319 | "authors": [
1320 | {
1321 | "name": "Sebastian Bergmann",
1322 | "email": "sebastian@phpunit.de"
1323 | }
1324 | ],
1325 | "description": "Snapshotting of global state",
1326 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1327 | "keywords": [
1328 | "global state"
1329 | ],
1330 | "support": {
1331 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1332 | "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1"
1333 | },
1334 | "funding": [
1335 | {
1336 | "url": "https://github.com/sebastianbergmann",
1337 | "type": "github"
1338 | }
1339 | ],
1340 | "time": "2020-11-30T07:43:24+00:00"
1341 | },
1342 | {
1343 | "name": "sebastian/object-enumerator",
1344 | "version": "3.0.4",
1345 | "source": {
1346 | "type": "git",
1347 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1348 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
1349 | },
1350 | "dist": {
1351 | "type": "zip",
1352 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1353 | "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
1354 | "shasum": ""
1355 | },
1356 | "require": {
1357 | "php": ">=7.0",
1358 | "sebastian/object-reflector": "^1.1.1",
1359 | "sebastian/recursion-context": "^3.0"
1360 | },
1361 | "require-dev": {
1362 | "phpunit/phpunit": "^6.0"
1363 | },
1364 | "type": "library",
1365 | "extra": {
1366 | "branch-alias": {
1367 | "dev-master": "3.0.x-dev"
1368 | }
1369 | },
1370 | "autoload": {
1371 | "classmap": [
1372 | "src/"
1373 | ]
1374 | },
1375 | "notification-url": "https://packagist.org/downloads/",
1376 | "license": [
1377 | "BSD-3-Clause"
1378 | ],
1379 | "authors": [
1380 | {
1381 | "name": "Sebastian Bergmann",
1382 | "email": "sebastian@phpunit.de"
1383 | }
1384 | ],
1385 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1386 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1387 | "support": {
1388 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1389 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
1390 | },
1391 | "funding": [
1392 | {
1393 | "url": "https://github.com/sebastianbergmann",
1394 | "type": "github"
1395 | }
1396 | ],
1397 | "time": "2020-11-30T07:40:27+00:00"
1398 | },
1399 | {
1400 | "name": "sebastian/object-reflector",
1401 | "version": "1.1.2",
1402 | "source": {
1403 | "type": "git",
1404 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1405 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
1406 | },
1407 | "dist": {
1408 | "type": "zip",
1409 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1410 | "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
1411 | "shasum": ""
1412 | },
1413 | "require": {
1414 | "php": ">=7.0"
1415 | },
1416 | "require-dev": {
1417 | "phpunit/phpunit": "^6.0"
1418 | },
1419 | "type": "library",
1420 | "extra": {
1421 | "branch-alias": {
1422 | "dev-master": "1.1-dev"
1423 | }
1424 | },
1425 | "autoload": {
1426 | "classmap": [
1427 | "src/"
1428 | ]
1429 | },
1430 | "notification-url": "https://packagist.org/downloads/",
1431 | "license": [
1432 | "BSD-3-Clause"
1433 | ],
1434 | "authors": [
1435 | {
1436 | "name": "Sebastian Bergmann",
1437 | "email": "sebastian@phpunit.de"
1438 | }
1439 | ],
1440 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1441 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1442 | "support": {
1443 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1444 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
1445 | },
1446 | "funding": [
1447 | {
1448 | "url": "https://github.com/sebastianbergmann",
1449 | "type": "github"
1450 | }
1451 | ],
1452 | "time": "2020-11-30T07:37:18+00:00"
1453 | },
1454 | {
1455 | "name": "sebastian/recursion-context",
1456 | "version": "3.0.1",
1457 | "source": {
1458 | "type": "git",
1459 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1460 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
1461 | },
1462 | "dist": {
1463 | "type": "zip",
1464 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
1465 | "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
1466 | "shasum": ""
1467 | },
1468 | "require": {
1469 | "php": ">=7.0"
1470 | },
1471 | "require-dev": {
1472 | "phpunit/phpunit": "^6.0"
1473 | },
1474 | "type": "library",
1475 | "extra": {
1476 | "branch-alias": {
1477 | "dev-master": "3.0.x-dev"
1478 | }
1479 | },
1480 | "autoload": {
1481 | "classmap": [
1482 | "src/"
1483 | ]
1484 | },
1485 | "notification-url": "https://packagist.org/downloads/",
1486 | "license": [
1487 | "BSD-3-Clause"
1488 | ],
1489 | "authors": [
1490 | {
1491 | "name": "Sebastian Bergmann",
1492 | "email": "sebastian@phpunit.de"
1493 | },
1494 | {
1495 | "name": "Jeff Welch",
1496 | "email": "whatthejeff@gmail.com"
1497 | },
1498 | {
1499 | "name": "Adam Harvey",
1500 | "email": "aharvey@php.net"
1501 | }
1502 | ],
1503 | "description": "Provides functionality to recursively process PHP variables",
1504 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1505 | "support": {
1506 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1507 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
1508 | },
1509 | "funding": [
1510 | {
1511 | "url": "https://github.com/sebastianbergmann",
1512 | "type": "github"
1513 | }
1514 | ],
1515 | "time": "2020-11-30T07:34:24+00:00"
1516 | },
1517 | {
1518 | "name": "sebastian/resource-operations",
1519 | "version": "2.0.2",
1520 | "source": {
1521 | "type": "git",
1522 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1523 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
1524 | },
1525 | "dist": {
1526 | "type": "zip",
1527 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1528 | "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
1529 | "shasum": ""
1530 | },
1531 | "require": {
1532 | "php": ">=7.1"
1533 | },
1534 | "type": "library",
1535 | "extra": {
1536 | "branch-alias": {
1537 | "dev-master": "2.0-dev"
1538 | }
1539 | },
1540 | "autoload": {
1541 | "classmap": [
1542 | "src/"
1543 | ]
1544 | },
1545 | "notification-url": "https://packagist.org/downloads/",
1546 | "license": [
1547 | "BSD-3-Clause"
1548 | ],
1549 | "authors": [
1550 | {
1551 | "name": "Sebastian Bergmann",
1552 | "email": "sebastian@phpunit.de"
1553 | }
1554 | ],
1555 | "description": "Provides a list of PHP built-in functions that operate on resources",
1556 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1557 | "support": {
1558 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1559 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
1560 | },
1561 | "funding": [
1562 | {
1563 | "url": "https://github.com/sebastianbergmann",
1564 | "type": "github"
1565 | }
1566 | ],
1567 | "time": "2020-11-30T07:30:19+00:00"
1568 | },
1569 | {
1570 | "name": "sebastian/type",
1571 | "version": "1.1.4",
1572 | "source": {
1573 | "type": "git",
1574 | "url": "https://github.com/sebastianbergmann/type.git",
1575 | "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4"
1576 | },
1577 | "dist": {
1578 | "type": "zip",
1579 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4",
1580 | "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4",
1581 | "shasum": ""
1582 | },
1583 | "require": {
1584 | "php": ">=7.2"
1585 | },
1586 | "require-dev": {
1587 | "phpunit/phpunit": "^8.2"
1588 | },
1589 | "type": "library",
1590 | "extra": {
1591 | "branch-alias": {
1592 | "dev-master": "1.1-dev"
1593 | }
1594 | },
1595 | "autoload": {
1596 | "classmap": [
1597 | "src/"
1598 | ]
1599 | },
1600 | "notification-url": "https://packagist.org/downloads/",
1601 | "license": [
1602 | "BSD-3-Clause"
1603 | ],
1604 | "authors": [
1605 | {
1606 | "name": "Sebastian Bergmann",
1607 | "email": "sebastian@phpunit.de",
1608 | "role": "lead"
1609 | }
1610 | ],
1611 | "description": "Collection of value objects that represent the types of the PHP type system",
1612 | "homepage": "https://github.com/sebastianbergmann/type",
1613 | "support": {
1614 | "issues": "https://github.com/sebastianbergmann/type/issues",
1615 | "source": "https://github.com/sebastianbergmann/type/tree/1.1.4"
1616 | },
1617 | "funding": [
1618 | {
1619 | "url": "https://github.com/sebastianbergmann",
1620 | "type": "github"
1621 | }
1622 | ],
1623 | "time": "2020-11-30T07:25:11+00:00"
1624 | },
1625 | {
1626 | "name": "sebastian/version",
1627 | "version": "2.0.1",
1628 | "source": {
1629 | "type": "git",
1630 | "url": "https://github.com/sebastianbergmann/version.git",
1631 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
1632 | },
1633 | "dist": {
1634 | "type": "zip",
1635 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
1636 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
1637 | "shasum": ""
1638 | },
1639 | "require": {
1640 | "php": ">=5.6"
1641 | },
1642 | "type": "library",
1643 | "extra": {
1644 | "branch-alias": {
1645 | "dev-master": "2.0.x-dev"
1646 | }
1647 | },
1648 | "autoload": {
1649 | "classmap": [
1650 | "src/"
1651 | ]
1652 | },
1653 | "notification-url": "https://packagist.org/downloads/",
1654 | "license": [
1655 | "BSD-3-Clause"
1656 | ],
1657 | "authors": [
1658 | {
1659 | "name": "Sebastian Bergmann",
1660 | "email": "sebastian@phpunit.de",
1661 | "role": "lead"
1662 | }
1663 | ],
1664 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1665 | "homepage": "https://github.com/sebastianbergmann/version",
1666 | "support": {
1667 | "issues": "https://github.com/sebastianbergmann/version/issues",
1668 | "source": "https://github.com/sebastianbergmann/version/tree/master"
1669 | },
1670 | "time": "2016-10-03T07:35:21+00:00"
1671 | },
1672 | {
1673 | "name": "symfony/polyfill-ctype",
1674 | "version": "v1.23.0",
1675 | "source": {
1676 | "type": "git",
1677 | "url": "https://github.com/symfony/polyfill-ctype.git",
1678 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
1679 | },
1680 | "dist": {
1681 | "type": "zip",
1682 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
1683 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
1684 | "shasum": ""
1685 | },
1686 | "require": {
1687 | "php": ">=7.1"
1688 | },
1689 | "suggest": {
1690 | "ext-ctype": "For best performance"
1691 | },
1692 | "type": "library",
1693 | "extra": {
1694 | "branch-alias": {
1695 | "dev-main": "1.23-dev"
1696 | },
1697 | "thanks": {
1698 | "name": "symfony/polyfill",
1699 | "url": "https://github.com/symfony/polyfill"
1700 | }
1701 | },
1702 | "autoload": {
1703 | "psr-4": {
1704 | "Symfony\\Polyfill\\Ctype\\": ""
1705 | },
1706 | "files": [
1707 | "bootstrap.php"
1708 | ]
1709 | },
1710 | "notification-url": "https://packagist.org/downloads/",
1711 | "license": [
1712 | "MIT"
1713 | ],
1714 | "authors": [
1715 | {
1716 | "name": "Gert de Pagter",
1717 | "email": "BackEndTea@gmail.com"
1718 | },
1719 | {
1720 | "name": "Symfony Community",
1721 | "homepage": "https://symfony.com/contributors"
1722 | }
1723 | ],
1724 | "description": "Symfony polyfill for ctype functions",
1725 | "homepage": "https://symfony.com",
1726 | "keywords": [
1727 | "compatibility",
1728 | "ctype",
1729 | "polyfill",
1730 | "portable"
1731 | ],
1732 | "support": {
1733 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
1734 | },
1735 | "funding": [
1736 | {
1737 | "url": "https://symfony.com/sponsor",
1738 | "type": "custom"
1739 | },
1740 | {
1741 | "url": "https://github.com/fabpot",
1742 | "type": "github"
1743 | },
1744 | {
1745 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
1746 | "type": "tidelift"
1747 | }
1748 | ],
1749 | "time": "2021-02-19T12:13:01+00:00"
1750 | },
1751 | {
1752 | "name": "theseer/tokenizer",
1753 | "version": "1.2.0",
1754 | "source": {
1755 | "type": "git",
1756 | "url": "https://github.com/theseer/tokenizer.git",
1757 | "reference": "75a63c33a8577608444246075ea0af0d052e452a"
1758 | },
1759 | "dist": {
1760 | "type": "zip",
1761 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
1762 | "reference": "75a63c33a8577608444246075ea0af0d052e452a",
1763 | "shasum": ""
1764 | },
1765 | "require": {
1766 | "ext-dom": "*",
1767 | "ext-tokenizer": "*",
1768 | "ext-xmlwriter": "*",
1769 | "php": "^7.2 || ^8.0"
1770 | },
1771 | "type": "library",
1772 | "autoload": {
1773 | "classmap": [
1774 | "src/"
1775 | ]
1776 | },
1777 | "notification-url": "https://packagist.org/downloads/",
1778 | "license": [
1779 | "BSD-3-Clause"
1780 | ],
1781 | "authors": [
1782 | {
1783 | "name": "Arne Blankerts",
1784 | "email": "arne@blankerts.de",
1785 | "role": "Developer"
1786 | }
1787 | ],
1788 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1789 | "support": {
1790 | "issues": "https://github.com/theseer/tokenizer/issues",
1791 | "source": "https://github.com/theseer/tokenizer/tree/master"
1792 | },
1793 | "funding": [
1794 | {
1795 | "url": "https://github.com/theseer",
1796 | "type": "github"
1797 | }
1798 | ],
1799 | "time": "2020-07-12T23:59:07+00:00"
1800 | },
1801 | {
1802 | "name": "webmozart/assert",
1803 | "version": "1.10.0",
1804 | "source": {
1805 | "type": "git",
1806 | "url": "https://github.com/webmozarts/assert.git",
1807 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
1808 | },
1809 | "dist": {
1810 | "type": "zip",
1811 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
1812 | "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
1813 | "shasum": ""
1814 | },
1815 | "require": {
1816 | "php": "^7.2 || ^8.0",
1817 | "symfony/polyfill-ctype": "^1.8"
1818 | },
1819 | "conflict": {
1820 | "phpstan/phpstan": "<0.12.20",
1821 | "vimeo/psalm": "<4.6.1 || 4.6.2"
1822 | },
1823 | "require-dev": {
1824 | "phpunit/phpunit": "^8.5.13"
1825 | },
1826 | "type": "library",
1827 | "extra": {
1828 | "branch-alias": {
1829 | "dev-master": "1.10-dev"
1830 | }
1831 | },
1832 | "autoload": {
1833 | "psr-4": {
1834 | "Webmozart\\Assert\\": "src/"
1835 | }
1836 | },
1837 | "notification-url": "https://packagist.org/downloads/",
1838 | "license": [
1839 | "MIT"
1840 | ],
1841 | "authors": [
1842 | {
1843 | "name": "Bernhard Schussek",
1844 | "email": "bschussek@gmail.com"
1845 | }
1846 | ],
1847 | "description": "Assertions to validate method input/output with nice error messages.",
1848 | "keywords": [
1849 | "assert",
1850 | "check",
1851 | "validate"
1852 | ],
1853 | "support": {
1854 | "issues": "https://github.com/webmozarts/assert/issues",
1855 | "source": "https://github.com/webmozarts/assert/tree/1.10.0"
1856 | },
1857 | "time": "2021-03-09T10:59:23+00:00"
1858 | }
1859 | ],
1860 | "aliases": [],
1861 | "minimum-stability": "stable",
1862 | "stability-flags": [],
1863 | "prefer-stable": false,
1864 | "prefer-lowest": false,
1865 | "platform": {
1866 | "php": "^5.6 || ^7.0 || ^8.0",
1867 | "ext-curl": "*",
1868 | "ext-json": "*"
1869 | },
1870 | "platform-dev": [],
1871 | "plugin-api-version": "2.1.0"
1872 | }
1873 |
--------------------------------------------------------------------------------
/etc/links.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "itag": 18,
4 | "mimeType": "video/mp4; codecs=\"avc1.42001E, mp4a.40.2\"",
5 | "width": 640,
6 | "height": 360,
7 | "contentLength": "37566943",
8 | "quality": "medium",
9 | "qualityLabel": "360p",
10 | "audioQuality": "AUDIO_QUALITY_LOW",
11 | "audioSampleRate": "44100",
12 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=18&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=ClVsKdYkdsXEH-wN5BA-tTkF&gir=yes&clen=37566943&ratebypass=yes&dur=667.016&lmt=1612997479356301&mt=1613060937&fvip=3&beids=9466586&c=WEB&txp=5530434&n=B4Y7dhUpKo8z1j&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAP3_51aqK3K3MONvgqDmcthpiM8oniucCXxMs01ebhq2AiEAmfHQaKsiu96gyf9TD7x_EPt3dLFqyWNWBr7ksFP7y40%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
13 | "signatureCipher": null
14 | },
15 | {
16 | "itag": 22,
17 | "mimeType": "video/mp4; codecs=\"avc1.64001F, mp4a.40.2\"",
18 | "width": 1280,
19 | "height": 720,
20 | "contentLength": null,
21 | "quality": "hd720",
22 | "qualityLabel": "720p",
23 | "audioQuality": "AUDIO_QUALITY_MEDIUM",
24 | "audioSampleRate": "44100",
25 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=22&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=ClVsKdYkdsXEH-wN5BA-tTkF&cnr=14&ratebypass=yes&dur=667.016&lmt=1613000535641001&mt=1613060937&fvip=3&beids=9466586&c=WEB&txp=5532434&n=B4Y7dhUpKo8z1j&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Ccnr%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAKTqGSfCcG2SnSHE-f0ZprCv_BNAdWfdr3wK-ILgux3lAiA6hidm7mqjMR4rYdMTjk7a3A9SLA1PbmAlyEPn_8cD9Q%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
26 | "signatureCipher": null
27 | },
28 | {
29 | "itag": 137,
30 | "mimeType": "video/mp4; codecs=\"avc1.640028\"",
31 | "width": 1920,
32 | "height": 1080,
33 | "contentLength": "107754305",
34 | "quality": "hd1080",
35 | "qualityLabel": "1080p",
36 | "audioQuality": null,
37 | "audioSampleRate": null,
38 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=137&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=107754305&dur=666.960&lmt=1613001396223569&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAKtEZ6ecG56Eaye7oTYOPZoAlXO2lps9I0KQKpz6UNC9AiEA4qIQEFugWm-DIcjnpwMiX2qS0SMvn08db26wUg2WZ0M%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
39 | "signatureCipher": null
40 | },
41 | {
42 | "itag": 248,
43 | "mimeType": "video/webm; codecs=\"vp9\"",
44 | "width": 1920,
45 | "height": 1080,
46 | "contentLength": "90902983",
47 | "quality": "hd1080",
48 | "qualityLabel": "1080p",
49 | "audioQuality": null,
50 | "audioSampleRate": null,
51 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=248&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=90902983&dur=666.960&lmt=1613004063059938&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAIoWCawOnzuDhqu4o_y_sVceQZ3ouftr90y8Dzb27Ju4AiBp736HAiWsPgd87Q8yvfHz2pDrtYZ8d3lubJJvjcgRyA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
52 | "signatureCipher": null
53 | },
54 | {
55 | "itag": 136,
56 | "mimeType": "video/mp4; codecs=\"avc1.4d401f\"",
57 | "width": 1280,
58 | "height": 720,
59 | "contentLength": "31161584",
60 | "quality": "hd720",
61 | "qualityLabel": "720p",
62 | "audioQuality": null,
63 | "audioSampleRate": null,
64 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=136&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=31161584&dur=666.960&lmt=1613000523151160&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhANlyzM2wvDVDNGcVRJBLwZC_XMcIaPpLMojkQWCjQawhAiEA-X2MnprsYj5-98wf-L0CRIDALsXIb4aPNHxL5YSfYMo%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
65 | "signatureCipher": null
66 | },
67 | {
68 | "itag": 247,
69 | "mimeType": "video/webm; codecs=\"vp9\"",
70 | "width": 1280,
71 | "height": 720,
72 | "contentLength": "33655281",
73 | "quality": "hd720",
74 | "qualityLabel": "720p",
75 | "audioQuality": null,
76 | "audioSampleRate": null,
77 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=247&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=33655281&dur=666.960&lmt=1613004691754283&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAJOCki1v84LbBnTsbpIVf4vgwe1J3E8hWmSCa6431iZMAiEAxXIX7yYAFGLO_oAmbdpNdfgJhHUlf68pXXd8xVlmtM8%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
78 | "signatureCipher": null
79 | },
80 | {
81 | "itag": 135,
82 | "mimeType": "video/mp4; codecs=\"avc1.4d401e\"",
83 | "width": 854,
84 | "height": 480,
85 | "contentLength": "18188922",
86 | "quality": "large",
87 | "qualityLabel": "480p",
88 | "audioQuality": null,
89 | "audioSampleRate": null,
90 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=135&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=18188922&dur=666.960&lmt=1613000426776116&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAIw_BkZkleH7S-1g5s5e509hRwHnvBuhILxcmZ8R13OoAiEAo8ZVa9hb6CozwI3iaWeC1UenDYqJ2-9Q7mOyxEQsQsU%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
91 | "signatureCipher": null
92 | },
93 | {
94 | "itag": 244,
95 | "mimeType": "video/webm; codecs=\"vp9\"",
96 | "width": 854,
97 | "height": 480,
98 | "contentLength": "21008955",
99 | "quality": "large",
100 | "qualityLabel": "480p",
101 | "audioQuality": null,
102 | "audioSampleRate": null,
103 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=244&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=21008955&dur=666.960&lmt=1613004690905920&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgcc2k0ZzE2DcyN4Y-QmgdFxafB5xs6_RegV6OLb1l0RMCIGxrorv3cHVXdUa9TWXN3orCJK6djUPgcOdNuJ9Mp8gl&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
104 | "signatureCipher": null
105 | },
106 | {
107 | "itag": 134,
108 | "mimeType": "video/mp4; codecs=\"avc1.4d401e\"",
109 | "width": 640,
110 | "height": 360,
111 | "contentLength": "12491149",
112 | "quality": "medium",
113 | "qualityLabel": "360p",
114 | "audioQuality": null,
115 | "audioSampleRate": null,
116 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=134&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=12491149&dur=666.960&lmt=1613000413521531&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAICCGzhYkEAj2BcLscT8DLNhby4DVpmNqWVBvoSGCLFaAiEAj01K0Sq8Iq-UM7ne0tCDclF2hJCv-nrByxrGrR08P_g%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
117 | "signatureCipher": null
118 | },
119 | {
120 | "itag": 243,
121 | "mimeType": "video/webm; codecs=\"vp9\"",
122 | "width": 640,
123 | "height": 360,
124 | "contentLength": "14961041",
125 | "quality": "medium",
126 | "qualityLabel": "360p",
127 | "audioQuality": null,
128 | "audioSampleRate": null,
129 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=243&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=14961041&dur=666.960&lmt=1613004699985244&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgBmSbWsRc6Q4ZJurlr63ap-C7IFTshKjKoFs3rquDnbgCIC4nxbVs8q_Ud4r6ReNI4uL4tuGVblSudqLuXQ_ZHusY&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
130 | "signatureCipher": null
131 | },
132 | {
133 | "itag": 133,
134 | "mimeType": "video/mp4; codecs=\"avc1.4d4015\"",
135 | "width": 426,
136 | "height": 240,
137 | "contentLength": "7255081",
138 | "quality": "small",
139 | "qualityLabel": "240p",
140 | "audioQuality": null,
141 | "audioSampleRate": null,
142 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=133&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=7255081&dur=666.960&lmt=1613000469082024&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIgRdHAU9QdSOfmTQcaSH9EY3kPHcpDmR-l7lFGj-FigSUCIQCeUo5Pzt9tjcyHqW6oySazkS73Jjn4RtZuwA7OKrz5UQ%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
143 | "signatureCipher": null
144 | },
145 | {
146 | "itag": 242,
147 | "mimeType": "video/webm; codecs=\"vp9\"",
148 | "width": 426,
149 | "height": 240,
150 | "contentLength": "9197885",
151 | "quality": "small",
152 | "qualityLabel": "240p",
153 | "audioQuality": null,
154 | "audioSampleRate": null,
155 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=242&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=9197885&dur=666.960&lmt=1613004705046561&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAIKKZ7uwcEaP8vxJLvaPVOjB4SmHpZCc5-sekNHE2yPxAiEAqz4a28sKoau88MYOlC8sy3JjfTqSVjrSWVE0-_N9c20%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
156 | "signatureCipher": null
157 | },
158 | {
159 | "itag": 160,
160 | "mimeType": "video/mp4; codecs=\"avc1.4d400c\"",
161 | "width": 256,
162 | "height": 144,
163 | "contentLength": "4647707",
164 | "quality": "tiny",
165 | "qualityLabel": "144p",
166 | "audioQuality": null,
167 | "audioSampleRate": null,
168 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=160&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=4647707&dur=666.960&lmt=1613000438648456&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAJKVjdrJivysIF9ps3tSIr1O36bg400lzlFIMbo2rN3uAiA5gvWC_GR8BF-1MumlnppAZNqNxdM2WNRfPjFuFMuu0w%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
169 | "signatureCipher": null
170 | },
171 | {
172 | "itag": 278,
173 | "mimeType": "video/webm; codecs=\"vp9\"",
174 | "width": 256,
175 | "height": 144,
176 | "contentLength": "6913554",
177 | "quality": "tiny",
178 | "qualityLabel": "144p",
179 | "audioQuality": null,
180 | "audioSampleRate": null,
181 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=278&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=video%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=6913554&dur=666.960&lmt=1613004710486243&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5535434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgaWkZZW57RaxzjlA4Ylzr7XOoDtxVepaByNoPmq9DiicCICyqre6WNrk_045O8GzbOJZhTzga7Tlq5T_oZ3FmOBun&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
182 | "signatureCipher": null
183 | },
184 | {
185 | "itag": 140,
186 | "mimeType": "audio/mp4; codecs=\"mp4a.40.2\"",
187 | "width": null,
188 | "height": null,
189 | "contentLength": "10795602",
190 | "quality": "tiny",
191 | "qualityLabel": null,
192 | "audioQuality": "AUDIO_QUALITY_MEDIUM",
193 | "audioSampleRate": "44100",
194 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=140&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=audio%2Fmp4&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=10795602&dur=667.016&lmt=1612996129703340&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5532434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAOZ_w4P2y6CCyGivKkIDihpdoF065NQ2xQqYj-McS0YyAiEAlqgbTLzYFCowKm64zQ4HqdaRrU1sBjcCk6BdL3pAWxE%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
195 | "signatureCipher": null
196 | },
197 | {
198 | "itag": 249,
199 | "mimeType": "audio/webm; codecs=\"opus\"",
200 | "width": null,
201 | "height": null,
202 | "contentLength": "4346683",
203 | "quality": "tiny",
204 | "qualityLabel": null,
205 | "audioQuality": "AUDIO_QUALITY_LOW",
206 | "audioSampleRate": "48000",
207 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=249&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=audio%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=4346683&dur=666.981&lmt=1612996146279714&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5532434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgD90YBq4kr2phCMTkVs-Fpaw8FyN8O5J2dS9ss3djKYYCIDCd2OSHvSzUatm-qvBqiJ_SQYqqyARvUDcphHmV0hPH&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
208 | "signatureCipher": null
209 | },
210 | {
211 | "itag": 250,
212 | "mimeType": "audio/webm; codecs=\"opus\"",
213 | "width": null,
214 | "height": null,
215 | "contentLength": "6200435",
216 | "quality": "tiny",
217 | "qualityLabel": null,
218 | "audioQuality": "AUDIO_QUALITY_LOW",
219 | "audioSampleRate": "48000",
220 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=250&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=audio%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=6200435&dur=666.981&lmt=1612996701287229&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5532434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgQohaUl41PyWAW6gq3ME1G7nueAJ55OCQHoeTHOucf6kCIFK1SaIrJGb9UWqrR4F6PFO2XU80OdeY4A-MvrlvHdxH&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
221 | "signatureCipher": null
222 | },
223 | {
224 | "itag": 251,
225 | "mimeType": "audio/webm; codecs=\"opus\"",
226 | "width": null,
227 | "height": null,
228 | "contentLength": "11603339",
229 | "quality": "tiny",
230 | "qualityLabel": null,
231 | "audioQuality": "AUDIO_QUALITY_MEDIUM",
232 | "audioSampleRate": "48000",
233 | "url": "https://r3---sn-vgqs7ney.googlevideo.com/videoplayback?expire=1613083175&ei=xl0lYLTsOYuRigTniKewBw&ip=73.44.159.175&id=o-AK5U3YRNvHl6y8UNYeHOuSju2dUkkBqiWNNn4EnczOE3&itag=251&source=youtube&requiressl=yes&mh=ta&mm=31%2C29&mn=sn-vgqs7ney%2Csn-vgqskns7&ms=au%2Crdu&mv=m&mvi=3&pl=15&initcwndbps=1785000&vprv=1&mime=audio%2Fwebm&ns=K_JP2OGgfaFu6evpcZw7POgF&gir=yes&clen=11603339&dur=666.981&lmt=1612996129075535&mt=1613060937&fvip=3&keepalive=yes&beids=9466586&c=WEB&txp=5532434&n=KfWqVJy7kNiAOe&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAMTxBDoQdNOlxqm-JzAbL-bgQEY0_BpuybB5_Kh5yeEEAiBPh2Spw2a1x5OSez1VDB7QHngzJCg8exuWyfU0xm8Ckg%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAN1GHEBLYLpgmMpZsCIpt6f4U7zBPSPkLsP5ouc2oMVWAiEA1Ff2HrdIVYUqV3Vlq_uncsUEebAKU4RjUMziTUjItwU%3D",
234 | "signatureCipher": null
235 | }
236 | ]
--------------------------------------------------------------------------------
/etc/youtube_urls.txt:
--------------------------------------------------------------------------------
1 | https://www.youtube.com/watch?v=aqz-KE-bpKQ&ab_channel=Blender
2 | http://www.youtube.com/attribution_link?a=aqz-KE-bpKQ&u=/watch?v=aqz-KE-bpKQ&feature=share
3 | https://www.youtube.com/attribution_link?a=8g8kPrPIi-ecwIsS&u=/watch?v=aqz-KE-bpKQ&feature=em-uploademail
4 | https://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/aqz-KE-bpKQ
5 | https://www.youtube-nocookie.com/embed/aqz-KE-bpKQ?rel=0
6 | http://www.youtube.com/ytscreeningroom?v=aqz-KE-bpKQ
7 | http://www.youtube.com/user/SilkRoadTheatre#p/a/u/2/aqz-KE-bpKQ
8 | http://www.youtube.com/watch?feature=player_embedded&v=aqz-KE-bpKQ
9 | http://www.youtube.com/?feature=player_embedded&v=aqz-KE-bpKQ
10 | http://www.youtube.com/user/IngridMichaelsonVEVO#p/u/11/aqz-KE-bpKQ
11 | http://www.youtube-nocookie.com/v/aqz-KE-bpKQ?version=3&hl=en_US&rel=0
12 | http://www.youtube.com/user/dreamtheater#p/u/1/aqz-KE-bpKQ
13 | http://www.youtube.com/ytscreeningroom?v=aqz-KE-bpKQ
--------------------------------------------------------------------------------
/phpstan.neon.dist:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 6
3 | paths:
4 | - src
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
51 |
52 | Youtube Downloader
53 |
54 |
55 |
56 |
57 | YouTube Downloader By Maadhav Sharma
58 |
59 |
60 | Source Code:
61 | https://github.com/Maadhav/youtube-downloader-API
63 |
64 |
70 |
71 |
72 |
73 | Sorry, your browser doesn't support HTML5 video.
74 |
75 |
76 |
77 |
132 |
133 | Project Originally Forked From:
134 | https://github.com/Athlon1600/youtube-downloader
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/public/stream.php:
--------------------------------------------------------------------------------
1 | stream($url);
15 |
--------------------------------------------------------------------------------
/public/video_info.php:
--------------------------------------------------------------------------------
1 | 'No URL provided!'
17 | ]);
18 | }
19 |
20 | $youtube = new \YouTube\YouTubeDownloader();
21 |
22 | try {
23 | $links = $youtube->getDownloadLinks($url);
24 |
25 | $best = $links->getFirstCombinedFormat();
26 |
27 | if ($best) {
28 | send_json([
29 | 'links' => [$best->url]
30 | ]);
31 | } else {
32 | send_json(['error' => 'No links found']);
33 | }
34 |
35 | } catch (\YouTube\Exception\YouTubeException $e) {
36 |
37 | send_json([
38 | 'error' => $e->getMessage()
39 | ]);
40 | }
41 |
--------------------------------------------------------------------------------
/src/Browser.php:
--------------------------------------------------------------------------------
1 | headers['User-Agent'] = $agent;
13 | }
14 |
15 | public function getUserAgent()
16 | {
17 | return Utils::arrayGet($this->headers, 'User-Agent');
18 | }
19 |
20 | public function followRedirects($enabled)
21 | {
22 | $this->options[CURLOPT_FOLLOWLOCATION] = $enabled ? 1 : 0;
23 | return $this;
24 | }
25 |
26 | public function cachedGet($url)
27 | {
28 | $cache_path = sprintf('%s/%s', static::getStorageDirectory(), $this->getCacheKey($url));
29 |
30 | if (file_exists($cache_path)) {
31 |
32 | // unserialize could fail on empty file
33 | $str = file_get_contents($cache_path);
34 | return unserialize($str);
35 | }
36 |
37 | $response = $this->get($url);
38 |
39 | // cache only if successful
40 | if (empty($response->error)) {
41 | file_put_contents($cache_path, serialize($response));
42 | }
43 |
44 | return $response;
45 | }
46 |
47 | protected function getCacheKey($url)
48 | {
49 | return md5($url) . '_v3';
50 | }
51 |
52 | public function consentCookies()
53 | {
54 | $response = $this->get('https://www.youtube.com/');
55 | $current_url = $response->info->url;
56 |
57 | // must be missing that special cookie
58 | if (strpos($current_url, 'consent.youtube.com') !== false) {
59 |
60 | $field_names = ['gl', 'm', 'pc', 'continue', 'ca', 'x', 'v', 't', 'hl', 'src', 'uxe'];
61 |
62 | $form_data = [];
63 |
64 | foreach ($field_names as $name) {
65 | $value = Utils::getInputValueByName($response->body, $name);
66 | $form_data[$name] = htmlspecialchars_decode($value);
67 | }
68 |
69 | // this will set that cookie that we need to never see that message again
70 | $this->post('https://consent.youtube.com/s', $form_data);
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/src/DownloadOptions.php:
--------------------------------------------------------------------------------
1 | formats = $formats;
21 | $this->info = $info;
22 | }
23 |
24 | /**
25 | * @return StreamFormat[]
26 | */
27 | public function getAllFormats()
28 | {
29 | return $this->formats;
30 | }
31 |
32 | /**
33 | * @return VideoDetails|null
34 | */
35 | public function getInfo()
36 | {
37 | return $this->info;
38 | }
39 |
40 | // Will not include Videos with Audio
41 | public function getVideoFormats()
42 | {
43 | return Utils::arrayFilterReset($this->getAllFormats(), function ($format) {
44 | /** @var $format StreamFormat */
45 | return strpos($format->mimeType, 'video') === 0 && empty($format->audioQuality);
46 | });
47 | }
48 |
49 | public function getAudioFormats()
50 | {
51 | return Utils::arrayFilterReset($this->getAllFormats(), function ($format) {
52 | /** @var $format StreamFormat */
53 | return strpos($format->mimeType, 'audio') === 0;
54 | });
55 | }
56 |
57 | public function getCombinedFormats()
58 | {
59 | return Utils::arrayFilterReset($this->getAllFormats(), function ($format) {
60 | /** @var $format StreamFormat */
61 | return strpos($format->mimeType, 'video') === 0 && !empty($format->audioQuality);
62 | });
63 | }
64 |
65 | /**
66 | * @return StreamFormat|null
67 | */
68 | public function getFirstCombinedFormat()
69 | {
70 | $combined = $this->getCombinedFormats();
71 | return count($combined) ? $combined[0] : null;
72 | }
73 |
74 | protected function getLowToHighVideoFormats()
75 | {
76 | $copy = array_values($this->getVideoFormats());
77 |
78 | usort($copy, function ($a, $b) {
79 |
80 | /** @var StreamFormat $a */
81 | /** @var StreamFormat $b */
82 |
83 | return $a->height - $b->height;
84 | });
85 |
86 | return $copy;
87 | }
88 |
89 | protected function getLowToHighAudioFormats()
90 | {
91 | $copy = array_values($this->getAudioFormats());
92 |
93 | // just assume higher filesize => higher quality...
94 | usort($copy, function ($a, $b) {
95 |
96 | /** @var StreamFormat $a */
97 | /** @var StreamFormat $b */
98 |
99 | return $a->contentLength - $b->contentLength;
100 | });
101 |
102 | return $copy;
103 | }
104 |
105 | // Combined using: ffmpeg -i video.mp4 -i audio.mp3 output.mp4
106 | public function getSplitFormats($quality = null)
107 | {
108 | // sort formats by quality in desc, and high = first, medium = middle, low = last
109 | $videos = $this->getLowToHighVideoFormats();
110 | $audio = $this->getLowToHighAudioFormats();
111 |
112 | if ($quality == 'high' || $quality == 'best') {
113 |
114 | return new SplitStream([
115 | 'video' => $videos[count($videos) - 1],
116 | 'audio' => $audio[count($audio) - 1]
117 | ]);
118 |
119 | } else if ($quality == 'low' || $quality == 'worst') {
120 |
121 | return new SplitStream([
122 | 'video' => $videos[0],
123 | 'audio' => $audio[0]
124 | ]);
125 | }
126 |
127 | // something in between!
128 | return new SplitStream([
129 | 'video' => $videos[floor(count($videos) / 2)],
130 | 'audio' => $audio[floor(count($audio) / 2)]
131 | ]);
132 | }
133 | }
--------------------------------------------------------------------------------
/src/Exception/TooManyRequestsException.php:
--------------------------------------------------------------------------------
1 | page = $page;
16 | }
17 |
18 | /**
19 | * @return WatchVideoPage
20 | */
21 | public function getPage()
22 | {
23 | return $this->page;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Exception/VideoNotFoundException.php:
--------------------------------------------------------------------------------
1 | fillFromArray($array);
11 | }
12 | }
13 |
14 | public static function fromArray($array)
15 | {
16 | return new static($array);
17 | }
18 |
19 | private function fillFromArray($array)
20 | {
21 | foreach ($array as $key => $val) {
22 | if (property_exists($this, $key)) {
23 | $this->{$key} = $val;
24 | }
25 | }
26 | }
27 |
28 | /**
29 | * @return array
30 | */
31 | public function toArray()
32 | {
33 | return get_object_vars($this);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Models/SplitStream.php:
--------------------------------------------------------------------------------
1 | mimeType));
22 | }
23 | }
--------------------------------------------------------------------------------
/src/Models/VideoDetails.php:
--------------------------------------------------------------------------------
1 | videoDetails = $videoDetails;
14 | }
15 |
16 | /**
17 | * From `videoDetails` array that appears inside JSON on /watch or /get_video_info pages
18 | * @param $array
19 | * @return static
20 | */
21 | public static function fromPlayerResponseArray($array)
22 | {
23 | return new static(Utils::arrayGet($array, 'videoDetails'));
24 | }
25 |
26 | public function getId()
27 | {
28 | return Utils::arrayGet($this->videoDetails, 'videoId');
29 | }
30 |
31 | public function getTitle()
32 | {
33 | return Utils::arrayGet($this->videoDetails, 'title');
34 | }
35 |
36 | public function getKeywords()
37 | {
38 | return Utils::arrayGet($this->videoDetails, 'keywords');
39 | }
40 |
41 | public function getShortDescription()
42 | {
43 | return Utils::arrayGet($this->videoDetails, 'shortDescription');
44 | }
45 |
46 | public function getViewCount()
47 | {
48 | return Utils::arrayGet($this->videoDetails, 'viewCount');
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Models/VideoInfo.php:
--------------------------------------------------------------------------------
1 | getResponseBody());
12 | }
13 |
14 | public function isError()
15 | {
16 | return Utils::arrayGet($this->getJson(), 'errorcode') !== null;
17 | }
18 |
19 | /**
20 | * About same as `player_response` that appears on video pages.
21 | * @return array
22 | */
23 | public function getPlayerResponse()
24 | {
25 | $playerResponse = Utils::arrayGet($this->getJson(), 'player_response');
26 | return json_decode($playerResponse, true);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Responses/HttpResponse.php:
--------------------------------------------------------------------------------
1 | response = $response;
20 | $this->json = json_decode($response->body, true);
21 | }
22 |
23 | public function getResponse()
24 | {
25 | return $this->response;
26 | }
27 |
28 | /**
29 | * @return string|null
30 | */
31 | public function getResponseBody()
32 | {
33 | return $this->response->body;
34 | }
35 |
36 | /**
37 | * @return array|null
38 | */
39 | public function getJson()
40 | {
41 | return $this->json;
42 | }
43 |
44 | public function isStatusOkay()
45 | {
46 | return $this->getResponse()->status == 200;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Responses/VideoPlayerJs.php:
--------------------------------------------------------------------------------
1 | getResponseBody(), 'We have been receiving a large volume of requests') !== false ||
14 | strpos($this->getResponseBody(), 'systems have detected unusual traffic') !== false ||
15 | strpos($this->getResponseBody(), '/recaptcha/') !== false;
16 | }
17 |
18 | public function isVideoNotFound()
19 | {
20 | return strpos($this->getResponseBody(), ' - YouTube ') !== false;
21 | }
22 |
23 | public function hasPlayableVideo()
24 | {
25 | $playerResponse = $this->getPlayerResponse();
26 | $playabilityStatus = Utils::arrayGet($playerResponse, 'playabilityStatus.status');
27 |
28 | return $this->getResponse()->status == 200 && $playabilityStatus == 'OK';
29 | }
30 |
31 | /**
32 | * Look for a player script URL. E.g:
33 | *
34 | *
35 | * @return string|null
36 | */
37 | public function getPlayerScriptUrl()
38 | {
39 | // check what player version that video is using
40 | if (preg_match('@