function proxyAction() { // time to get params from get /* @var $request Zend_Controller_Request_Http */ $request = $this->getRequest(); if (!$this->plugin->config('proxy.enabled', true) && !X_VlcShares_Plugins::helpers()->devices()->isWiimc()) { throw new Exception(X_Env::_('p_animeftw_err_proxydisabled')); } // this action is so special.... no layout or viewRenderer $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout->disableLayout(); $videoUrl = $request->getParam('v', false); // video file url $refererUrl = $request->getParam('r', false); // referer page needed if ($videoUrl === false || $refererUrl === false) { // invalid request throw new Exception(X_Env::_('p_animeftw_err_invalidrequest')); return; } $videoUrl = X_Env::decode($videoUrl); $refererUrl = X_Env::decode($refererUrl); // if user abort request (vlc/wii stop playing, this process ends ignore_user_abort(false); // close and clean the output buffer, everything will be read and send to device ob_end_clean(); //$userAgent = $this->plugin->config('hide.useragent', true) ? 'User-Agent: vlc-shares/'.X_VlcShares::VERSION : 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20101019 Firefox/4.0.1'; $userAgent = 'User-Agent: vlc-shares/' . X_VlcShares::VERSION . ' animeftw/' . X_VlcShares_Plugins_AnimeFTW::VERSION; $opts = array('http' => array('header' => array("Referer: {$refererUrl}", "User-Agent: {$userAgent}"))); $context = stream_context_create($opts); // readfile open a file and send it directly to output buffer readfile($videoUrl, false, $context); }
public function gen_afterPageBuild(X_Page_ItemList_PItem $items, Zend_Controller_Action $controller) { /* if ( !$this->_forceRendering ) { // even if forced.enabled, don't build the page if the device is wiimc if ( $this->helpers()->devices()->isWiimc() || ( !((bool) $this->config('forced.enabled', false)) && !$this->helpers()->devices()->isAndroid() )) return; } */ if (!$this->isDefaultRenderer()) { return; } X_Debug::i("Plugin triggered"); $request = $controller->getRequest(); $urlHelper = $controller->getHelper('url'); /* @var $view Zend_Controller_Action_Helper_ViewRenderer */ $view = $controller->getHelper('viewRenderer'); /* @var $layout Zend_Layout_Controller_Action_Helper_Layout */ $layout = $controller->getHelper('layout'); $view->setViewSuffix('mobile.phtml'); $layout->getLayoutInstance()->setLayout('mobile', true); if ($request instanceof Zend_Controller_Request_Http) { if ($request->isXmlHttpRequest()) { $layout->getLayoutInstance()->disableLayout(); } } try { $providerObj = X_VlcShares_Plugins::broker()->getPlugins($request->getParam('p', '')); $view->view->providerName = strtolower($providerObj->getId()); if ($providerObj instanceof X_VlcShares_Plugins_ResolverDisplayableInterface) { // location in request obj are X_Env::encoded $view->view->location = $providerObj->resolveLocation(X_Env::decode($request->getParam('l', ''))); } if ($providerObj instanceof X_VlcShares_Plugins_ResolverInterface) { // location in request obj are X_Env::encoded $view->view->locationRaw = $providerObj->resolveLocation(X_Env::decode($request->getParam('l', ''))); $view->view->parentLocation = $providerObj->getParentLocation(X_Env::decode($request->getParam('l', ''))); } } catch (Exception $e) { //die('No provider'); X_Debug::i('No provider O_o'); } // set some vars for view $view->view->provider = $request->getParam('p', ''); $view->view->items = $items; $view->view->actionName = $request->getActionName(); $view->view->controllerName = $request->getControllerName(); $view->view->coverflowEnabled = $this->config('coverflow.enabled', true); }
/** * Get category/video list * @param string $provider * @param string $location * @param Zend_Controller_Action $controller * @return X_Page_ItemList_PItem */ public function getShareItems($provider, $location, Zend_Controller_Action $controller) { // this plugin add items only if it is the provider if ($provider != $this->getId()) { return; } X_Debug::i("Plugin triggered"); // disabling cache plugin try { $cachePlugin = X_VlcShares_Plugins::broker()->getPlugins('cache'); if (method_exists($cachePlugin, 'setDoNotCache')) { $cachePlugin->setDoNotCache(); } } catch (Exception $e) { // cache plugin not registered, no problem } $urlHelper = $controller->getHelper('url'); X_VlcShares_Plugins::broker()->unregisterPluginClass('X_VlcShares_Plugins_SortItems'); $items = new X_Page_ItemList_PItem(); // location format: // $catPage/X_Env::encode($category)/$itemPage/$item $locParts = $location != '' ? explode('/', $location, 4) : array(); @(list($catPage, $category, $itemPage, $item) = $locParts); $locCount = count($locParts); // category is double encoded so we need an extra decode $category = X_Env::decode($category); switch ($locCount) { case 2: $itemPage = 1; case 4: // we shouldn't be here, $locCount = 4 means that we have a // selected video in location. We should be in browse/mode // we shouldn't be here, $locCount = 4 means that we have a // selected video in location. We should be in browse/mode case 3: $this->fetchVideos($items, $catPage, $category, $itemPage); break; default: case 0: $catPage = 1; case 1: $this->fetchCategories($items, $catPage); break; } return $items; }
function proxyAction() { // time to get params from get /* @var $request Zend_Controller_Request_Http */ $request = $this->getRequest(); // this action is so special.... no layout or viewRenderer $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout->disableLayout(); $videoUrl = $request->getParam('v', false); // video file url //$refererUrl = $request->getParam('r', false); // referer page needed if ($videoUrl === false) { // invalid request throw new Exception(X_Env::_('p_spainradio_err_invalidrequest')); } $videoUrl = X_Env::decode($videoUrl); //$refererUrl = X_Env::decode($refererUrl); if (!defined("X_VlcShares_Plugins_Spainradio::C_{$videoUrl}")) { throw new Exception(X_Env::_('p_spainradio_err_invalidchannel')); } $videoUrl = constant("X_VlcShares_Plugins_Spainradio::C_{$videoUrl}"); //$userAgent = $this->plugin->config('hide.useragent', true) ? 'User-Agent: vlc-shares/'.X_VlcShares::VERSION.' spainradio/'.X_VlcShares_Plugins_Spainradio::VERSION : 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20101019 Firefox/4.0.1'; //$userAgent = 'User-Agent: vlc-shares/'.X_VlcShares::VERSION.' spainradio/'.X_VlcShares_Plugins_Spainradio::VERSION; $opts = array('http' => array('header' => array())); $context = stream_context_create($opts); /* redirect support in wiimc exists only from 1.1.0 if ( X_VlcShares_Plugins::helpers()->devices()->isWiimc() && !X_VlcShares_Plugins::helpers()->devices()->isWiimcBeforeVersion('1.0.9') && $this->plugin->config('direct.enabled', true) ) { $match = array(); $xml = file_get_contents($videoUrl, false, $context); if ( preg_match('/<REF HREF=\"([^\"]*)\"\/>/', $xml, $match ) ) { $this->_helper->redirector->gotoUrlAndExit($match[1]); } else { throw new Exception(X_Env::_('p_spainradio_err_invalidchannel')); } } else {*/ // if user abort request (vlc/wii stop playing, this process ends) ignore_user_abort(false); // close and clean the output buffer, everything will be read and send to device ob_end_clean(); // readfile open a file and send it directly to output buffer readfile($videoUrl, false, $context); //} }
function removeAction() { $hash = $this->getRequest()->getParam('csrf'); $key = X_Env::decode($this->getRequest()->getParam('key', false)); $csrf = new Zend_Form_Element_Hash('csrf', array('salt' => __CLASS__)); if (!$csrf->isValid($hash)) { $this->_helper->flashMessenger(array('type' => 'error', 'text' => X_Env::_('p_auth_err_invalidhash'))); $this->_helper->redirector('index', 'acl'); return; } $resource = new Application_Model_AclResource(); Application_Model_AclResourcesMapper::i()->find($key, $resource); if ($resource->isNew()) { $this->_helper->flashMessenger(array('type' => 'error', 'text' => X_Env::_('p_auth_acl_err_invalidkey'))); $this->_helper->redirector('index', 'acl'); return; } Application_Model_AclResourcesMapper::i()->delete($resource); $this->_helper->flashMessenger(array('type' => 'success', 'text' => X_Env::_('p_auth_acl_resourceremoved', $resource->getKey()))); $this->_helper->redirector('index', 'acl'); }
/** * Add the button BackToStream in controls page * * @param X_Streamer_Engine $engine * @param Zend_Controller_Action $controller the controller who handle the request * @return array */ public function preGetControlItems(X_Streamer_Engine $engine, Zend_Controller_Action $controller) { $urlHelper = $controller->getHelper('url'); $return = new X_Page_ItemList_PItem(); if ($this->config('show.title', true)) { $onAirName = X_Env::_("p_streaminfo_unknown_source"); if ($engine instanceof X_Streamer_Engine_Vlc) { $vlc = $engine->getVlcWrapper(); $onAirName = $vlc->getCurrentName(); } else { // try to find the name from the location (if any) $providerId = $controller->getRequest()->getParam('p', false); $location = $controller->getRequest()->getParam('l', false); if ($providerId && $location) { $providerObj = X_VlcShares_Plugins::broker()->getPlugins($providerId); $location = X_Env::decode($location); if ($providerObj instanceof X_VlcShares_Plugins_ResolverInterface) { $onAirName = $providerObj->resolveLocation($location); } } } // show the title of the file $item = new X_Page_Item_PItem('streaminfo-onair', X_Env::_('p_streaminfo_onair') . ": {$onAirName}"); $item->setType(X_Page_Item_PItem::TYPE_ELEMENT)->setLink(X_Env::completeUrl($urlHelper->url())); $return->append($item); } if ($engine instanceof X_Streamer_Engine_Vlc) { $vlc = $engine->getVlcWrapper(); if ($this->config('show.time', false)) { $currentTime = X_Env::formatTime($vlc->getCurrentTime()); $totalTime = X_Env::formatTime($vlc->getTotalTime()); $item = new X_Page_Item_PItem('streaminfo-time', "{$currentTime}/{$totalTime}"); $item->setType(X_Page_Item_PItem::TYPE_ELEMENT)->setLink(X_Env::completeUrl($urlHelper->url())); $return->append($item); } } return $return; }
/** * Show configs page */ public function indexAction() { $request = $this->getRequest(); if ($request instanceof Zend_Controller_Request_Http) { if ($request->isXmlHttpRequest()) { $this->_helper->layout->disableLayout(); } } $section = 'plugins'; $key = $this->getRequest()->getParam('key', false); if ($key === false) { $this->_helper->flashMessenger(array('type' => 'error', 'text' => X_Env::_('config_invalidkey'))); $this->_helper->redirector('index', 'manage'); } $configs = Application_Model_ConfigsMapper::i()->fetchBySectionNamespace($section, $key); $form = $this->_initConfigsForm($section, $key, $configs); //$section = $this->getRequest()->getParam('section', false); $redirect = X_Env::decode($this->getRequest()->getParam('r', '')); if ($redirect == '') { $redirect = 'manage:index'; } if (!is_null($form->getElement('redirect'))) { $form->redirect->setValue($redirect); } $defaultValues = array(); foreach ($configs as $config) { /* @var $config Application_Model_Config */ $elementName = $config->getSection() . '_' . str_replace('.', '_', $config->getKey()); $defaultValues[$elementName] = $config->getValue(); } $form->setDefaults($defaultValues); $plugins = Application_Model_PluginsMapper::i()->fetchAll(); $this->view->plugins = $plugins; $this->view->form = $form; $this->view->messages = array_merge($this->_helper->flashMessenger->getMessages(), $this->_helper->flashMessenger->getCurrentMessages()); $this->view->key = strtolower($key); }
function convertAction() { // time to get params from get /* @var $request Zend_Controller_Request_Http */ $request = $this->getRequest(); // this action is so special.... no layout or viewRenderer $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout->disableLayout(); $videoId = $request->getParam('v', false); // youtube video id $format = $request->getParam('f', false); // convert to format $lcode = $request->getParam('l', false); // language code if ($videoId === false || $format === false || !array_key_exists($format, $this->cFormats) || $lcode === false) { // invalid request echo 'Invalid Request'; return; } // $lcode need to be decoded $lcode = X_Env::decode($lcode); /* @var $helper X_VlcShares_Plugins_Helper_Youtube */ $helper = X_VlcShares_Plugins::helpers('youtube'); try { $sub = $helper->getSubtitleNOAPI($videoId, $lcode); } catch (Exception $e) { echo 'Invalid Language Code'; return; } // $sub format: /* $sub = array( 'id' => $current->getAttribute('id'), 'name' => $current->getAttribute('name'), 'lang_code' => $current->getAttribute('lang_code'), 'lang_original' => $current->getAttribute('lang_original'), 'lang_translated' => $current->getAttribute('lang_translated'), 'lang_default' => $current->getAttribute('lang_default'), 'xml_url' => 'http://video.google.com/timedtext?type=track&' .'lang='.utf8_encode($sub['lang_code']).'&' .'name='.utf8_encode($sub['name']).'&' .'v='.$this->_location; ); */ $uri = $sub['xml_url']; $http = $helper->getHttpClient($uri); $xml = $http->request(Zend_Http_Client::GET)->getBody(); $dom = new Zend_Dom_Query($xml); $method = $this->cFormats[$format]; $string = $this->{$method}($dom); echo $string; }
public function deleteAction() { $request = $this->getRequest(); $id = $request->getParam('id', null); $type = $request->getParam('type', 'video'); if (!is_null($id)) { if ($type == 'video') { $video = new Application_Model_Video(); Application_Model_VideosMapper::i()->find($id, $video); if ($video->getId()) { $category = $video->getCategory(); Application_Model_VideosMapper::i()->delete($video); $this->_helper->redirector('category', 'onlinelibrary', 'default', array('id' => X_Env::encode($category))); } } elseif ($type == 'category') { Application_Model_VideosMapper::i()->deleteCategory(X_Env::decode($id)); } } $this->_helper->redirector('index', 'onlinelibrary'); }
public function streamAction() { $request = $this->getRequest(); X_VlcShares_Plugins::broker()->gen_preProviderSelection($this); $provider = $request->getParam('p', false); if ($provider === false || !X_VlcShares_Plugins::broker()->isRegistered($provider)) { throw new Exception("Invalid provider"); } $location = X_Env::decode($request->getParam('l', '')); $providerObj = X_VlcShares_Plugins::broker()->getPlugins($provider); // if provider is a resolver, i can use new streamer api if (X_VlcShares_Plugins::helpers()->streamer()->isEnabled() && $providerObj instanceof X_VlcShares_Plugins_ResolverInterface) { $url = $providerObj->resolveLocation($location); X_Debug::i("Resolved location: {{$url}}"); // check if url is valid (resolver give null or false on error) if (!$url) { X_Debug::e("Invalid location: {$location}"); throw new Exception("Stream location is invalid: {$url}"); } $engine = X_VlcShares_Plugins::helpers()->streamer()->find($url); X_Debug::i("Streamer engine found: {{$engine->getId()}}"); // automatically set the url as source param in the engine $engine->setSource($url); // NEW APIS // each arg is stored as in a LIFO stack. If i put top priority as first, // low priority args could override it. So i use an inverse priority insertion // register low priority args X_VlcShares_Plugins::broker()->preRegisterStreamerArgs($engine, $url, $provider, $location, $this); // register normal priority args X_VlcShares_Plugins::broker()->registerStreamerArgs($engine, $url, $provider, $location, $this); // register top priority args X_VlcShares_Plugins::broker()->postRegisterStreamerArgs($engine, $url, $provider, $location, $this); X_VlcShares_Plugins::broker()->preStartStreamer($engine, $url, $provider, $location, $this); $results = X_VlcShares_Plugins::broker()->canStartStreamer($engine, $url, $provider, $location, $this); $started = false; if (is_null($results) || !in_array(false, $results)) { X_Debug::i("Starting streamer {{$engine->getId()}}: {$engine}"); $started = true; X_Streamer::i()->start($engine); } else { $pluginId = array_search(false, $results, true); X_Debug::f("Plugin {{$pluginId}} prevented streamer from starting..."); //throw new Exception("Plugin {{$pluginId}} prevented streamer from starting"); } X_VlcShares_Plugins::broker()->postStartStreamer($started, $engine, $url, $provider, $location, $this); } else { // otherwise i'm forced to fallback to old api //{{{ THIS CODE BLOCK WILL IS DEPRECATED AND WILL BE REMOVED IN 0.5.6 or 0.6 //TODO remove in 0.5.6 or 0.6 // each arg is stored as in a LIFO stack. If i put top priority as first, // low priority args could override it. So i use an inverse priority insertion // register low priority args X_VlcShares_Plugins::broker()->preRegisterVlcArgs($this->vlc, $provider, $location, $this); // register normal priority args X_VlcShares_Plugins::broker()->registerVlcArgs($this->vlc, $provider, $location, $this); // register top priority args X_VlcShares_Plugins::broker()->postRegisterVlcArgs($this->vlc, $provider, $location, $this); X_VlcShares_Plugins::broker()->preSpawnVlc($this->vlc, $provider, $location, $this); $this->vlc->spawn(); X_VlcShares_Plugins::broker()->postSpawnVlc($this->vlc, $provider, $location, $this); try { $engine = X_VlcShares_Plugins::helpers()->streamer()->get('vlc'); } catch (Exception $e) { X_Debug::w('No vlc streamer available'); $engine = new X_Streamer_Engine_Vlc($this->vlc); } $url = $this->vlc->getArg('source'); //}}} } $pageItems = new X_Page_ItemList_PItem(); // i can't add here the go to play button // because i don't know the output type // i need to leave this to the plugins, too // i hope that an output manager plugin // will be always enabled // top links $pageItems->merge(X_VlcShares_Plugins::broker()->preGetStreamItems($engine, $url, $provider, $location, $this)); // normal links $pageItems->merge(X_VlcShares_Plugins::broker()->getStreamItems($engine, $url, $provider, $location, $this)); // bottom links $pageItems->merge(X_VlcShares_Plugins::broker()->postGetStreamItems($engine, $url, $provider, $location, $this)); // trigger for page creation X_VlcShares_Plugins::broker()->gen_afterPageBuild($pageItems, $this); }
private function _getParent(Zend_Controller_Request_Http $request) { $controller = $request->getControllerName(); $action = $request->getActionName(); if ($controller == 'index' && $action == 'collections') { // we don't need to know anything: we are in the root return '0'; } if ($controller == 'browse') { // we are in mode selection // parent is the same, but action = share if ($action == 'mode') { // rebuild the query, keep only location and provider $parent = array('controller' => 'browse', 'action' => 'share', 'p' => $request->getParam('p'), 'l' => $request->getParam('l')); return X_Env::encode(http_build_query($parent)); //$request->getParams(); } // if ($action == 'share') { // we need the providerObj to know the parent :( $location = $request->getParam('l', false); if ($location === false) { // NICE, parent is the ROOT return '0'; } $providerId = $request->getParam('p'); $providerObj = X_VlcShares_Plugins::broker()->getPlugins($providerId); if ($providerObj instanceof X_VlcShares_Plugins_ResolverInterface) { // easy: provider will give us the parent $location = X_Env::decode($location); return X_Env::encode($providerObj->getParentLocation($location)); } // so providerObj is not Resolver.... f**k // rude way? return '0'; } if ($action == 'selection') { // same as 'controls' Q_Q return '0'; } } if ($controller == 'controls') { // f**k: how can i manage this? return '0'; } $data = array('controller' => $controller, 'action' => $action); $data = array_merge($data, $request->getParams()); return X_Env::encode(http_build_query($data)); }
/** * This hook can be used to add low priority args in vlc stack * * @param X_Vlc $vlc vlc wrapper object * @param string $provider id of the plugin that should handle request * @param string $location to stream * @param Zend_Controller_Action $controller the controller who handle the request */ public function preRegisterVlcArgs(X_Vlc $vlc, $provider, $location, Zend_Controller_Action $controller) { // this plugin inject params only if this is the provider if ($provider != $this->getId()) { return; } // i need to register source as first, because subtitles plugin use source // for create subfile X_Debug::i('Plugin triggered'); $dLocation = $this->resolveLocation($location); if ($location !== null) { // TODO adapt to newer api when ready $vlc->registerArg('source', "\"{$dLocation}\""); } else { X_Debug::e("No source o_O"); return; } // Now, it's time to check for sub parameter $request = $controller->getRequest(); $sub = $request->getParam($this->getId() . ':sub', false); if ($sub !== false) { $sub = X_Env::decode($sub); /* @var $helper X_VlcShares_Plugins_Helper_Youtube */ $helper = $this->helpers('youtube'); list(, , , $videoId) = explode('/', $location); $sub = $helper->getSubtitleNOAPI($videoId, $sub); $urlHelper = $controller->getHelper('url'); $subFile = X_Env::completeUrl($urlHelper->url($sub['srt_url'], 'default', true)); $vlc->registerArg('subtitles', "--sub-file=\"{$subFile}\""); } }
public function browseAction() { /* @var $request Zend_Controller_Request_Http */ $request = $this->getRequest(); $path = X_Env::decode($request->getParam('p', '')); $filter = $request->getParam('f', 'file'); $callback = $request->getParam('c', 'void'); $return = array(); // i can't browse inside a file :) if (!is_dir($path)) { $path = dirname($path); } $path = realpath($path); if (is_dir($path) && is_readable($path)) { $objects = scandir($path); foreach ($objects as $object) { if ($object != ".") { if (@filetype($path . "/" . $object) == "dir" && is_readable($path . "/" . $object)) { $return[] = array('type' => 'folder', 'path' => $path . "/" . $object . '/', 'label' => $object . '/', 'href' => $this->_helper->url('browse', 'configs', 'default', array('f' => $filter, 'p' => X_Env::encode($path . "/" . $object), 'c' => $callback))); } elseif ($filter == 'file') { //$array["/".$dir."/".$object] = md5_file($dir."/".$object); $return[] = array('type' => 'file', 'path' => realpath($path . "/" . $object), 'label' => $object, 'c' => $callback); } } } reset($objects); } usort($return, array(__CLASS__, 'sortFolderBased')); $return = array('path' => $path, 'filter' => $filter, 'items' => $return); if ($request->isXmlHttpRequest()) { $this->_helper->json($return); } else { $this->_helper->layout()->disableLayout(); $this->view->callback = $callback; $this->view->path = $return['path']; $this->view->filter = $return['filter']; $this->view->items = $return['items']; } }
/** * This hook can be used to add normal priority args in vlc stack * * @param X_Vlc $vlc vlc wrapper object * @param string $provider id of the plugin that should handle request * @param string $location to stream * @param Zend_Controller_Action $controller the controller who handle the request */ public function registerVlcArgs(X_Vlc $vlc, $provider, $location, Zend_Controller_Action $controller) { X_Debug::i('Plugin triggered'); $subParam = $controller->getRequest()->getParam($this->getId(), false); if ($subParam !== false) { $subParam = X_Env::decode($subParam); list($type, $sub) = explode(':', $subParam, 2); if ($type == self::FILE) { $source = trim($vlc->getArg('source'), '"'); $filename = pathinfo($source, PATHINFO_FILENAME); // only the name of file, without ext $dirname = pathinfo($source, PATHINFO_DIRNAME); $subFile = $dirname . '/' . $filename . '.' . ltrim($sub, '.'); $subFile = realpath($subFile); X_Debug::i("Alternative audio file selected: {$subFile}"); $vlc->registerArg('audio', "--input-slave=\"{$subFile}\""); } elseif ($type == self::STREAM) { $sub = (int) $sub; X_Debug::i("Alternative audio track selected: {$sub}"); $vlc->registerArg('audio', "--audio-track=\"{$sub}\""); } } }
function thumbAction() { // time to get params from get /* @var $request Zend_Controller_Request_Http */ $request = $this->getRequest(); if (!is_writable(APPLICATION_PATH . "/../public/images/fsthumbs/thumbs/")) { throw new Exception('"/public/images/fsthumbs/thumbs/" must be writable'); } $l = $request->getParam('l', false); if ($l == false) { throw new Exception(X_Env::_('p_fsthumbs_invalidlocation')); } $ldec = X_Env::decode($l); $itemRealPath = $this->fsPlugin->resolveLocation($ldec); if ($itemRealPath == false) { throw new Exception(X_Env::_('p_fsthumbs_invalidlocation')); } // cache check and redirect if possible $imagePath = "/images/fsthumbs/thumbs/{$l}.jpg"; // else thumb creation and then redirect if (!file_exists(APPLICATION_PATH . "/../public{$imagePath}")) { if (X_VlcShares_Plugins::helpers()->ffmpeg()->isEnabled()) { // create the thumb $ffmpegPath = $this->options->helpers->ffmpeg->path; $destPath = APPLICATION_PATH . "/../public{$imagePath}"; $secOffset = intval($this->plugin->config('capture.seconds', '2')) + (int) rand(0, 10) - 5; if ($secOffset < 1) { $secOffset = 1; } $imageDim = $this->plugin->config('thumbs.size', '320x240'); if (!preg_match('/(\\d{3})x(\\d{3})/', $imageDim)) { X_Debug::e("Thumb size is not a valid value (IIIxIII): {$imageDim}"); $imageDim = '320x240'; } // thumb creation should be always completed ignore_user_abort(true); // semaphore is needed for folders with lots files and low-end cpus $lockFile = fopen(__FILE__, 'r+'); flock($lockFile, LOCK_EX); $exec = "{$ffmpegPath} -itsoffset -{$secOffset} -i \"{$itemRealPath}\" -vcodec mjpeg -vframes 1 -an -f rawvideo -s {$imageDim} \"{$destPath}\""; $return = X_Env::execute($exec); // remove lock flock($lockFile, LOCK_UN); fclose($lockFile); $filesize = @filesize($destPath); if ($filesize == 0) { // it's better to replace the thumbs created with // a placeholder file to prevent a new creation @copy(APPLICATION_PATH . "/../public/images/fsthumbs/nothumbs.jpg", $destPath); clearstatcache(true, $destPath); $filesize = @filesize($destPath); } $thumb = new Application_Model_FsThumb(); // try to load an old entry in db, this prevent error when files are removed but not the reference in db Application_Model_FsThumbsMapper::i()->fetchByPath($itemRealPath, $thumb); $thumb->setCreated(time())->setPath($itemRealPath)->setUrl($imagePath)->setSize(@filesize($destPath)); try { Application_Model_FsThumbsMapper::i()->save($thumb); X_Debug::i('Thumb stored'); } catch (Exception $e) { X_Debug::e("Error while storing thumb data: {$e->getMessage()}"); } //X_Debug::i(var_export($return, true)); // -itsoffset -30 -i test.avi -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320x240 test.jpg } else { $imagePath = "/images/fsthumbs/nothumbs.jpg"; } } // if it is wiimc i have to return here the image directly, not a redirect if (X_VlcShares_Plugins::helpers()->devices()->isWiimc()) { $this->getResponse()->clearAllHeaders(); ob_end_clean(); $this->getResponse()->setHeader('Content-Type', 'image/jpeg')->setHeader('Content-Length', @filesize(APPLICATION_PATH . "/../public{$imagePath}")); $this->getResponse()->sendHeaders(); readfile(APPLICATION_PATH . "/../public{$imagePath}"); } else { $this->_helper->redirector->gotoUrlAndExit($imagePath, array('prependBase' => true, 'code' => 302)); } }