Source of file YouTube.php

Size: 10,192 Bytes - Last Modified: 2019-04-22T15:29:30+00:00

C:/xampp/htdocs/PodTube/src/SupportedSites/YouTube.php

123456789101112131415161718192021222324
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
252627
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
28
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
29
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
303132
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
33
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
34
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
35
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
3637
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
383940
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
41
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
42
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
43
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
4445
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
46
Covered by 4 test(s):
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
4748
Covered by 2 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testDownload
49
Covered by 2 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testDownload
50
Covered by 2 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testDownload
51
Covered by 2 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testDownload
5253
Covered by 2 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testDownload
5455565758596061626364
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
65
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
66
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
67
Covered by 1 test(s):
  • YouTubeTest::testPlaylist
6869
Covered by 9 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
70
Covered by 3 test(s):
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
7172
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
7374757677
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
78
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
7980818283
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
84858687888990
Covered by 1 test(s):
  • YouTubeTest::testDownload
91
Covered by 1 test(s):
  • YouTubeTest::testDownload
92
Covered by 1 test(s):
  • YouTubeTest::testDownload
9394
Covered by 1 test(s):
  • YouTubeTest::testDownload
95
Covered by 1 test(s):
  • YouTubeTest::testDownload
96979899100101102103104
Covered by 1 test(s):
  • YouTubeTest::testDownload
105
Covered by 1 test(s):
  • YouTubeTest::testDownload
106
Covered by 1 test(s):
  • YouTubeTest::testDownload
107108
Covered by 1 test(s):
  • YouTubeTest::testDownload
109
Covered by 1 test(s):
  • YouTubeTest::testDownload
110111112113114115116117
Covered by 1 test(s):
  • YouTubeTest::testDownload
118119
Covered by 1 test(s):
  • YouTubeTest::testDownload
120
Covered by 1 test(s):
  • YouTubeTest::testDownload
121
Covered by 1 test(s):
  • YouTubeTest::testDownload
122123124125126127128129130131
Covered by 1 test(s):
  • YouTubeTest::testDownload
132
Covered by 1 test(s):
  • YouTubeTest::testDownload
133
Covered by 1 test(s):
  • YouTubeTest::testDownload
134135
Covered by 1 test(s):
  • YouTubeTest::testDownload
136137138
Covered by 1 test(s):
  • YouTubeTest::testDownload
139
Covered by 1 test(s):
  • YouTubeTest::testDownload
140141
Covered by 1 test(s):
  • YouTubeTest::testDownload
142143144145
Covered by 1 test(s):
  • YouTubeTest::testDownload
146
Covered by 1 test(s):
  • YouTubeTest::testDownload
147148
Covered by 1 test(s):
  • YouTubeTest::testDownload
149
Covered by 1 test(s):
  • YouTubeTest::testDownload
150
Covered by 1 test(s):
  • YouTubeTest::testDownload
151
Covered by 1 test(s):
  • YouTubeTest::testDownload
152
Covered by 1 test(s):
  • YouTubeTest::testDownload
153
Covered by 1 test(s):
  • YouTubeTest::testDownload
154
Covered by 1 test(s):
  • YouTubeTest::testDownload
155156
Covered by 1 test(s):
  • YouTubeTest::testDownload
157
Covered by 1 test(s):
  • YouTubeTest::testDownload
158
Covered by 1 test(s):
  • YouTubeTest::testDownload
159
Covered by 1 test(s):
  • YouTubeTest::testDownload
160161162163
Covered by 1 test(s):
  • YouTubeTest::testDownload
164165
Covered by 1 test(s):
  • YouTubeTest::testDownload
166
Covered by 1 test(s):
  • YouTubeTest::testDownload
167168169170
Covered by 1 test(s):
  • YouTubeTest::testDownload
171172173174
Covered by 1 test(s):
  • YouTubeTest::testDownload
175176177178179180
Covered by 1 test(s):
  • YouTubeTest::testDownload
181
Covered by 1 test(s):
  • YouTubeTest::testDownload
