for Worcester Community Cable Access http://wccatv.com/ Mike Benedetti is the current technical contact. You can reach WCCA at 508-755-1880 or 415 Main St., Worcester, MA 01608 Notes: Tested with Drupal 5.7, emfield 5.x-1.2, and cck 5.x-1.7 Due to a bug in emfield (or Drupal core?), item data isn't available in the preview Custom colors aren't available since archive.org doesn't support them Version 0.0: Initial version 07/26/2008 Version 0.1: Added support for non-derived mp4s 08/26/2008 Version 0.2: 11/07/1008 Changed method for finding "best" file to embed All archive.org data is now stored in $item["data"]["formats"] Version 0.2.1: 11/15/2005 Turned off "autoBuffering" */ // From youtube.inc, as the suggested example inc file define('EMVIDEO_ARCHIVE_MAIN_URL', 'http://www.archive.org/'); define('EMVIDEO_ARCHIVE_API_INFO', 'http://www.archive.org/help/contrib-advanced.php'); define('EMVIDEO_ARCHIVE_API_APPLICATION_URL', 'http://www.archive.org/account/login.php'); //define('EMVIDEO_ARCHIVE_REST_ENDPOINT', 'http://www.youtube.com/api2_rest'); // Not sure if this line above ^^ relates to archive.org? // Here is a good example of a metadata list below, in case it's helpful as we go: // http://www.archive.org/serve/gd73-03-28.aud-nourse.weiner.16886.sbeok.shnf/gd73-03-28.aud-nourse.weiner.16886.sbeok.shnf_meta.xml // See note above about custom colors - commenting out next two lines for now //define('EMVIDEO_ARCHIVE_COLOR1_DEFAULT', '#FFFFFF'); //define('EMVIDEO_ARCHIVE_COLOR2_DEFAULT', '#CCCCCC'); /* Regular expressions to match archive.org video URLs Currently supports the forms: http://www.archive.org/details/soapbox_615/ (with or without trailing slash) http://www.archive.org/details.php?identifier=soapbox_615 */ define('EMVIDEO_ARCHIVE_URL_REGEXP1','@archive\.org/details/([^"\&/]+)@i'); define('EMVIDEO_ARCHIVE_URL_REGEXP2','@archive\.org/details\.php\?identifier=([^"\&]+)@i'); define('EMVIDEO_ARCHIVE_URL_REGEXP3','@Replace this with something that will match other internet archive URLs@'); // Array Constants global $EMVIDEO_ARCHIVE_NON_VIDEO_FORMATS; $EMVIDEO_ARCHIVE_NON_VIDEO_FORMATS = array("Thumbnail","Metadata","Animated GIF"); /* Function to match preferred video format */ function emvideo_find_best_file($files_by_format) { if (!is_array($files_by_format)) return array(); // Use the 512Kb MPEG4 if it's available. It's H264 and will play in // Flash. if (array_key_exists("512Kb MPEG4",$files_by_format)) { return $files_by_format["512Kb MPEG4"][0]; // Use Flash Video if it's available } elseif (array_key_exists("Flash Video",$files_by_format)) { // Look for a derived flash first foreach ($files_by_format["Flash Video"] as $thisfile) { if ($thisfile["source"] == "derivative") return $thisfile; } // If there's none derived by archive.org, use the first flash video return $files_by_format["Flash Video"][0]; // Use 256Kb MPEG4 as a last resort. Not Flash compatible. } elseif (array_key_exists("256Kb MPEG4",$files_by_format)) { return $files_by_format["256Kb MPEG4"][0]; // Give up. Text list of files will be displayed. } else { return array(); } } /** * hook emvideo_PROVIDER_info * this returns information relevant to a specific 3rd party video provider * @return * an array of strings requested by various admin and other forms * 'name' => the translated name of the provider * 'url' => the url to the main page for the provider * 'settings_description' => a description of the provider that will be posted in the admin settings form * 'supported_features' => an array of rows describing the state of certain supported features by the provider. * These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'. */ function emvideo_archive_info() { $name = t('The Internet Archive'); $features = array( array(t('Autoplay'), t('Yes'), 'Starts playing the embedded video when the page loads'), array(t('RSS Attachment'), t('Yes'), ''), array(t('Show related videos'), t('No'), t('Not supported')), array(t('Thumbnails'), t('Yes'), t('Uses thumbnail from video embedding example')), array(t('Custom player colors'), t('No'), t('Not supported')), ); return array( 'provider' => 'archive', 'name' => $name, 'url' => EMVIDEO_ARCHIVE_MAIN_URL, 'settings_description' => t('Settings for videos from !archive.', array('!archive' => l($name, EMVIDEO_ARCHIVE_MAIN_URL, array('target' => '_blank')))), 'supported_features' => $features, ); } /** * hook emvideo_PROVIDER_settings * this should return a subform to be added to the emvideo_settings() admin settings page. * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['youtube']) * so if you want specific provider settings within that field, you can add the elements to that form field. */ function emvideo_archive_settings() { return $form; } /** * hook emfield_PROVIDER_data * * provides an array to be serialised and made available with $item elsewhere */ function emvideo_archive_data($field, $item) { global $EMVIDEO_ARCHIVE_NON_VIDEO_FORMATS; $data = array(); $id = $item['value']; $data['emvideo_archive_version'] = 0; // Grab the metadata // // It might be possible to use emfield_request_xml(), but there's a bug // in it that prevents it from working with pages with redirects $url = "http://www.archive.org/download/$id/${id}_files.xml"; $result = drupal_http_request($url); if (200 == $result->code || 200 == $result->redirect_code) { $parser = drupal_xml_parser_create($result->data); $vals = array(); $index = array(); xml_parse_into_struct($parser, $result->data, $vals, $index); xml_parser_free($parser); $data["formats"] = array(); for ($i = 0;$i < count($vals);$i++) { if ($vals[$i]["tag"] == "FILE" && $vals[$i]["type"] == "open") { $thisfile = array(); $filename = $thisfile["name"] = $vals[$i]["attributes"]["NAME"]; $thisfile["source"] = $vals[$i]["attributes"]["SOURCE"]; $level = $vals[$i]["level"]; for ($i++;!($vals[$i]["level"] == $level && $vals[$i]["tag"] == "FILE" && $vals[$i]["type"] == "close");$i++) { if (!($vals[$i]["tag"] == "FILE" && $vals[$i]["type"] == "cdata")) { if (!array_key_exists($vals[$i]["tag"], $thisfile)) { $thisfile[$vals[$i]["tag"]] = ""; } $thisfile[$vals[$i]["tag"]] .= $vals[$i]["value"]; } } $thisfile['url'] = "http://www.archive.org/download/$id/$filename"; if (!in_array($thisfile["FORMAT"],$EMVIDEO_ARCHIVE_NON_VIDEO_FORMATS)) { // The file size and type aren't included in the metadata, so we // need to request the file to find them $result = drupal_http_request($thisfile['url'],array(),"HEAD"); if (200 == $result->code || 200 == $result->redirect_code) { $thisfile['size'] = $result->headers["Content-Length"]; $thisfile['mime'] = $result->headers["Content-Type"]; } else { emvideo_archive_error(t("Could not find video size and type for !id on archive.org. The emfield Internet Archive module may need to be updated.",array('!id' => $id))); } } if (!array_key_exists($thisfile["FORMAT"],$data["formats"])) $data["formats"][$thisfile["FORMAT"]] = array(); $data["formats"][$thisfile["FORMAT"]][] = $thisfile; } } if (array_key_exists("Thumbnail",$data["formats"])) { if (count($data["formats"]["Thumbnail"]) >=3) $data['thumbnail']['url'] = $data["formats"]["Thumbnail"][2]["url"]; else $data['thumbnail']['url'] = $data["formats"]["Thumbnail"][count($data["formats"]["Thumbnail"])-1]["url"]; } // The title and description are in this file $url = "http://www.archive.org/download/$id/${id}_meta.xml"; $result = drupal_http_request($url); if (200 == $result->code || 200 == $result->redirect_code) { $parser = drupal_xml_parser_create($result->data); $vals = array(); $index = array(); xml_parse_into_struct($parser, $result->data, $vals, $index); xml_parser_free($parser); foreach ($vals as $val) { if ($val["tag"] == "TITLE" && $val["type"] == "complete") $data['archive_title'] = $val["value"]; if ($val["tag"] == "DESCRIPTION" && $val["type"] == "complete") $data['archive_description'] = $val["value"]; } } else { emvideo_archive_error(t("Could not load metadata meta XML for !id on archive.org. The emfield Internet Archive module may need to be updated.",array('!id' => $id))); } } else { emvideo_archive_error(t("Could not load metadata files XML for !id on archive.org. The emfield Internet Archive module may need to be updated.",array('!id' => $id))); } return $data; } /** * hook EMVIDEO_PROVIDER_RSS */ function emvideo_archive_rss($item, $teaser = NULL) { $file = array(); if (is_array($item['data']['mp4'])) { $file['filepath'] = $item['data']['mp4']['url']; $file['filesize'] = $item['data']['mp4']['size']; $file['filemime'] = $item['data']['mp4']['mime']; } else { $bestfile = emvideo_find_best_file($item['data']['formats']); if (count($bestfile)>0) { $file['filepath'] = $bestfile['url']; $file['filesize'] = $bestfile['size']; $file['filemime'] = $bestfile['mime']; } } $file['thumbnail']['filepath'] = $data['thumbnail']['url']; return $file; } /** * hook emvideo_PROVIDER_extract * this is called to extract the video code from a pasted URL or embed code. * @param $embed * an optional string with the pasted URL or embed code * @return * either an array of regex expressions to be tested, or a string with the video code to be used * if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array. * otherwise, the calling function will handle testing the embed code against each regex string in the returned array. */ function emvideo_archive_extract($embed = '') { return array(EMVIDEO_ARCHIVE_URL_REGEXP1, EMVIDEO_ARCHIVE_URL_REGEXP2, EMVIDEO_ARCHIVE_URL_REGEXP3); } /** * hook emvideo_PROVIDER_embedded_link($video_code) * returns a link to view the video at the provider's site * @param $video_code * the string containing the video to watch * @return * a string containing the URL to view the video at the original provider's site */ function emvideo_archive_embedded_link($video_code) { return 'http://www.archive.org/details/' . $video_code; } /** * hook emvideo_PROVIDER_thumbnail * returns the external url for a thumbnail of a specific video * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things * @param $field * the field of the requesting node * @param $item * the actual content of the field from the requesting node * @return * a URL pointing to the thumbnail */ function emvideo_archive_thumbnail($field, $item, $formatter, $node, $width, $height) { return $item['data']['thumbnail']['url']; } /** * hook emvideo_PROVIDER_video * this actually displays the full/normal-sized video we want, usually on the default page view * @param $embed * the video code for the video to embed * @param $width * the width to display the video * @param $height * the height to display the video * @param $field * the field info from the requesting node * @param $item * the actual content from the field * @return * the html of the embedded video */ // Dispatch to the appropriate embedded video code function emvideo_archive_video($embed, $width, $height, $field, $item, $autoplay) { if (array_key_exists("flv",$item['data'])) return theme('emvideo_archive_flash_legacy', $embed, $width, $height, $autoplay, $item); $bestfile = emvideo_find_best_file($item['data']['formats']); if (array_key_exists("FORMAT",$bestfile)) { if ($bestfile["FORMAT"] == "Flash Video") return theme('emvideo_archive_flash', $embed, $width, $height, $autoplay, $item, $bestfile); elseif ($bestfile["FORMAT"] == "512Kb MPEG4") return theme('emvideo_archive_mp4', $embed, $width, $height, $autoplay, $item, $bestfile); } return theme('emvideo_archive_allvids', $embed, $width, $height, $autoplay, $item); } /** * hook emvideo_PROVIDER_video * this actually displays the preview-sized video we want, commonly for the teaser * @param $embed * the video code for the video to embed * @param $width * the width to display the video * @param $height * the height to display the video * @param $field * the field info from the requesting node * @param $item * the actual content from the field * @return * the html of the embedded video */ function emvideo_archive_preview($embed, $width, $height, $field, $item, $autoplay) { return theme('emvideo_archive_video', $embed, $width, $height, $field , $item, $autoplay); } function theme_emvideo_archive_mp4($embed, $width, $height, $autoplay, $item, $bestfile) { global $base_url; if ($autoplay) { $autoplay = "true"; } else { $autoplay = "false"; } if (count($item['data']) > 1) { $link = $vid = $bestfile['url']; $size = floor($bestfile['size']/(1024*1024)); $title = $item['data']['archive_title']; $desc = $item['data']['archive_description']; if (isset($item['data']['emthumb']['filepath'])) { $thumb = "$base_url/".$item['data']['emthumb']['filepath']; } else { $thumb = $item['data']['thumbnail']['url']; } } else { $vid = ""; $size = "?"; $link = $base_url; $title = t('Not available in preview'); $desc = t('Not available in preview'); $thumb = ""; } return "
Download the mp4 video directly ($size MB) or see other formats.
"; } /** * The embedded flash displaying the arhive.org video. */ function theme_emvideo_archive_flash($embed, $width, $height, $autoplay, $item, $bestfile) { global $base_url; if ($autoplay) { $autoplay = "true"; } else { $autoplay = "false"; } if (count($item['data']) > 1) { $link = $vid = $bestfile['url']; $size = floor($bestfile['size']/(1024*1024)); $title = $item['data']['archive_title']; $desc = $item['data']['archive_description']; if (isset($item['data']['emthumb']['filepath'])) { $thumb = "$base_url/".$item['data']['emthumb']['filepath']; } else { $thumb = $item['data']['thumbnail']['url']; } } else { $vid = ""; $size = "?"; $link = $base_url; $title = t('Not available in preview'); $desc = t('Not available in preview'); $thumb = ""; } return "
Download the flash video directly ($size MB) or see other formats.
"; } // If we can't find a preferred video format, list all the formats function theme_emvideo_archive_allvids($embed, $width, $height, $autoplay, $item) { global $EMVIDEO_ARCHIVE_NON_VIDEO_FORMATS; $output = ""; return $output; } // Display flash video created before version we loaded data for every file function theme_emvideo_archive_flash_legacy($embed, $width, $height, $autoplay, $item) { global $base_url; if ($autoplay) { $autoplay = "true"; } else { $autoplay = "false"; } if (count($item['data']) > 1) { $vid = $item['data']['flv']['url']; $size = floor($item['data']['mp4']['size']/(1024*1024)); $link = $item['data']['mp4']['url']; $title = $item['data']['archive_title']; $desc = $item['data']['archive_description']; if (isset($item['data']['emthumb']['filepath'])) { $thumb = "$base_url/".$item['data']['emthumb']['filepath']; } else { $thumb = $item['data']['thumbnail']['url']; } } else { $vid = ""; $size = "?"; $link = $base_url; $title = t('Not available in preview'); $desc = t('Not available in preview'); $thumb = ""; } return "
Download the mp4 video ($size MB) or see other formats.
"; } // Display an error for the user and log an emfield error function emvideo_archive_error($text) { emfield_set_error($text); drupal_set_message(t("ERROR: ").$text); }