Diffs
Wozozo_WWW_YouTube/tags/0.0.6-stable-20110805233202/Wozozo/WWW/YouTube.php
@@ -0,0 +1,229 @@
+<?php
+require_once 'Wozozo/WWW/YouTube/VideoInfo.php';
+
+class Wozozo_WWW_YouTube
+{
+ const PATH_INFO = 'http://www.youtube.com/get_video_info?video_id=%s';
+ const BASE_URL = 'http://www.youtube.com/watch?v=';
+
+ /**
+ * @var Zend_Http_Client
+ */
+ protected $_httpClient;
+
+ /**
+ * @var array
+ */
+ protected $_config = array('prefer_fmt' => null,
+ 'save' => 'GETCWD', //'GETCWD' will use getcwd();
+ 'request_video_stream' => true, //output stream
+ 'response_video_cleanup' => true
+ );
+ private $_clientStream;
+
+ public function __construct($config = null)
+ {
+ if ($config) $this->setConfig($config);
+ }
+
+ public function setConfig($config = array())
+ {
+ if ($config instanceof Zend_Config) {
+ $config = $config->toArray();
+
+ } elseif (! is_array($config)) {
+ throw new Exception('Array or Zend_Config object expected, got ' . gettype($config));
+ }
+
+ foreach ($config as $k => $v) {
+ $this->_config[strtolower($k)] = $v;
+ }
+
+ return $this;
+ }
+
+ /**
+ *
+ * @param string|Zend_Uri $videoId
+ * @param array|Zend_Config $config
+ * @param $path
+ * @return Wozozo_WWW_YouTube_VideoInfo
+ */
+ public static function download($videoId, $config = array())
+ {
+ $videoId = self::detectVideoId($videoId);
+
+ $self = new self($config);
+
+ $videoInfo = $self->getVideoInfo($videoId);
+ $self->downloadByVideoInfo($videoInfo);
+
+ return $videoInfo;
+ }
+
+ protected function _putVideo($response, Wozozo_WWW_YouTube_VideoInfo $videoInfo, $config)
+ {
+
+ if (is_string($config['save'])) {
+ $path = $this->suggestSavePath($videoInfo);
+ } else {
+
+ return call_user_func($config['save'], $response, $videoInfo, $config);
+ }
+
+ $ret = @file_put_contents($path, $response->getRawBody());
+ if ($ret === false) {
+ throw new Exception('cannot write at' . $path);
+ }
+ }
+
+ /**
+ * request & get videoinfo
+ *
+ * @param string $videoId
+ */
+ public function getVideoInfo($videoId)
+ {
+ $client = $this->getHttpClient();
+
+ $client->setUri(sprintf(self::PATH_INFO, $videoId));
+ $response = $client->request();
+
+ parse_str($response->getBody(), $parse);
+
+ return new Wozozo_WWW_YouTube_VideoInfo($parse);
+ }
+
+ /**
+ * Request video file
+ *
+ * @param Wozozo_WWW_YouTube_VideoInfo
+ * @return Zend_Http_Response_Stream
+ */
+ public function requestVideo(Wozozo_WWW_YouTube_VideoInfo $videoInfo)
+ {
+ // retrive url & save-file-path
+ $url = $videoInfo->makeDownloadUrl($this->_config['prefer_fmt']);
+
+ $client = $this->getHttpClient();
+ $client->setUri($url);
+
+ try {
+ $this->_setupClientStream();
+ $response = $client->request();
+ $this->_restoreClientStream();
+ $response->setCleanup($this->_config['response_video_cleanup']);
+
+ return $response;
+ } catch (Exception $e) {
+ // ensure, restore HttpClient's origin stream
+ $this->_restoreClientStream();
+ throw $e;
+ }
+ }
+
+ public function downloadByVideoInfo(Wozozo_WWW_YouTube_VideoInfo $videoInfo)
+ {
+ $response = $this->requestVideo($videoInfo);
+
+ $this->_putVideo($response, $videoInfo, $this->_config);
+ }
+
+ private function _setupClientStream()
+ {
+ $this->_clientStream = $this->getHttpClient()->getStream();
+ $this->getHttpClient()->setStream($this->_config['request_video_stream']);
+ }
+
+ private function _restoreClientStream()
+ {
+ $this->getHttpClient()->setStream($this->_clientStream);
+ }
+
+ public function getHttpClient()
+ {
+ if (!$this->_httpClient) {
+ require_once 'Zend/Http/Client.php';
+ $this->_httpClient = new Zend_Http_Client(null, array('useragent' => __CLASS__));
+ }
+
+ return $this->_httpClient;
+ }
+
+ public function setHttpClient(Zend_Http_Client $client)
+ {
+ $this->_httpClient = $client;
+ }
+
+ public function suggestSavePath($videoInfo)
+ {
+ $dir = $this->_config['save'];
+ $fmt = $this->_config['prefer_fmt'];
+ if ('GETCWD' === $dir) {
+ $dir = getcwd();
+ } else {
+ if(!is_dir($dir)) {
+ throw new InvalidArgumentException('Invalid dir'.$dir);
+ }
+ }
+ $path = $dir . DIRECTORY_SEPARATOR . $videoInfo['video_id'] . self::detectSuffix($videoInfo->detectFmt($fmt));
+
+ return $path;
+ }
+
+ /**
+ * borrowed from WWW::YouTube::Download
+ *
+ * @see
+ * http://cpansearch.perl.org/src/XAICRON/WWW-YouTube-Download-0.13/lib/WWW/YouTube/Download.pm
+ *
+ * @param string
+ * @return string
+ */
+ public static function detectSuffix($fmt)
+ {
+ switch ($fmt) {
+ case '18' :
+ case '22' :
+ case '37' :
+ case '38' :
+ return '.mp4';
+ case '17' :
+ return '.3gp';
+ case '43':
+ case '45':
+ return '.vp8';
+ default :
+ return '.flv';
+ }
+ }
+
+ /**
+ * detect videoId
+ *
+ * @param string $var (url)
+ * @return string|false
+ */
+ public static function detectVideoId($var)
+ {
+ if (is_string($var)) {
+ if (!preg_match('#^h*(?:ttp\:\/\/)(.+\/watch\?v=.*)#', $var, $match)) {
+ if (!preg_match('#^[A-Za-z0-9]+$#', $var)) {
+ throw new InvalidArgumentException('Invalid id '.$var);
+ }
+ return trim($var);
+ }
+ //uri
+ require_once 'Zend/Uri.php';
+ $var = Zend_Uri::factory('http://'.$match[1]);
+ }
+
+ if ($var instanceof Zend_Uri_Http) {
+ $query = $var->getQueryAsArray();
+ return $query['v'];
+ }
+
+ return false;
+ }
+}
+
Wozozo_WWW_YouTube/tags/0.0.6-stable-20110805233202/Wozozo/WWW/YouTube/Storage/Couchdb.php
@@ -0,0 +1,52 @@
+<?php
+require_once 'Sopha/Db.php';
+
+class Wozozo_WWW_YouTube_Storage_Couchdb
+{
+ private $_document;
+ private $_url;
+ private $_name = 'video';
+
+ public function __construct($videoInfo, $url, $dbname, $host = 'localhost', $port = Sopha_Db::COUCH_PORT)
+ {
+ $db = new Sopha_Db($dbname, $host, $port);
+
+ $this->_validateExists($url, $db);
+
+ $this->_document = new Sopha_Document($videoInfo->toArray(), $url, $db);
+
+ $this->_url = $db->getUrl().urlencode($url).'/'.$this->_name;
+ }
+
+ public function setAttachmentName($name)
+ {
+ $this->_name = $name;
+ }
+
+ public function getUrl()
+ {
+ //return $this->_document->getUrl();
+ return $this->_url;
+ }
+
+ private function _validateExists($url, $db)
+ {
+ if ($db->retrieve($url)) {
+ throw new Exception($url . 'is already used.');
+ }
+ }
+
+ //save
+ public function callbackUpdate($response, $videoInfo, $config)
+ {
+ $document = $this->_document;
+ $document->save();
+
+ $type = 'video/x-flv';
+ $document->setAttachment($this->_name, $type, $response->getRawBody());
+
+ $document->save();
+ }
+
+}
+
Wozozo_WWW_YouTube/tags/0.0.6-stable-20110805233202/Wozozo/WWW/YouTube/HttpSocketProgressBar.php
@@ -0,0 +1,232 @@
+<?php
+
+require_once 'Zend/Http/Client/Adapter/Socket.php';
+class Wozozo_WWW_YouTube_HttpSocketProgressBar extends Zend_Http_Client_Adapter_Socket
+{
+ private $_max = 0;
+ private $_progressBar;
+
+ public function setMax($max)
+ {
+ $this->_max = $max;
+ }
+
+ public function getMax()
+ {
+ return $this->_max;
+ }
+
+ private function getProgressBar()
+ {
+ if (PHP_SAPI != 'cli') throw new RuntimeException();
+
+ if (!$this->_progressBar) {
+ require_once 'Zend/ProgressBar/Adapter/Console.php';
+ require_once 'Zend/ProgressBar.php';
+ $adapter = new Zend_ProgressBar_Adapter_Console();
+ $this->_progressBar = new Zend_ProgressBar($adapter, 0, $this->getMax());
+ }
+
+ return $this->_progressBar;
+
+ }
+
+ /**
+ * Read response from server
+ *
+ * @return string
+ */
+ public function read()
+ {
+ // First, read headers only
+ $response = '';
+ $gotStatus = false;
+ $stream = !empty($this->config['stream']);
+
+ while (($line = @fgets($this->socket)) !== false) {
+ $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
+ if ($gotStatus) {
+ $response .= $line;
+ if (rtrim($line) === '') break;
+ }
+ }
+
+ $this->_checkSocketReadTimeout();
+
+ $statusCode = Zend_Http_Response::extractCode($response);
+
+ // Handle 100 and 101 responses internally by restarting the read again
+ if ($statusCode == 100 || $statusCode == 101) return $this->read();
+
+ // Check headers to see what kind of connection / transfer encoding we have
+ $headers = Zend_Http_Response::extractHeaders($response);
+
+ /**
+ * Responses to HEAD requests and 204 or 304 responses are not expected
+ * to have a body - stop reading here
+ */
+ if ($statusCode == 304 || $statusCode == 204 ||
+ $this->method == Zend_Http_Client::HEAD) {
+
+ // Close the connection if requested to do so by the server
+ if (isset($headers['connection']) && $headers['connection'] == 'close') {
+ $this->close();
+ }
+ return $response;
+ }
+
+ // If we got a 'transfer-encoding: chunked' header
+ if (isset($headers['transfer-encoding'])) {
+
+ if (strtolower($headers['transfer-encoding']) == 'chunked') {
+
+ do {
+ $line = @fgets($this->socket);
+ $this->_checkSocketReadTimeout();
+
+ $chunk = $line;
+
+ // Figure out the next chunk size
+ $chunksize = trim($line);
+ if (! ctype_xdigit($chunksize)) {
+ $this->close();
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' .
+ $chunksize . '" unable to read chunked body');
+ }
+
+ // Convert the hexadecimal value to plain integer
+ $chunksize = hexdec($chunksize);
+
+ // Read next chunk
+ $read_to = ftell($this->socket) + $chunksize;
+
+ do {
+ $current_pos = ftell($this->socket);
+ if ($current_pos >= $read_to) break;
+
+ if($this->out_stream) {
+ if(stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ }
+ } else {
+ $line = @fread($this->socket, $read_to - $current_pos);
+ if ($line === false || strlen($line) === 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ }
+ $chunk .= $line;
+ }
+ } while (! feof($this->socket));
+
+ $chunk .= @fgets($this->socket);
+ $this->_checkSocketReadTimeout();
+
+ if(!$this->out_stream) {
+ $response .= $chunk;
+ }
+ } while ($chunksize > 0);
+ } else {
+ $this->close();
+ throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' .
+ $headers['transfer-encoding'] . '" transfer encoding');
+ }
+
+ // We automatically decode chunked-messages when writing to a stream
+ // this means we have to disallow the Zend_Http_Response to do it again
+ if ($this->out_stream) {
+ $response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $response);
+ }
+ // Else, if we got the content-length header, read this number of bytes
+ } elseif (isset($headers['content-length'])) {
+
+ // If we got more than one Content-Length header (see ZF-9404) use
+ // the last value sent
+ if (is_array($headers['content-length'])) {
+ $contentLength = $headers['content-length'][count($headers['content-length']) - 1];
+ } else {
+ $contentLength = $headers['content-length'];
+ }
+
+ if ($contentLength != 0) $this->setMax($contentLength);
+
+ $current_pos = ftell($this->socket);
+ $chunk = '';
+
+ $startProgressBar = false;
+ for ($read_to = $current_pos + $contentLength;
+ $read_to > $current_pos;
+ $current_pos = ftell($this->socket)) {
+
+ if ($startProgressBar === false) {
+ $this->setMax($read_to);
+ $startProgressBar = true;
+ }
+ $this->getProgressBar()->update($current_pos);
+
+ //if($this->out_stream) {
+
+ /*
+ if(@stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ }
+ */
+ //} else {
+ $chunk = @fread($this->socket, $read_to - $current_pos);
+ if ($chunk === false || strlen($chunk) === 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ }
+
+ if ($this->out_stream) {
+ $fwrite = fwrite($this->out_stream, $chunk);
+ if ($fwrite === false) {
+ $this->close();
+ throw new Exception('cannot write stream');
+ }
+ } else {
+ $response .= $chunk;
+ }
+ //}
+
+ // Break if the connection ended prematurely
+ if (feof($this->socket)) break;
+ }
+ if ($startProgressBar) $this->getProgressBar()->finish();
+
+ // Fallback: just read the response until EOF
+ } else {
+
+ do {
+ if($this->out_stream) {
+ if(@stream_copy_to_stream($this->socket, $this->out_stream) == 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ }
+ } else {
+ $buff = @fread($this->socket, 8192);
+ if ($buff === false || strlen($buff) === 0) {
+ $this->_checkSocketReadTimeout();
+ break;
+ } else {
+ $response .= $buff;
+ }
+ }
+
+ } while (feof($this->socket) === false);
+
+ $this->close();
+ }
+
+ // Close the connection if requested to do so by the server
+ if (isset($headers['connection']) && $headers['connection'] == 'close') {
+ $this->close();
+ }
+
+ return $response;
+ }
+
+}
+
Wozozo_WWW_YouTube/tags/0.0.6-stable-20110805233202/Wozozo/WWW/YouTube/VideoInfo.php
@@ -0,0 +1,210 @@
+<?php
+
+class Wozozo_WWW_YouTube_VideoInfo implements ArrayAccess
+{
+
+ const FORMAT_FLV = 'flv';
+ const FORMAT_MP4 = 'mp4';
+ const FORMAT_3GP = '3gp';
+ const FORMAT_VP8 = 'vp8';
+
+ private $_parsedVideoInfo;
+
+ public function __construct(array $parsedVideoInfo)
+ {
+ if (!isset($parsedVideoInfo['status'])) {
+ $msg = implode('', $parsedVideoInfo);
+ throw new UnexpectedValueException("invalid array is passed, array has not 'status' - key");
+ }
+
+ $this->_parsedVideoInfo = $parsedVideoInfo;
+ }
+
+ public function makeDownloadUrl($preferFmt = null)
+ {
+ $fmtUrlMap = $this->makeDownloadUrls();
+
+ // get detected high quality fmt
+ $fmt = $this->detectFmt($preferFmt);
+
+ return $fmtUrlMap[$fmt];
+ }
+
+ public function makeDownloadUrls()
+ {
+ if ($this->_parsedVideoInfo['status'] !== 'ok') {
+ if ($this->_parsedVideoInfo['status'] === 'fail') {
+ throw new Exception($this->_parsedVideoInfo['reason'], $this->_parsedVideoInfo['errorcode']);
+ } else {
+ throw new Exception('error raise by unknown status'.$this->_parsedVideoInfo['status']);
+ }
+ }
+
+ // get detected high quality fmt
+ //$fmt = $this->detectFmt($preferFmt);
+
+ //$fmtUrlMap = $this->parseFmtUrlMap();
+ $fmtUrlMap = $this->parseUrlEncodedFmtStreamMap();
+
+ return $fmtUrlMap;
+ }
+
+ /**
+ * detect format int (High)
+ *
+ * @see http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
+ *
+ * @param int|string|null
+ * @return int
+ */
+ public function detectFmt($preferFmt = null)
+ {
+ if (is_integer($preferFmt)) {
+ return $preferFmt;
+ }
+
+ //$fmts = $this->parseFmtUrlMap();
+ $fmts = $this->parseUrlEncodedFmtStreamMap();
+
+ if (null === $preferFmt) {
+ return key($fmts); //@todo calcurate high fmt
+ }
+
+ $keys = array_keys($fmts);
+
+ switch (strtolower($preferFmt)) {
+ case self::FORMAT_MP4:
+ $fmt = current(array_intersect($keys, array(38, 37, 22, 18)));
+ break;
+ case self::FORMAT_VP8:
+ $fmt = current(array_intersect($keys, array(45, 43)));
+ break;
+ case self::FORMAT_FLV:
+ $fmt = current(array_intersect($keys, array(35, 34, 5)));
+ break;
+ case self::FORMAT_VP8:
+ $fmt = current(array_intersect($keys, array(17)));
+ break;
+ default:
+ throw new Exception('unknown format');
+ }
+
+ if (false === $fmt) {
+ throw new Exception("couldn't find format");
+ }
+
+ return $fmt;
+ }
+
+ /**
+ * @deprecated
+ *
+ * Get format list
+ * fmt_list or fmt_map
+ * eg. 22/2000000/9/0/115,35/640000/9/0/115,34/0/9/0/115,5/0/7/0/0"
+ *
+ * @return array
+ */
+ public function getFmts()
+ {
+ if (preg_match_all('#(?:^|,)([\d]+)#', $this->offsetGet('fmt_list'), $m)) {
+ return $m[1];
+ } else {
+ throw new Exception('extract fmt_list error');
+ }
+
+ }
+
+ public function offsetExists($offset)
+ {
+ return isset($this->_parsedVideoInfo[$offset]);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->_parsedVideoInfo[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ $this->_parsedVideoInfo[$offset] = $value;
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->_parsedVideoInfo[$offset]);
+ }
+
+ public function toArray()
+ {
+ return $this->_parsedVideoInfo;
+ }
+
+ public function __toString()
+ {
+ return http_build_query($this->_parsedVideoInfo, null, '&');
+ }
+
+ public function parseUrlEncodedFmtStreamMap()
+ {
+
+ if (!($this->offsetExists('url_encoded_fmt_stream_map'))) {
+ throw new RuntimeException('fmt_url_map not exists');
+ }
+
+ //$fmtUrlMap = $this->offsetGet('fmt_url_map');
+ $fmtMap = $this->offsetGet('url_encoded_fmt_stream_map');
+ $maps = preg_split('#(,*)url\=#', $fmtMap);
+
+ array_shift($maps);
+
+ $ret = array();
+ foreach ($maps as $map){
+ //preg_match('#(.+)\&itag=([0-9]+)$#', $map, $m);
+ preg_match('#(.+)(&type=.*)\&itag=([0-9]+)$#', $map, $m);
+ $ret[$m[3]] = urldecode($m[1]);
+ }
+
+ return $ret;
+
+ }
+
+ /**
+ * @deprecated
+ */
+ public function parseFmtUrlMap()
+ {
+ if (!($this->offsetExists('fmt_url_map'))) {
+ throw new RuntimeException('fmt_url_map not exists');
+ }
+
+ $fmtUrlMap = $this->offsetGet('fmt_url_map');
+ $maps = preg_split('#,#', $fmtMap);
+
+ $ret = array();
+ foreach ($maps as $map){
+ list($key, $var) = preg_split('#\|#', $map);
+ $ret[$key] = $var;
+ }
+
+ return $ret;
+ }
+
+ public function parseFmtMap()
+ {
+ if (!($this->offsetExists('fmt_map'))) {
+ throw new RuntimeException('fmt_map not exists');
+ }
+
+ $fmtMap = $this->offsetGet('fmt_map');
+ $maps = preg_split('#,#', $fmtMap);
+
+ $ret = array();
+ foreach ($maps as $map){
+ $m = preg_split('#/#', $map);
+ $ret[array_shift($m)] = $m;
+ }
+
+ return $ret;
+ }
+}
Wozozo_WWW_YouTube/tags/0.0.6-stable-20110805233202/Wozozo/WWW/YouTube/Tool/YoutubeProvider.php
@@ -0,0 +1,139 @@
+<?php
+require_once 'Wozozo/WWW/YouTube.php';
+require_once 'Zend/Tool/Framework/Provider/Abstract.php';
+
+class Wozozo_WWW_YouTube_Tool_YoutubeProvider extends Zend_Tool_Framework_Provider_Abstract
+{
+ protected $_specialties = array('SendQueue', 'Couchdb');
+
+ /**
+ * @var Wozozo_WWW_YouTube
+ */
+ protected $_youtube;
+
+ public function getDownloadUrl($id)
+ {
+ $videoId = Wozozo_WWW_YouTube::detectVideoId($id);
+ $youtube = $this->_loadYoutube();
+ $url = $youtube->getVideoInfo($videoId)->makeDownloadUrl();
+
+ $this->_out($url);
+ }
+
+ public function getDownloadUrls($id)
+ {
+ $videoId = Wozozo_WWW_YouTube::detectVideoId($id);
+ $youtube = $this->_loadYoutube();
+ $urls = $youtube->getVideoInfo($videoId)->makeDownloadUrls();
+
+ $this->_out(var_export($urls, true));
+ }
+
+ public function download($id, $path = 'GETCWD', $format = 'DETECT')
+ {
+ $format = ('DETECT' === $format) ? null : $format;
+ $this->_download($id, $format, $path, false);
+ }
+
+ public function downloadCouchdb($id)
+ {
+ $this->_download($id, $format, null, true);
+ }
+
+ private function _setupSave($videoInfo, $path = null, $couch = false)
+ {
+ if ($couch) {
+ $config = $this->_loadConfig('couchdb');
+ if (!isset($config->dbname)) {
+ throw new Exception ('should config dbname');
+ }
+ if ($dbname = $config->dbname) {
+ require_once 'Wozozo/WWW/YouTube/Storage/Couchdb.php';
+ $storage = new Wozozo_WWW_YouTube_Storage_Couchdb($videoInfo, $videoInfo['video_id'], $dbname);
+ $this->_youtube->setConfig(array('save' => array($storage, 'callbackUpdate')));
+
+ return $storage->getUrl();
+ }
+ } else {
+ $this->_youtube->setConfig(array('save' => $path));
+ $path = $this->_youtube->suggestSavePath($videoInfo);
+ if (file_exists($path)) {
+ throw new Exception($path.' already exists');
+ }
+
+ return $this->_youtube->suggestSavePath($videoInfo);
+ }
+ }
+
+ //@todo format
+ protected function _download($id, $format, $save, $couch = false)
+ {
+ $videoId = Wozozo_WWW_YouTube::detectVideoId($id);
+ $this->_out("Video ID :$videoId");
+
+ $youtube = $this->_loadYoutube();
+ $youtube->setConfig(array('prefer_fmt' => $format));
+ $videoInfo = $youtube->getVideoInfo($videoId);
+ $this->_out("Status :". $videoInfo['status']);
+
+ if ($videoInfo['status'] != 'ok') {
+ $videoInfo = $videoInfo->toArray();
+ $message = '';
+ array_walk($videoInfo, function($v, $k) use (&$message){$message .= $k .' : '. $v .PHP_EOL;});
+ throw new Exception("Status is not ok ". PHP_EOL .$message);
+ }
+
+ $this->_out("Title : ". $videoInfo['title']);
+ $this->_out("Length Seconds : ". $videoInfo['length_seconds']);
+
+ $client = $youtube->getHttpClient();
+ //ensure load adapter
+ $client->setAdapter('Wozozo_WWW_YouTube_HttpSocketProgressBar');
+
+ $youtube->setHttpClient($client);
+ /*
+ if ($path) $youtube->setConfig(array('save' => $path));
+ $path = $youtube->suggestSavePath($videoInfo);
+ */
+ $path = $this->_setupSave($videoInfo, $save, $couch);
+
+ $this->_out("Downloading ..: ". $path);
+ $youtube->downloadByVideoInfo($videoInfo);
+ }
+
+ //@todo
+ //public function downloadSendQueue()
+ //{}
+
+ protected function _loadYoutube()
+ {
+ if (null === $this->_youtube) {
+ $youtube = new Wozozo_WWW_YouTube();
+ if ($config = $this->_loadConfig('youtube')) {
+ if ($config->httpClient) {
+ require_once 'Zend/Http/Client.php';
+ $client = new Zend_Http_Client(null, $config->httpClient);
+ $youtube->setHttpClient($client);
+ }
+ $youtube->setConfig($config);
+ }
+
+ $this->_youtube = $youtube;
+ }
+
+ return $this->_youtube;
+ }
+
+ protected function _loadConfig($key)
+ {
+ $userConfig = $this->_registry->getConfig();
+
+ return $userConfig->$key;
+ }
+
+ protected function _out($string)
+ {
+ $this->_registry->getResponse()->appendContent($string);
+ }
+}
+