182
Covered by 1 test(s):
  • YouTubeTest::testDownload
183
Covered by 1 test(s):
  • YouTubeTest::testDownload
184
Covered by 1 test(s):
  • YouTubeTest::testDownload
185
Covered by 1 test(s):
  • YouTubeTest::testDownload
186
Covered by 1 test(s):
  • YouTubeTest::testDownload
187
Covered by 1 test(s):
  • YouTubeTest::testDownload
188
Covered by 1 test(s):
  • YouTubeTest::testDownload
189190191
Covered by 1 test(s):
  • YouTubeTest::testDownload
192
Covered by 1 test(s):
  • YouTubeTest::testDownload
193
Covered by 1 test(s):
  • YouTubeTest::testDownload
194195
Covered by 1 test(s):
  • YouTubeTest::testDownload
196
Covered by 1 test(s):
  • YouTubeTest::testDownload
197
Covered by 1 test(s):
  • YouTubeTest::testDownload
198
Covered by 1 test(s):
  • YouTubeTest::testDownload
199
Covered by 1 test(s):
  • YouTubeTest::testDownload
200201
Covered by 1 test(s):
  • YouTubeTest::testDownload
202
Covered by 1 test(s):
  • YouTubeTest::testDownload
203204
Covered by 1 test(s):
  • YouTubeTest::testDownload
205
Covered by 1 test(s):
  • YouTubeTest::testDownload
206
Covered by 1 test(s):
  • YouTubeTest::testDownload
207
Covered by 1 test(s):
  • YouTubeTest::testDownload
208209210211
Covered by 1 test(s):
  • YouTubeTest::testDownload
212213214215216217218219220221
Covered by 1 test(s):
  • YouTubeTest::testDownload
222
Covered by 1 test(s):
  • YouTubeTest::testDownload
223
Covered by 1 test(s):
  • YouTubeTest::testDownload
224
Covered by 1 test(s):
  • YouTubeTest::testDownload
225
Covered by 1 test(s):
  • YouTubeTest::testDownload
226
Covered by 1 test(s):
  • YouTubeTest::testDownload
227
Covered by 1 test(s):
  • YouTubeTest::testDownload
228
Covered by 1 test(s):
  • YouTubeTest::testDownload
229
Covered by 1 test(s):
  • YouTubeTest::testDownload
230
Covered by 1 test(s):
  • YouTubeTest::testDownload
231
Covered by 1 test(s):
  • YouTubeTest::testDownload
232
Covered by 1 test(s):
  • YouTubeTest::testDownload
233
Covered by 1 test(s):
  • YouTubeTest::testDownload
234
Covered by 1 test(s):
  • YouTubeTest::testDownload
235
Covered by 1 test(s):
  • YouTubeTest::testDownload
236
Covered by 1 test(s):
  • YouTubeTest::testDownload
237238
Covered by 1 test(s):
  • YouTubeTest::testDownload
239
Covered by 1 test(s):
  • YouTubeTest::testDownload
240
Covered by 1 test(s):
  • YouTubeTest::testDownload
241242243244245
Covered by 1 test(s):
  • YouTubeTest::testDownload
246
Covered by 1 test(s):
  • YouTubeTest::testDownload
247
Covered by 1 test(s):
  • YouTubeTest::testDownload
248
Covered by 1 test(s):
  • YouTubeTest::testDownload
249250
Covered by 1 test(s):
  • YouTubeTest::testDownload
251252253254255256257258259260261262263
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
264
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
265
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
266
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
267
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
268
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
269
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
270
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
271
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
272273
Covered by 6 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testDownload
274275276277278279280281282283
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
284
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
285
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
286
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
287
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
288
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
289
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
290
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
291
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
292
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
293
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
294
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
295
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
296
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
297
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
298299
Covered by 10 test(s):
  • YouTubeTest::testConstructor
  • YouTubeTest::testBadID1
  • YouTubeTest::testBadID2
  • YouTubeTest::testBadID3
  • YouTubeTest::testBadID4
  • YouTubeTest::testPlaylist
  • YouTubeTest::testChannel1
  • YouTubeTest::testChannel2
  • YouTubeTest::testChannel3
  • YouTubeTest::testDownload
