PageRenderTime 133ms CodeModel.GetById 40ms RepoModel.GetById 8ms app.codeStats 0ms

/system/server/youtube/FetchData.php

https://github.com/ffiadmin/Denial-Detour
PHP | 175 lines | 92 code | 34 blank | 49 comment | 13 complexity | 3ce70944e29965d34c248b8e1c01a011 MD5 | raw file
  1. <?php
  2. /**
  3. * Denial Detour
  4. *
  5. * LICENSE
  6. *
  7. * By viewing, using, or actively developing this application in any way, you are
  8. * henceforth bound the license agreement, and all of its changes, set forth by
  9. * ForwardFour Innovations. The license can be found, in its entirety, at this
  10. * address: http://forwardfour.com/license.
  11. *
  12. * Copyright (c) 2012 and Onwards, ForwardFour Innovations
  13. * http://forwardfour.com/license [Proprietary/Closed Source]
  14. */
  15. /**
  16. * FetchData is a class which reads a standard YouTube video URL and parses it
  17. * in order to fetch all revalent data about a given video from the YouTube data
  18. * API.
  19. */
  20. class FetchData {
  21. private $videoID = 0;
  22. public function __construct($URL) {
  23. //Use PHP's native capabilites to capture and parse the URL
  24. $URLFragments = parse_url($URL);
  25. //Check and see if a URL was provided
  26. if (empty($URL)) {
  27. echo "<data><status>error</status><message><title>No Link Provided</title><content>You did not provide us with a link! Please go back and enter the link of the video you wish to watch, or search YouTube for a one.</content></message></data>";
  28. }
  29. //Parse $URLFragments['query'] for the video ID
  30. if (!empty($URLFragments['query'])) {
  31. //Break up each of the parameters, which are deliminated by the ampersand
  32. $parameters = explode("&", $URLFragments['query']);
  33. //Then look for the attribute named "v", which contains the video ID
  34. foreach($parameters as $param) {
  35. $paramSegment = explode("=", $param);
  36. if (strtolower($paramSegment['0']) == "v") {
  37. $this->videoID = $paramSegment['1'];
  38. break;
  39. }
  40. }
  41. //Not URL query was passed
  42. } else {
  43. echo "<data><status>error</status><message><title>Invalid Link Provided</title><content>We could not understand the link that you gave us. Although it does link to youtube.com, it does not appear to link to any video. A typical video link from YouTube looks like this: www.youtube.com/watch?v=XXXXXXXXXXX, where the list of Xs can be any combination of letters or numbers. Try finding a link that looks similar to this an try again.</content></message></data>";
  44. }
  45. //Check and see if the URL is in the format youtube.com/watch?v=XXXXXXXXXXX and that the video ID was found
  46. //The video ID will be 10 if the URL query was invalid or unparsable
  47. if ($this->videoID != "0") {
  48. //Now that all of the tests have been passed, fetch the data URL
  49. echo print_r($this->fetch($this->videoID));
  50. } else {
  51. echo "<data><status>error</status><message><title>Invalid Link Provided</title><content>We could not understand the link that you gave us. Although it does link to youtube.com, it does not appear to link to any video. A typical video link from YouTube looks like this: www.youtube.com/watch?v=XXXXXXXXXXX, where the list of Xs can be any combination of letters or numbers. Try finding a link that looks similar to this an try again.</content></message></data>";
  52. }
  53. }
  54. private function fetch($ID) {
  55. //Build the API URL from the given data
  56. $URL = "http://youtube.com/get_video_info?video_id=" . $ID;
  57. //Fetch the contents of the requested page
  58. $contents = file_get_contents($URL);
  59. //Explode query so that the entire query can be parsed into an array
  60. $firstSplit = explode("&", $contents);
  61. //Parse the contents into an array
  62. $return = array();
  63. foreach ($firstSplit as $value) {
  64. $secondSplit = explode("=", $value);
  65. //Some parameters will require additional parsing
  66. switch ($secondSplit['0']) {
  67. //The "url_encoded_fmt_stream_map" parameter is weird and it required more parsing, as in includes all of the video URLs
  68. case "url_encoded_fmt_stream_map" :
  69. //This is a URL encoded query within the "url_encoded_fmt_stream_map", so this requires it own, subparser
  70. $URLFMTsSplit = explode("&", urldecode($secondSplit['1']));
  71. $returnURLFMTs = array();
  72. //This query value has parameter names that repeat in a pattern: url, quality, fallback_host, type, itag. Append an interator to avoid conflicts
  73. $iterator = 1;
  74. foreach ($URLFMTsSplit as $URLFMTs) {
  75. $URLFMTsDetails = explode("=", $URLFMTs);
  76. switch ($URLFMTsDetails['0']) {
  77. //The "type" parameter *may* have an embedded "codecs" paramter that can be pulled out
  78. case "type" :
  79. //There will be a "; ", if a codec name is provided
  80. $typeSplit = explode("; ", urldecode($URLFMTsDetails['1']));
  81. $returnCodecs = array();
  82. //Generate the "codecs" parameter
  83. if (!empty($typeSplit['1'])) {
  84. //If we are given this for the codec parameter: codecs="vp8.0, vorbis", strip the 'codecs="' and '"'
  85. $codecs = str_replace('codecs="', "", $typeSplit['1']);
  86. $codecs = str_replace('"', "", $codecs);
  87. $codecs = explode(", ", $codecs);
  88. foreach ($codecs as $codec) {
  89. $returnCodecs[] = urldecode($codec);
  90. }
  91. }
  92. //Append "type" parameter
  93. $returnURLFMTs["type_" . $iterator] = urldecode($typeSplit['0']);
  94. //Append the codecs parameter
  95. $returnURLFMTs["codecs_" . $iterator] = $returnCodecs;
  96. break;
  97. //The "itag" parameter requires even more parsing as a video URL is listed within this parameter
  98. case "itag" :
  99. $itagSplit = explode(",", urldecode($URLFMTsDetails['1']));
  100. //The above split seperated the "itag" number from an attached "url" parameter. Attach the "itag" parameter here...
  101. $returnURLFMTs[$URLFMTsDetails['0'] . "_" . $iterator] = urldecode($itagSplit['0']);
  102. //...increment the iterator at the end of every pattern (which is after each "itag" parameter) ...
  103. $iterator ++;
  104. //... finally append the next "url" parameter. Note that the last "itag" in the list will not have a URL (WHY???)
  105. //Note the use of the "$URLFMTsDetails", since the explode at the "=" exploded this off the end of the "itag" parameter, and must be retrieved there
  106. if (!empty($URLFMTsDetails['2'])) {
  107. $returnURLFMTs["url_" . $iterator] = urldecode($URLFMTsDetails['2']);
  108. }
  109. break;
  110. //This can be parse regularily
  111. default :
  112. $returnURLFMTs[$URLFMTsDetails['0'] . "_" . $iterator] = urldecode($URLFMTsDetails['1']);
  113. break;
  114. }
  115. }
  116. $return[$secondSplit['0']] = $returnURLFMTs;
  117. break;
  118. //Break the following parametersy into an array
  119. case "keywords" :
  120. case "fmt_list" :
  121. case "ad_channel_code_overlay" :
  122. case "fexp" :
  123. case "excluded_ads" :
  124. case "watermark" :
  125. $objectSplit = explode(",", urldecode($secondSplit['1']));
  126. $returnObject = array();
  127. foreach ($objectSplit as $object) {
  128. $returnObject[] = urldecode($object);
  129. }
  130. $return[$secondSplit['0']] = $returnObject;
  131. break;
  132. //This can be parse regularily
  133. default :
  134. $return[$secondSplit['0']] = urldecode($secondSplit['1']);
  135. break;
  136. }
  137. }
  138. return $return;
  139. }
  140. }
  141. ?>