# watching  video on www.funvid.eu



## darkshadow (Dec 15, 2010)

I write this small script to download video from http://www.funvid.eu/ .

I hope you will enjoy it ,t he script is in alpha stage and I will update it with other site in the future , any  patches and changes are welcomed .


```
#!/usr/bin/env php
<?php
/**
 *Copyright (c) 2010,Darkshadow
 *All rights reserved.
 *
 *Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 *    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *    * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
 *LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 *GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 *STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 */
define('_VID_URL' , 'http://www.funvid.eu/index.php?handler=videos&action=show&vid_id={vid_id}&pla_id=1&ext=1&rand={rand}');
function usage()
{
    fwrite(STDOUT , "command -uvideourl [-tsaveto] \n");
}
$list =  getopt("u:t:");
if(!isset($list['u'])  || strpos($list['u'] , 'http://') === false )
{
    do
    {
        fwrite(STDOUT , "please enter link name? \n"  );
        $list['u'] = trim(fgets(STDIN));  
    }
    while(strpos($list['u'] , 'http://') === false);
}
$toFile = time();
if(isset($list['t']) && trim($list['t']) != "")
{
    $toFile = trim($list['t']) ;
}
$videoDownloader = new VideoDownloader($list['u'] , _VID_URL); 
fwrite(STDOUT , sprintf("getting the video file for %s \n" ,  $list['u'])); 
$videoDownloader->downloadXml("flv" , $toFile );
fwrite(STDOUT , sprintf("finish downloading file  %s \n" ,$videoDownloader->To() )); 
fwrite(STDOUT ,"press any key to continue\n"); 
fgets(STDIN);
class VideoDownloader
{
    private $url = "";
    private $vidUrl = "";
    private $fileSize;
    private $to;
    const chunkSize = 2048;
    public function __construct( $url , $vidUrl )
    {
        $this->url    = $url;
        $this->vidUrl = $vidUrl;
    }
    public  function remoteFileSize($url, $unit = null )
    {
       $parsed = parse_url($url);
       $host = $parsed["host"];
       $fp = @fsockopen($host, 80, $errno, $errstr, 20);
       if(!$fp) return false;
       else {
           @fputs($fp, "HEAD $url HTTP/1.1\r\n");
           @fputs($fp, "HOST: $host\r\n");
           @fputs($fp, "Connection: close\r\n\r\n");
           $headers = "";
           while(!@feof($fp))$headers .= @fgets ($fp, 128);
       }
       @fclose ($fp);
       $return = false;
       $arr_headers = explode("\n", $headers);
       foreach($arr_headers as $header) {
                // follow redirect
                $s = 'Location: ';
                if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
                    $url = trim(substr($header, strlen($s)));
                    return $this->remoteFileSize($url, $readable);
                }
                
                // parse for content length
           $s = "Content-Length: ";
           if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
               $return = trim(substr($header, strlen($s)));
               break;
           }
       }
       if($return && isset($unit)) 
       {
           $size = round($return / 1024, 2);
           $sz = "KB"; // Size In KB
           $return = "$size $sz";
           if($unit == "MB")
           {
                $size = round($size / 1024, 2);
                $sz = "MB"; // Size in MB
                $return = "$size $sz";
           }
       }
       return $return;
    }
    public function To( $to = null )
    {
        if(isset($to))
        {
            $this->to = $to;
        }
        else
        {
           return  $this->to;
        }
    } 
    public function downloadXml($nodeName , $saveTo )
    {
        if(!isset($nodeName) || $nodeName == "")
        {
            throw(new Exception("please provid the node name"));
        }
        
        $vidUrl = $this->vidUrl;  
        $url    = $this->getComp($this->url);
        $match  = preg_match( "/{([^}]+)}/" , $this->vidUrl  , $list );
        array_shift($list);
        foreach($list  as $item)
        {
           $vidUrl =  str_replace("{" . $item . "}" ,  $url[$item] ,    $vidUrl);
        }
        foreach(array("rand" => rand()) as $key=>$value)
        {
            $vidUrl =  str_replace("{". $key . "}" ,  $value  ,    $vidUrl);
        }
        $xml        = file_get_contents($vidUrl);
        $sXml       = new SimpleXmlElement($xml);
        $from       = fopen($sXml->$nodeName    , "r"); 
        if(strpos($saveTo , ".") === false)
        {
            $f = basename($sXml->$nodeName);
            $l = explode(".", $f);
            if(count($l) == 2)
            {
                $saveTo = $saveTo . "." .  $l[1];
            }
        }
        $this->To($saveTo);
        $to         = fopen($saveTo , "w"); 
        if(!$from)
        {
            throw new Exception("can open file for writing.");
            return false;
        }
        else if(!$to)
        {
            throw new Exception("can open file for reading.");
            return false;
        }
        $this->fileSize = $this->remoteFileSize($sXml->$nodeName) / (1024 * 1024);
        $prog           = new ProgressPar($this->fileSize  , 50);
        fwrite(STDOUT , " total size  " .  round($this->fileSize , 2) .  " M \n"  );
        fwrite(STDOUT , " progress :- "  );
        while(($data = fread($from , self::chunkSize )))
        {
            $prog->updateProgress((self::chunkSize / (1024 * 1024)));
            fwrite($to , $data);
        }
        fwrite(STDOUT , "\n");
        return true;
    }
    public function getComp($url)
    {
        $queryString = array();
        foreach(explode('&', parse_url($url, PHP_URL_QUERY )) as $item)
        {
            $f =   explode('=' , $item); 
            if(count($f) == 2)
            {
                $queryString[$f[0]] = $f[1];
            }
        }
        return $queryString;
    }
}
class ProgressPar
{
    private $unit;
    private $totalSize;
    private $accomplish;
    private $printedUnit = 0 ;
    public function __construct($totalSize , $unit = 10)
    {
        if(!isset($totalSize) || floatval($totalSize) == 0)
        {
            throw new Exception("you should provide total size");
        }
        $this->totalSize = (float) $totalSize ; 
        $this->unit      = (int)   $unit ; 
    }
    public function addAccomplish($accomplish)
    {
         $this->Accomplish($this->accomplish +   $accomplish);
    }
    public function Accomplish($accomplish = null)
    {
        if(isset($accomplish))
        {
            if($accomplish > $this->totalSize)
            {
                $this->accomplish = $this->totalSize;
            }
            else
            {
                $this->accomplish = $accomplish;
            }
        }
        else
        {
            return $this->accomplish;
        }
    }
    public function updateProgress($newSize)
    {
        $this->addAccomplish($newSize);
        $this->virtulize();
    }
    public function virtulize()
    {
             $perUnitSize       = $this->totalSize / $this->unit;
             $accomplishedUnit  = $this->Accomplish() / $perUnitSize; 
             if(($accomplishedUnit - $this->printedUnit) > 1)
             {
                fwrite(STDOUT ,  str_repeat("#" , $accomplishedUnit - $this->printedUnit));
                fflush(STDOUT);
                $this->printedUnit = $accomplishedUnit ;
                return true;
             }
             return false;
    }
}
```

*Note : this script require php5> to run.


----------



## darkshadow (Dec 15, 2010)

*hi*

if you want a video site to be supported just write to this post your suggested video website , I will consider adding them to the script .


----------



## sk8harddiefast (Dec 19, 2010)

Sound's very good   You can also add support for vimeo


----------



## FRANCOIS (Jan 13, 2011)

Youtube and Dailymotion would be great, and all the pron sites out there(just kidding  )


----------



## darkshadow (Jan 28, 2011)

*sorry for being a way for long time guys*

I just move the project to c language , I hope u will like it .

I added support for config file , this should be easily changed in future from ordinary user to support many other site , I will try to find pattern between video files add many site as possible (currently only funvid.eu is supported) .

Remember guys the project still in alpha stage , and there will be new changes soon.

To compile take a look at https://sourceforge.net/projects/mutent/forums/forum/1329711/topic/4076110 ( tested only on openbsd )

the Program depend on libcurl libxml and libyaml plus cmake program please make sure that they are installed

I will accept any patches or request .

Project link is https://sourceforge.net/projects/mutent/

the new release will include :

1- convert to other file format 
2- add more site include veno
3- compile on other platform


----------