300301302303
Covered by 1 test(s):
  • SupportedSitesTest::testYouTubeSupportsURL
304305306307308
<?php

namespace AudioDidact\SupportedSites;

use AudioDidact\Video;
use AudioDidact\GlobalFunctions;

/**
 * Class YouTube
 */
class YouTube extends SupportedSite {
	// Setup global variables
	/** @var string YouTube URL */
	private $YouTubeBaseURL = "http://www.youtube.com/";

	/**
	 * YouTube constructor. Gets the video information, checks for it in the user's feed.
	 *
	 * @param string $str
	 * @param boolean $isVideo
	 * @throws \Exception
	 */
	public function __construct($str, $isVideo){
		$this->video = new Video();

		// If there is a URL/ID, continue
		if($str != null){
			$this->video->setURL($str);
			$this->video->setIsVideo($isVideo);

			// Set video ID from setYoutubeID and time to current time
			$this->video->setId($this->setYoutubeID($str));
			$this->video->setFilename($this->video->getId());
			$this->video->setThumbnailFilename($this->video->getFilename() . ".jpg");
			$this->video->setTime(time());

			$key = GOOGLE_API_KEY;

			// Get video author, title, and description from YouTube API
			$info = json_decode(GlobalFunctions::file_get_contents_no_verify("https://www.googleapis.com/youtube/v3/videos?part=snippet&id="
				. $this->video->getId() .
				"&fields=items/snippet/description,items/snippet/title,items/snippet/channelTitle&key=" .
				$key), true);
			// If the lookup fails, send this error to the UI as a JSON array
			if(!isset($info['items'][0]['snippet'])){
				throw new \Exception("ID Inaccessible");
			}
			$info = $info['items'][0]['snippet'];
			$this->video->setTitle($info["title"]);
			$this->video->setAuthor($info["channelTitle"]);
			$this->video->setDesc($info["description"]);
		}
	}

	/**
	 * Set YouTube ID from a given string using parseYoutubeURL
	 *
	 * @param string $str
	 * @return bool
	 * @throws \Exception
	 */
	private function setYoutubeID($str){
		// Try and parse the string into a usable ID
		$tmpId = $this->parseYoutubeURL($str);
		$vidId = ($tmpId !== false) ? $tmpId : $str;
		if(mb_strpos($vidId, "/playlist") > -1){
			throw new \Exception("URL is a playlist. AudioDidact does not currently support playlists.");
		}
		if(mb_strpos($vidId, "/c/") > -1 || strpos($vidId, "/channel/") > -1 || strpos($vidId, "/user/") > -1){
			throw new \Exception("URL is a channel. AudioDidact does not, and likely will not ever, support downloading of channels.");
		}
		$url = sprintf($this->YouTubeBaseURL . "watch?v=%s", $vidId);
		// Get HTTP status of the video url and make sure that it is
		// 200 = OK
		// 301 = Moved Permanently
		// 302 = Moved Temporarily
		if($this->cURLHTTPStatus($url) !== 200 && $this->cURLHTTPStatus($url) !== 301 && $this->cURLHTTPStatus($url)
			!== 302
		){
			throw new \Exception("Invalid Youtube video ID: $vidId");
		}

		return $vidId;
	}

	/**
	 * Download thumbnail using videoID from YouTube's image server
	 */
	public function downloadThumbnail(){
		$path = getcwd() . DIRECTORY_SEPARATOR . DOWNLOAD_PATH . DIRECTORY_SEPARATOR;
		$thumbnail = $path . $this->video->getThumbnailFilename();
		file_put_contents($thumbnail, fopen("https://i.ytimg.com/vi/" . $this->video->getID() . "/mqdefault.jpg", "r"));
		// Set the thumbnail file as publicly accessible
		@chmod($thumbnail, 0775);
	}

