archive.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. /**
  3. * @file
  4. * This is an archive.org provider include file for Embedded Media Video.
  5. */
  6. /**
  7. * This is the main URL for your provider.
  8. */
  9. define('EMVIDEO_ARCHIVE_MAIN_URL', 'http://www.archive.org/');
  10. /**
  11. * This is the URL to the API of your provider, if this exists.
  12. */
  13. define('EMVIDEO_ARCHIVE_API_URL', 'http://www.google.com/search?q=archive.org+api');
  14. /**
  15. * This defines the version of the content data array that we serialize
  16. * in emvideo_archive_data(). If we change the expected keys of that array,
  17. * we must increment this value, which will allow older content to be updated
  18. * to the new version automatically.
  19. */
  20. define('EMVIDEO_ARCHIVE_DATA_VERSION', 2);
  21. /**
  22. * hook emvideo_PROVIDER_info
  23. * This returns information relevant to a specific 3rd party video provider.
  24. *
  25. * @return
  26. * A keyed array of strings requested by various admin and other forms.
  27. * 'provider' => The machine name of the provider. This must be the same as
  28. * the base name of this filename, before the .inc extension.
  29. * 'name' => The translated name of the provider.
  30. * 'url' => The url to the main page for the provider.
  31. * 'settings_description' => A description of the provider that will be
  32. * posted in the admin settings form.
  33. * 'supported_features' => An array of rows describing the state of certain
  34. * supported features by the provider. These will be rendered in a table,
  35. * with the columns being 'Feature', 'Supported', 'Notes'. In general,
  36. * the 'Feature' column will give the name of the feature, 'Supported'
  37. * will be Yes or No, and 'Notes' will give an optional description or
  38. * caveats to the feature.
  39. */
  40. function emvideo_archive_info() {
  41. $features = array(
  42. array(t('Autoplay'), t('Yes'), ''),
  43. array(t('RSS Attachment'), t('Yes'), ''),
  44. array(t('Thumbnails'), t('Yes'), t('')),
  45. array(t('Full screen mode'), t('Yes'), t('You may customize the player to enable or disable full screen playback. Full screen mode is enabled by default.')),
  46. );
  47. return array(
  48. 'provider' => 'archive',
  49. 'name' => t('archive.org'),
  50. 'url' => EMVIDEO_ARCHIVE_MAIN_URL,
  51. 'settings_description' => t('These settings specifically affect videos displayed from !archive. You can also read more about its !api.', array('!archive' => l(t('Archive.com'), EMVIDEO_ARCHIVE_MAIN_URL), '!api' => l(t("developer's API"), EMVIDEO_ARCHIVE_API_URL))),
  52. 'supported_features' => $features,
  53. );
  54. }
  55. /**
  56. * hook emvideo_PROVIDER_settings
  57. * This should return a subform to be added to the emvideo_settings() admin
  58. * settings page.
  59. *
  60. * Note that a form field set will already be provided at $form['archive'],
  61. * so if you want specific provider settings within that field set, you should
  62. * add the elements to that form array element.
  63. */
  64. function emvideo_archive_settings() {
  65. // We'll add a field set of player options here. You may add other options
  66. // to this element, or remove the field set entirely if there are no
  67. // user-configurable options allowed by the archive provider.
  68. /* $form['archive']['player_options'] = array(
  69. '#type' => 'fieldset',
  70. '#title' => t('Embedded video player options'),
  71. '#collapsible' => TRUE,
  72. '#collapsed' => TRUE,
  73. );
  74. // This is an option to set the video to full screen. You should remove this
  75. // option if it is not provided by the archive provider.
  76. $form['archive']['player_options']['emvideo_archive_full_screen'] = array(
  77. '#type' => 'checkbox',
  78. '#title' => t('Allow fullscreen'),
  79. '#default_value' => variable_get('emvideo_archive_full_screen', 1),
  80. '#description' => t('Allow users to view video using the entire computer screen.'),
  81. );
  82. return $form;*/
  83. }
  84. /**
  85. * hook emvideo_PROVIDER_extract
  86. *
  87. * This is called to extract the video code from a pasted URL or embed code.
  88. *
  89. * We'll be passed a URL or the embed code from a video when an editor pastes
  90. * that in the field's textfield. We'll need to either pass back an array of
  91. * regex expressions to match, or do the matching ourselves and return the
  92. * resulting video code.
  93. *
  94. * @param $parse
  95. * An optional string with the pasted URL or embed code.
  96. * @return
  97. * Either an array of regex expressions to be tested, or a string with the
  98. * video code to be used. If the hook tests the code itself, it should
  99. * return either the string of the video code (if matched), or an empty
  100. * array. Otherwise, the calling function will handle testing the embed code
  101. * against each regex string in the returned array.
  102. */
  103. function emvideo_archive_extract($parse = '') {
  104. // Here we assume that a URL will be passed in the form of
  105. // http://www.archive.org/video/text-video-title
  106. // or embed code in the form of <object value="http://www.archive.org/embed...".
  107. // We'll simply return an array of regular expressions for Embedded Media
  108. // Field to handle for us.
  109. return array(
  110. //In the URL the archive.org item id will appear after "details/" in the URL
  111. '@archive\.org\/details\/([^\"\&]+)@i',
  112. // Now we test for embedded video code, which is similar in this case to
  113. // the above expression, except the item id will appear after "download/"
  114. '@archive\.org/download/([^/]+)@i',
  115. );
  116. }
  117. /**
  118. * Implement hook emvideo_PROVIDER_data_version().
  119. */
  120. function emvideo_archive_data_version() {
  121. return EMVIDEO_ARCHIVE_DATA_VERSION;
  122. }
  123. /**
  124. * hook emvideo_PROVIDER_data
  125. *
  126. * Provides an array to be serialised and made available with $item elsewhere.
  127. *
  128. * This data can be used to store any extraneous information available
  129. * specifically to the archive provider.
  130. */
  131. function emvideo_archive_data($field, $item, $error_field = '') {
  132. // Initialize the data array.
  133. $data = array();
  134. // Create some version control. Thus if we make changes to the data array
  135. // down the road, we can respect older content. If allowed by Embedded Media
  136. // Field, any older content will automatically update this array as needed.
  137. // In any case, you should account for the version if you increment it.
  138. $data['emvideo_archive_version'] = $data['emvideo_data_version'] = EMVIDEO_ARCHIVE_DATA_VERSION;
  139. // Construct a base item url
  140. $item_url = "http://www.archive.org/details/". $item['value'];
  141. $download_url = "http://www.archive.org/download/". $item['value'];
  142. // We will leverage the JSON archive.org api to get details about this item
  143. // See http://www.archive.org/help/json.php
  144. $xml_meta_url = $item_url .'&output=json';
  145. $xml_meta = media_archive_request_xml('archive', $xml_meta_url, array(), TRUE, TRUE, $item['value'] .'_meta', FALSE, TRUE);
  146. if ($xml_meta['stat'] == 'error' || empty($xml_meta)) {
  147. drupal_set_message('This item\'s details cannot be retrieved. The video can not be displayed.');
  148. return $data;
  149. }
  150. else {
  151. $data['details'] = $xml_meta;
  152. $server_url = $data['details']['server'] . $data['details']['dir'];
  153. }
  154. $item_files = $data['details']['files'];
  155. if (!$item_files) {
  156. form_set_error($error_field, 'The list of files for the item at archive.org could not be retrieved. The video can not be displayed.');
  157. return $data;
  158. }
  159. //Putting the $key (which is actually the file name) as an element of the
  160. //array too for convenience later.
  161. foreach ($item_files as $key => $value) {
  162. $item_files[$key]['name'] = $key;
  163. }
  164. //Get only .mp4 files
  165. $files_play = array_filter($item_files, "_archive_video_toplay");
  166. //If there is no playlist then fail
  167. if (is_null($files_play)) {
  168. form_set_error($error_field, 'This archive.org item does not appear to have files to play.');
  169. return $data;
  170. }
  171. //Create a playlist suitable for feeding to player
  172. foreach ($files_play as $file => $file_data) {
  173. $data['playlist'][] = $download_url . $file;
  174. }
  175. // Add the thumbnail data.
  176. $data['thumbnail'] = 'http://www.archive.org/download/'. $item['value'] .'/format=Thumbnail?.jpg';
  177. return $data;
  178. }
  179. /**
  180. * Is this a 512Kb MPEG4 file?
  181. */
  182. function _archive_video_toplay($file) {
  183. if ($file['format'] == "512Kb MPEG4") {
  184. return TRUE;
  185. }
  186. else {
  187. return FALSE;
  188. }
  189. }
  190. /**
  191. * hook emvideo_PROVIDER_duration($item)
  192. * Returns the duration of the video in seconds.
  193. * @param $item
  194. * The video item itself, which needs the $data array.
  195. * @return
  196. * The duration of the video in seconds.
  197. */
  198. function emvideo_archive_duration($item) {
  199. if (!isset($item['data']['emvideo_archive_version'])) {
  200. $item['data'] = emvideo_archive_data(NULL, $item);
  201. }
  202. return isset($item['data']['metadata']['RUNTIME'][0]) ? emvideo_convert_to_seconds($item['data']['metadata']['RUNTIME'][0]) : 0;
  203. }
  204. /**
  205. * hook emvideo_PROVIDER_rss
  206. *
  207. * This attaches a file to an RSS feed.
  208. */
  209. function emvideo_archive_rss($item, $teaser = NULL) {
  210. if ($item['value']) {
  211. $file['thumbnail']['filepath'] = $item['data']['thumbnail'];
  212. return $file;
  213. }
  214. }
  215. /**
  216. * hook emvideo_PROVIDER_embedded_link($video_code)
  217. * returns a link to view the video at the provider's site.
  218. * @param $video_code
  219. * The string containing the video to watch.
  220. * @return
  221. * A string containing the URL to view the video at the original provider's site.
  222. */
  223. function emvideo_archive_embedded_link($video_code) {
  224. return 'http://www.archive.org/details/'. $video_code;
  225. }
  226. /**
  227. * The embedded flash displaying the archive video.
  228. */
  229. function theme_emvideo_archive_flash($item, $width, $height, $autoplay) {
  230. $output = '';
  231. if ($item['embed']) {
  232. $flowplayerplaylist = _media_archive_flowplayer_playlist($item['data']['playlist']);
  233. $controlplaylist = (count($item['data']['playlist'])>1) ? "true" : "false";
  234. $clipautoplay = $autoplay ? 'true' : 'false';
  235. $output = <<<EOD
  236. <embed type="application/x-shockwave-flash" width="$width" height="$height" allowfullscreen="true"
  237. allowscriptaccess="always" src="http://www.archive.org/flow/flowplayer.commercial-3.0.5.swf"
  238. w3c="true" flashvars='config={
  239. "key":"#\$b6eb72a0f2f1e29f3d4",
  240. "playlist":[
  241. {
  242. "url":"{$item['data']['thumbnail']}",
  243. "autoPlay":true,
  244. "scaling":"fit"
  245. },
  246. {$flowplayerplaylist}
  247. ],
  248. "clip":{
  249. "autoPlay":false,
  250. "accelerated":true,
  251. "scaling":"fit"
  252. },
  253. "canvas":{
  254. "backgroundColor":"0x000000",
  255. "backgroundGradient":"none"
  256. },
  257. "plugins":{
  258. "audio":{
  259. "url":"http://www.archive.org/flow/flowplayer.audio-3.0.3-dev.swf"
  260. },
  261. "controls":{
  262. "playlist":{$controlplaylist},
  263. "fullscreen":true,
  264. "gloss":"high",
  265. "backgroundColor":"0x000000",
  266. "backgroundGradient":"medium",
  267. "sliderColor":"0x777777",
  268. "progressColor":"0x777777",
  269. "timeColor":"0xeeeeee",
  270. "durationColor":"0x01DAFF",
  271. "buttonColor":"0x333333",
  272. "buttonOverColor":"0x505050"
  273. }
  274. },
  275. "contextMenu":[
  276. {
  277. "{$item['value']}":"function()"
  278. },
  279. "-",
  280. "Flowplayer 3.0.5"
  281. ]
  282. }'> </embed>
  283. EOD;
  284. }
  285. return $output;
  286. }
  287. /**
  288. * hook emvideo_PROVIDER_thumbnail
  289. * Returns the external url for a thumbnail of a specific video.
  290. * @param $field
  291. * The field of the requesting node.
  292. * @param $item
  293. * The actual content of the field from the requesting node.
  294. * @return
  295. * A URL pointing to the thumbnail.
  296. */
  297. function emvideo_archive_thumbnail($field, $item, $formatter, $node, $width, $height) {
  298. // In this demonstration, we previously retrieved a thumbnail using oEmbed
  299. // during the data hook.
  300. return $item['data']['thumbnail'];
  301. }
  302. /**
  303. * hook emvideo_PROVIDER_video
  304. * This actually displays the full/normal-sized video we want, usually on the
  305. * default page view.
  306. * @param $embed
  307. * The video code for the video to embed.
  308. * @param $width
  309. * The width to display the video.
  310. * @param $height
  311. * The height to display the video.
  312. * @param $field
  313. * The field info from the requesting node.
  314. * @param $item
  315. * The actual content from the field.
  316. * @return
  317. * The html of the embedded video.
  318. */
  319. function emvideo_archive_video($embed, $width, $height, $field, $item, $node, $autoplay) {
  320. $output = theme('emvideo_archive_flash', $item, $width, $height, $autoplay);
  321. return $output;
  322. }
  323. /**
  324. * hook emvideo_PROVIDER_video
  325. *
  326. * This actually displays the preview-sized video we want, commonly for the
  327. * teaser.
  328. * @param $embed
  329. * The video code for the video to embed.
  330. * @param $width
  331. * The width to display the video.
  332. * @param $height
  333. * The height to display the video.
  334. * @param $field
  335. * The field info from the requesting node.
  336. * @param $item
  337. * The actual content from the field.
  338. * @return
  339. * The html of the embedded video.
  340. */
  341. function emvideo_archive_preview($embed, $width, $height, $field, $item, $node, $autoplay) {
  342. $output = theme('emvideo_archive_flash', $item, $width, $height, $autoplay);
  343. return $output;
  344. }
  345. /**
  346. * Implementation of hook_emfield_subtheme().
  347. * This returns any theme functions defined by this provider.
  348. */
  349. function emvideo_archive_emfield_subtheme() {
  350. $themes = array(
  351. 'emvideo_archive_flash' => array(
  352. 'arguments' => array('item' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
  353. 'file' => 'providers/archive.inc',
  354. // If you don't provide a 'path' value, then it will default to
  355. // the emvideo.module path. Obviously, replace 'emarchive' with
  356. // the actual name of your custom module.
  357. //'path' => drupal_get_path('module', 'emarchive'),
  358. )
  359. );
  360. return $themes;
  361. }
  362. /**
  363. * Implement hook_emvideo_PROVIDER_content_generate().
  364. */
  365. function emvideo_archive_content_generate() {
  366. return array(
  367. 'http://www.archive.org/details/DrupalconDc2009-DrupalMultimedia',
  368. 'http://www.archive.org/details/DrupalconBoston2008-DrupalMultimedia',
  369. 'http://www.archive.org/details/drupal_song_dcamp_pune_09',
  370. 'http://www.archive.org/details/Drupal.Peru_DrupalSong20090718',
  371. );
  372. }