Source of file SoundCloud.php
Size: 6,469 Bytes - Last Modified: 2018-08-03T03:16:59+00:00
C:/xampp/htdocs/PodTube/src/SupportedSites/SoundCloud.php
1234567891011121314151617181920212223
Covered by 4 test(s):
242526
Covered by 4 test(s):
27
Covered by 4 test(s):
28
Covered by 1 test(s):
2930
Covered by 3 test(s):
31
Covered by 3 test(s):
323334
Covered by 3 test(s):
35
Covered by 3 test(s):
36
Covered by 1 test(s):
3738
Covered by 2 test(s):
39
Covered by 2 test(s):
40
Covered by 2 test(s):
41
Covered by 2 test(s):
42
Covered by 2 test(s):
43
Covered by 2 test(s):
44
Covered by 2 test(s):
4546
Covered by 2 test(s):
474849
Covered by 3 test(s):
5051
Covered by 3 test(s):
525354555657
Covered by 3 test(s):
58
Covered by 3 test(s):
59
Covered by 3 test(s):
60
Covered by 3 test(s):
61
Covered by 3 test(s):
62
Covered by 3 test(s):
63
Covered by 3 test(s):
64
Covered by 3 test(s):
6566
Covered by 3 test(s):
67
Covered by 3 test(s):
68
Covered by 3 test(s):
69707172
Covered by 3 test(s):
73747576
Covered by 3 test(s):
77
Covered by 3 test(s):
787980
Covered by 3 test(s):
81
Covered by 3 test(s):
828384
Covered by 3 test(s):
8586
Covered by 3 test(s):
87
Covered by 3 test(s):
88
Covered by 3 test(s):
8990
Covered by 3 test(s):
91
Covered by 3 test(s):
92
Covered by 3 test(s):
93
Covered by 3 test(s):
94
Covered by 3 test(s):
95
Covered by 3 test(s):
96
Covered by 3 test(s):
9798
Covered by 3 test(s):
99
Covered by 3 test(s):
100101
Covered by 3 test(s):
102
Covered by 3 test(s):
103
Covered by 3 test(s):
104105
Covered by 3 test(s):
106
Covered by 3 test(s):
107108109
Covered by 3 test(s):
110
Covered by 3 test(s):
111
Covered by 3 test(s):
112113114115
Covered by 3 test(s):
116
Covered by 3 test(s):
117
Covered by 3 test(s):
118
Covered by 2 test(s):
119
Covered by 2 test(s):
120
Covered by 2 test(s):
121
Covered by 2 test(s):
122
Covered by 2 test(s):
123
Covered by 2 test(s):
124125126127
Covered by 2 test(s):
128129130
Covered by 3 test(s):
131132133
Covered by 1 test(s):
134135
Covered by 1 test(s):
136137138139140141142143144
Covered by 1 test(s):
145
Covered by 1 test(s):
146147148
Covered by 1 test(s):
149
Covered by 1 test(s):
150151152
Covered by 1 test(s):
153154155156157158159160
Covered by 1 test(s):
161162163164165166167
Covered by 1 test(s):
168
Covered by 1 test(s):
169
Covered by 1 test(s):
170171
Covered by 1 test(s):
172
Covered by 1 test(s):
173174175
Covered by 1 test(s):
176
Covered by 1 test(s):
177
Covered by 1 test(s):
178179
Covered by 1 test(s):
180181182183
Covered by 1 test(s):
184
Covered by 1 test(s):
185
Covered by 1 test(s):
186187
Covered by 1 test(s):
188
Covered by 1 test(s):
189190
Covered by 1 test(s):
191
Covered by 1 test(s):
192193
Covered by 1 test(s):
194195196197198199200201202203204
Covered by 1 test(s):
205206207
Covered by 1 test(s):
208209210211212
| <?php namespace AudioDidact\SupportedSites; use AudioDidact\Video; class SoundCloud extends SupportedSite { // Setup global variables private $streamsBaseURL = "https://api.soundcloud.com/tracks/XYZ/streams?client_id="; private $clientID; private $invalidURLMessage = "Invalid SoundCloud URL Entered.<br/>Valid URLs look like https://soundcloud.com/user_name/xxxxxxxxxxxx"; private $thumbnailURL; private $audioJSON; /** * SoundCloud constructor. Gets the audio 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){ if(!filter_var($str, FILTER_VALIDATE_URL) || !mb_strpos($str, "soundcloud")){ throw new \Exception($this->invalidURLMessage); } $this->video->setURL($str); $this->video->setIsVideo(false); // Set video ID and time to current time $info = $this->getVideoInfo($str); if(!$info){ throw new \Exception($this->invalidURLMessage); } $this->video->setId($info["ID"]); $this->video->setFilename($this->video->getId()); $this->video->setThumbnailFilename($this->video->getFilename() . ".jpg"); $this->video->setTime(time()); $this->video->setTitle($info["title"]); $this->video->setAuthor($info["author"]); $this->video->setDesc($info["description"]); } } private function cURLHTTPGet($url, $ssl = false){ $ch = curl_init($url); $headers = [ "User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8h zlib/1.2.3 libssh2/0.15-CVS", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language: en-us;q=0.5,en;q=0.3", "Keep-Alive: 115", "Connection: keep-alive" ]; curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); if($ssl){ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); } $response = curl_exec($ch); $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if($responseCode != 200 && $responseCode != 302 && $responseCode != 304){ $response = false; } return $response; } private function getVideoInfo($str){ $str = str_replace("http://", "https://", $str); $webpage = $this->cURLHTTPGet($str, true); // Find javascript URLs to get a client ID preg_match_all("/<script.*src=\"(.*app-.*)\"\s*>/i", $webpage, $jsURLs); if(!isset($jsURLs[1][0])){ return false; } $jsURL = $jsURLs[1][0]; // Grab the client ID from te javascript $jsFile = file_get_contents($jsURL); preg_match_all("/\Wclient_id:\"(.*)\"/iU", $jsFile, $clientIDs); $this->clientID = $clientIDs[1][0]; preg_match("/var\s+c\s*=\s*(\[.*\]),/i", $webpage, $matches); $brackets = 0; $firstRun = true; $strlen = mb_strlen($matches[1]); for($i = 0; $i < $strlen; $i++){ if(!$firstRun && $brackets == 0){ break; } if($firstRun){ $firstRun = false; } $char = $matches[1][$i]; if($char == "["){ $brackets += 1; } else if($char == "]"){ $brackets -= 1; } } $json = mb_substr($matches[1], 0, $i); $this->audioJSON = json_decode($json, true); if(empty($this->audioJSON)){ return false; } foreach($this->audioJSON as $a){ $a = $a["data"][0]; if(isset($a["title"]) && isset($a["uri"]) && isset($a["description"])){ $id = explode("/", $a["uri"]); $videoId = $id[count($id) - 1]; $description = $a["description"]; $title = $a["title"]; $author = $a["user"]["username"]; if(isset($a["artwork_url"]) && $a["artwork_url"] != null){ $this->thumbnailURL = str_replace("large.jpg", "t500x500.jpg", $a["artwork_url"]); } else{ $this->thumbnailURL = str_replace("large.jpg", "t500x500.jpg", $a["user"]["avatar_url"]); } return ["ID" => $videoId, "description" => $description, "title" => $title, "author" => $author]; } } error_log("SoundCloud failed to parse JSON for URL: " . $str); return false; } /** * Checks if all thumbnail, video, and mp3 are downloaded and have a length (ie. video or audio are not null) * * @return bool */ public function allDownloaded(){ $downloadPath = DOWNLOAD_PATH . DIRECTORY_SEPARATOR; $fullDownloadPath = $downloadPath . $this->video->getFilename() . $this->video->getFileExtension(); // If the thumbnail has not been downloaded, go ahead and download it if(!file_exists($downloadPath . $this->video->getThumbnailFilename())){ $this->downloadThumbnail(); } // If the mp3 check if the mp3 has a duration that is not null if(file_exists($fullDownloadPath) && SupportedSite::getDuration($fullDownloadPath)){ // Before returning true, set the duration since convert will not be run $this->video->setDuration(SupportedSite::getDurationSeconds($fullDownloadPath)); return true; } // If all else fails, return false return false; } /** * Download thumbnail */ public function downloadThumbnail(){ $path = getcwd() . DIRECTORY_SEPARATOR . DOWNLOAD_PATH . DIRECTORY_SEPARATOR; $thumbnail = $path . $this->video->getThumbnailFilename(); file_put_contents($thumbnail, fopen($this->thumbnailURL, "r")); // Set the thumbnail file as publicly accessible @chmod($thumbnail, 0775); } private function getDownloadURL(){ $streamsURL = str_replace("/XYZ/", "/" . $this->video->getId() . "/", $this->streamsBaseURL); $streamsJSON = file_get_contents($streamsURL.$this->clientID); $streamsJSON = json_decode($streamsJSON, true); return $streamsJSON["http_mp3_128_url"]; } public function downloadVideo(){ $path = getcwd() . DIRECTORY_SEPARATOR . DOWNLOAD_PATH . DIRECTORY_SEPARATOR; $videoPath = $path . $this->video->getFilename() . $this->video->getFileExtension(); $url = $this->getDownloadURL(); if($this->downloadWithPercentage($url, $videoPath)){ $this->applyArt(); // Send progress to UI $response = ['stage' => 1, 'progress' => 100]; echo json_encode($response); return true; } return false; } /** * Since SoundCloud is audio only, we do not convert, but only add the album artwork */ public function convert(){ } public static function supportsURL($url){ return mb_strpos($url, "soundcloud.com") > -1; } } |