	/**
	 * Download video using download URL from Python script and then call downloadWithPercentage to actually download
	 * the video
	 *
	 * @throws \Exception
	 */
	public function downloadVideo(){
		$path = getcwd() . DIRECTORY_SEPARATOR . DOWNLOAD_PATH . DIRECTORY_SEPARATOR;
		$videoFilename = $this->video->getFilename() . ".mp4";
		$videoPath = $path . $videoFilename;

		$url = $this->getDownloadURL($this->video->getID());
		if(mb_strpos($url, "Error:") > -1){
			error_log("$url");
			throw new \Exception($url);
		}

		/* Actually download the video from the url and print the
		 * percentage to the screen with JSON
		 */
		$this->downloadWithPercentage($url, $videoPath);
		// Set the video file as publicly accessible
		@chmod($videoPath, 0775);
		$this->video->setDuration(SupportedSite::getDurationSeconds($videoPath));
	}

	/**
	 * Gets lowest quality mp4 download url based on a given id.
	 *
	 * @param $id
	 * @return string
	 * @throws \Exception
	 */
	private function getDownloadURL($id){
		$url = $this->YouTubeBaseURL . "watch?v=" . $id;
		$html = file_get_contents($url);
		$restrictionPattern = "og:restrictions:age";

		if(mb_strpos($html, $restrictionPattern) > -1){
			return "Error: Age restricted video. Unable to download.";
		}
		$jsonStartPattern = "ytplayer.config = ";
		$patternIndex = mb_strpos($html, $jsonStartPattern);
		// In case video is unable to play
		if($patternIndex == -1){
			return "Error: Unable to find start pattern.";
		}

		$start = $patternIndex + mb_strlen($jsonStartPattern);
		$html = mb_substr($html, $start);

		$unmatchedBracketsCount = 0;
		$index = 1;
		$htmlArr = GlobalFunctions::mb_str_split($html);
		$i = 0;
		foreach($htmlArr as $i => $ch){
			if($ch == "{"){
				$unmatchedBracketsCount += 1;
			}
			else if($ch == "}"){
				$unmatchedBracketsCount -= 1;
				if($unmatchedBracketsCount == 0){
					break;
				}
			}
		}
		$offset = $index + $i;

		$youtubeJSONData = json_decode(mb_substr($html, 0, $offset), true);
		if($youtubeJSONData == null){
			throw new \Exception("<h3>Download Failed</h3><h4>Unable to find JSON data from YouTube</h4>");
		}

		if(isset($youtubeJSONData["args"]["livestream"]) && $youtubeJSONData["args"]["livestream"] && (!isset($youtubeJSONData["args"]["url_encoded_fmt_stream_map"]) || $youtubeJSONData["args"]["url_encoded_fmt_stream_map"] == "")){
			throw new \Exception("<h3>Download Failed</h3><h4>This URL is a livestream, try again when the stream has ended</h4>");
		}

		if(!isset($youtubeJSONData["args"]["url_encoded_fmt_stream_map"]) || $youtubeJSONData["args"]["url_encoded_fmt_stream_map"] == ""){
			error_log("Couldn't download " . $id . " because could not find url_encoded_fmt_stream_map");
			error_log(json_encode($youtubeJSONData));
			throw new \Exception("<h3>Download Failed</h3><h4>Try again later</h4>");
		}

		$encodedStreamMap = $youtubeJSONData["args"]["url_encoded_fmt_stream_map"];
		$dct = [];
		$videos = explode(",", $encodedStreamMap);
		foreach($videos as $i => $video){
			$video = explode("&", $video);
			foreach($video as $v){
				$key = explode("=", $v)[0];
				$value = explode("=", $v)[1];
				$dct[$key][] = urldecode($value);
			}
		}
		$youtubeJSONData["args"]["stream_map"] = $dct;
		$streamMap = $dct;
		unset($dct, $videos, $html, $htmlArr, $youtubeJSONData);

		$videoURLs = $streamMap["url"];
		$downloads = [];
		foreach($videoURLs as $i => $vurl){
			$qualityProfile = $this->getQualityProfilesFromURL($vurl);
			$downloads[] = ["url" => $vurl, "ext" => $qualityProfile["extension"], "res" => $qualityProfile["resolution"]];
		}
		$downloadURL = "";
		$resolution = 999999;
		// Find lowest quality mp4
		foreach($downloads as $v){
			if($v["ext"] == "mp4" && intval(mb_substr($v["res"], 0, -1)) < $resolution){
				$resolution = intval(mb_substr($v["res"], 0, -1));
				$downloadURL = $v["url"];
			}
		}

		return $downloadURL;
	}

