/**
  * This hook can be used check vlc status just before
  * spawn is called
  * 
  * @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 preSpawnVlc(X_Vlc $vlc, $provider, $location, Zend_Controller_Action $controller)
 {
     // TODO port to newer api when ready
     // when newer X_Vlc's api will be ready
     // i will need change this to
     // $source = $vlc->getSource();
     // and double quote removal will be automatic
     $source = $vlc->getArg('source');
     $provider = X_VlcShares_Plugins::broker()->getPlugins($provider);
     //if ( X_Env::isWindows() && !X_Env::startWith($source, 'http://') && !X_Env::startWith($source, 'https://') ) {
     if (X_Env::isWindows() && is_a($provider, 'X_VlcShares_Plugins_FileSystem')) {
         // with newer api this will be useless
         $source = realpath(trim($source, '"'));
         // when newer X_Vlc's api will be ready
         // i will need change this to
         // $vlc->setSource($source);
         // and double quotation will be automatic
         $vlc->registerArg('source', "\"{$source}\"");
     }
 }
 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);
 }
 /**
  * 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}\"");
         }
     }
 }