	/**
	 * Returns a quality profile or false based on a url.
	 *
	 * @param $url
	 * @return bool|mixed
	 */
	private function getQualityProfilesFromURL($url){
		$qp = [];
		$qp[5] = ["flv", "240p", "Sorenson H.263", "N/A", "0.25", "MP3", "64"];
		$qp[17] = ["3gp", "144p", "MPEG-4 Visual", "Simple", "0.05", "AAC", "24"];
		$qp[36] = ["3gp", "240p", "MPEG-4 Visual", "Simple", "0.17", "AAC", "38"];
		$qp[43] = ["webm", "360p", "VP8", "N/A", "0.5", "Vorbis", "128"];
		$qp[100] = ["webm", "360p", "VP8", "3D", "N/A", "Vorbis", "128"];
		$qp[18] = ["mp4", "360p", "H.264", "Baseline", "0.5", "AAC", "96"];
		$qp[22] = ["mp4", "720p", "H.264", "High", "2-2.9", "AAC", "192"];
		$qp[82] = ["mp4", "360p", "H.264", "3D", "0.5", "AAC", "96"];
		$qp[83] = ["mp4", "240p", "H.264", "3D", "0.5", "AAC", "96"];
		$qp[84] = ["mp4", "720p", "H.264", "3D", "2-2.9", "AAC", "152"];
		$qp[85] = ["mp4", "1080p", "H.264", "3D", "2-2.9", "AAC", "152"];
		foreach($qp as $k => $q){
			$keys = ["extension", "resolution", "video_codec", "profile", "video_bitrate", "audio_codec", "audio_bitrate"];
			foreach($keys as $k2 => $v){
				$qp[$k][$v] = $q[$k2];
			}
			foreach(array_keys($qp[$k]) as $key){
				if(!in_array($key, $keys, true)){
					unset($qp[$k][$key]);
				}
			}
		}

		$itagPattern = '/itag=(\d+)/';
		preg_match_all($itagPattern, $url, $itag);
		if(isset($itag[1][0]) && intval($itag[1][0]) > -1){
			$itag = intval($itag[1][0]);

			return $qp[$itag];
		}

		return false;
	}

	/**
	 * Use cURL to get the HTTP status of a given URL
	 *
	 * @param $url
	 * @return int
	 */
	private function cURLHTTPStatus($url){
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0");
		curl_setopt($ch, CURLOPT_REFERER, $this->YouTubeBaseURL);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_NOBODY, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
		curl_exec($ch);
		$int = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);

		return intval($int);
	}

	/**
	 * Parse a YouTube URL to get the video ID
	 *
	 * @param $url
	 * @return bool
	 */
	private function parseYoutubeURL($url){
		$pattern = '#^(?:https?://)?';
		$pattern .= '(?:www\.)?';
		$pattern .= '(?:';
		$pattern .= 'youtu\.be/';
		$pattern .= '|youtube\.com';
		$pattern .= '(?:';
		$pattern .= '/embed/';
		$pattern .= '|/v/';
		$pattern .= '|/watch\?v=';
		$pattern .= '|/watch\?.+&v=';
		$pattern .= ')';
		$pattern .= ')';
		$pattern .= '([\w-]{11})';
		$pattern .= '(?:.+)?$#x';
		preg_match($pattern, $url, $matches);

		return (isset($matches[1])) ? $matches[1] : false;
	}

	public static function supportsURL($url){
		return (mb_strpos($url, "youtube") > -1) || (mb_strpos($url, "youtu.be") > -1);
	}


}