开发者

How can I find download links for vimeo videos?

I saw that today vimeo changed the way they are streaming the videos and I can't stream their videos anymore. I saw that when I generate the link to the video, which was for example:

http://vimeo.com/moogaloop/play/clip:6649390/1eab2a25f30f1aadaf5e306d0f40fd6c/1292498602/?q=hd

It's redirecting me to a page saying "Permission denied". I tried using curl, but without any success. I sniffed the traffic and I saw that it's streaming from something like:

http://av.vimeo.com/02047/623/34209065.mp4?token=1292496582_34de09a6d13212cf26af08357d311c30

Does anybody know how to get the working URL to the video file?

The way I'm getting the videos at the moment is:

  1. Choose link http://vimeo.com/video_id.
  2. Get only the video_id.
  3. Get the XML for the video http://vimeo.com/moogaloop/开发者_运维问答load/clip:video_id;.
  4. parse the XML and find the necessary information:

    • request_signature
    • request_signature_expires
    • isHD
  5. Generate the link:

    $video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
    

If I do this manually through the browser it works, but if I do it through the script it doesn't.


After spending a few hours on finding out how I can get the direct link to vimeo I found a good solution. So here are the steps for the users who want to download and stream video src directly from vimeo. Keep in mind that they block all IP addresses and probably hosts which are downloading the videos in this way, so I just stopped using their services and I will never use them again :).

Steps to get the video sources:

  1. choose link http://vimeo.com/video_id
  2. get only the video_id
  3. get the xml for the video http://vimeo.com/moogaloop/load/clip:video_id;
  4. parse the xml and I find the necessary information I need:

    • request_signature
    • request_signature_expires
    • isHD
  5. Then I generate the link:

    $video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
    
  6. Then if you are php dev, you call wget command through exec in this way

    exec("wget -b '$video_link' -a 'wget.log' -O -");

  7. Then you read the log and find out the link you are looking for. You can simply parse the log file. The direct link is between "Location: " and "[following]"

  8. You return the direct link and clean the log file :)

NOTE: keep in mind again that this won't work forever. Sooner or later they will block your ip :).


This javascript works for me.

var player = document.getElementsByClassName("player")[0].getAttribute("id");
player = eval(player.replace("player_", "clip"));
var time = player.config.request.timestamp;
var sig = player.config.request.signature;
var clip_id = window.location.href.substring(17);

var url = "http://player.vimeo.com/play_redirect" +
  "?clip_id=" + clip_id +
  "&sig=" + sig +
  "&time=" + time;

var v = document.getElementById("menu");
v.style.fontSize = "4em";
v.style.lineHeight = "1em";

v.innerHTML =
  "<a href='" + url + "'>SD</a>, " +
  "<a href='" + url + "&quality=hd'>HD</a>";

source


Warning The methods described above are not supported by Vimeo. There is no assurance they work right now, or will continue working in the future. They can (and likely will) break at any moment, without any prior notice.

The only officially supported method of accessing video file URLs is through the API.

If you are trying to access the URLs of videos you own, you must have a PRO account.

If you are trying to access the URLs of videos you don't own, you should embed the video, or open it with the Vimeo iOS app.


The answers for this on SuperUser were out of date so I thought I would post it here (not enough reputation to post there)

So I just recorded XHR requests with Chrome devtools and the first request was for the the json file containing the link to the akamai CDN hosted video along with the token akamai provides. This token is important. It is hash that includes a timestamp so the links for the videos here will need to be downloaded somewhat quickly or requests will be refused.

The format for this JSON file was in the form:

https://player.vimeo.com/video/VIDEO_ID/config?byline=0&collections=1&context=Vimeo%5CController%5CClipController.main&default_to_hd=1&outro=nothing&portrait=0&share=1&title=0&watch_trailer=0&s=6cffff97fffffffffff4ffffffff679ec66ffff_14ffffffff

And then I just looked for the highest quality object in the JSON (1080p) and download that file. In the format:

https://fpdl.vimeocdn.com/vimeo-prod-skyfire-std-us/01/XXXXX/8/XXXX/XXXXXXXX.mp4?token=XXXXXXX-0xXXXXXXXXXXXXX

Note the Xs are numbers I replaced for privacy.


FYI, the above example won't work, but it's close. You need to send fake cookies. So basically when you visit the page with the XML, you need to grab the cookies, and then send those cookies you previously received while visiting the final video url. So here's how you do it in PHP (using Yii) with curl:

public function actionVimeo($video_id)
    { 
        $xml_url = "http://vimeo.com/moogaloop/load/clip:$video_id";

        $ch = curl_init($xml_url);           
        $cookieFile = Yii::app()->basePath . '/runtime/vimeocookie'. time().'.txt'; //replace this line with code to generate a writeable path in your application
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); //the cookie file will be populated with cookies received while viewing the xml page   
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //you need to send a user agent here and it must be the same below when you visit the video url
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $output = curl_exec($ch);
        curl_close($ch);


        $xml = simplexml_load_string($output);
        $request_signature = $xml->request_signature;
        $request_signature_expires = $xml->request_signature_expires;
        $vid_url = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=sd";

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$vid_url);         
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);  //same user agent as on previous vimeo page you visited       
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); //the cookies in that cookie file will be used while visiting the video URL         
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); //vimeo changes the header location, so you gotta follow it
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $video = curl_exec($ch);
        curl_close($ch);

        unlink($cookieFile); //remove the temporary cookie file

        $savePath = Yii::app()->basePath . '/runtime/testvim.mp4'; //change this to a path your application can write the final video to
        file_put_contents($savePath, $video);

        exit;
    }


A quick and dirty approach would be:

$base = 'http://player.vimeo.com/play_redirect';

$curl = curl_init(sprintf('http://player.vimeo.com/video/%s', $_GET['id']));
curl_setopt_array($curl, array(
    CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
    CURLOPT_RETURNTRANSFER => true
));

preg_match('/g:(\{.*?\}),a/s', curl_exec($curl), $match);
curl_close($curl);

$json = json_decode($match[1])->request;
$url = sprintf('%s?quality=sd&clip_id=%s&time=%d&sig=%s',
    $base,
    $_GET['id'],
    $json->timestamp,
    $json->signature
);

$curl = curl_init($url);
curl_setopt_array($curl, array(
    CURLOPT_HEADER => true,
    CURLOPT_NOBODY => true,
    CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
    CURLOPT_RETURNTRANSFER => true
));

$headers = explode("\r\n", curl_exec($curl));
curl_close($curl);

foreach ($headers as $header) {
    if ($header) {
        header($header);
    }
}


No need for any scripts, let alone PHP.

I wanted to download protected video (embedded on specific website), that even on vimeo.com cannot be played due to "Privacy settings".

Simply fire-up Developer tools (Opera Dragonfly, Chrome Developer tools, whatever), choose Network and there you go:

http://pdl.vimeocdn.com/23062/181/302074466.mp4?token2=1424299768_bbeb6039c037cd429cd560d668ec851e&aksessionid=1f4d289cd1a3abe1
Method: Get
Status text: 206 Partial content
Type: video/mp4

Just copy that first URL and download with some tool (I used "wget").
Saved.


The extension Vimeo video downloader (now moved to Simple Vimeo Downloader) for browser is helpful to do this.

After installed the extension in Chrome or Edge browser, then click the Download button in the page. Finally you can download the video of the required quality.

This extension can also help you download private vimeo video which need input password, certainly you need know the password. No crack here.

How can I find download links for vimeo videos?


The algorithm looks like this:

  • Input data: vimeoUrl.
  • content = getRemoteContent(vimeoUrl).
  • Parse content to find and extract the value from data-config-url attribute.
  • Navigate to data-config-url and load the content as JSON Object: $video = json_decode($this->getRemoteContent($video->getAttribute('data-config-url')));
  • Return $video->request->files->h264->sd->url — this will return a direct link for SD quality video.

Here is my simple class, that working for this moment:

class VideoController
{

    /**
     * @var array Vimeo video quality priority
     */
    public $vimeoQualityPrioritet = array('sd', 'hd', 'mobile');

    /**
     * @var string Vimeo video codec priority
     */
    public $vimeoVideoCodec = 'h264';

    /**
     * Get direct URL to Vimeo video file
     * 
     * @param string $url to video on Vimeo
     * @return string file URL
     */
    public function getVimeoDirectUrl($url)
    {
        $result = '';
        $videoInfo = $this->getVimeoVideoInfo($url);
        if ($videoInfo && $videoObject = $this->getVimeoQualityVideo($videoInfo->request->files))
        {
            $result = $videoObject->url;
        }
        return $result;
    }

    /**
     * Get Vimeo video info
     * 
     * @param string $url to video on Vimeo
     * @return \stdClass|null result
     */
    public function getVimeoVideoInfo($url)
    {
        $videoInfo = null;
        $page = $this->getRemoteContent($url);
        $dom = new \DOMDocument("1.0", "utf-8");
        libxml_use_internal_errors(true);
        $dom->loadHTML('<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $page);
        $xPath = new \DOMXpath($dom);
        $video = $xPath->query('//div[@data-config-url]');
        if ($video)
        {
            $videoObj = json_decode($this->getRemoteContent($video->item(0)->getAttribute('data-config-url')));
            if (!property_exists($videoObj, 'message'))
            {
                $videoInfo = $videoObj;
            }
        }
        return $videoInfo;
    }

    /**
     * Get vimeo video object
     * 
     * @param stdClass $files object of Vimeo files
     * @return stdClass Video file object
     */
    public function getVimeoQualityVideo($files)
    {
        $video = null;
        if (!property_exists($files, $this->vimeoVideoCodec) && count($files->codecs))
        {
            $this->vimeoVideoCodec = array_shift($files->codecs);
        }
        $codecFiles = $files->{$this->vimeoVideoCodec};
        foreach ($this->vimeoQualityPrioritet as $quality)
        {
            if (property_exists($codecFiles, $quality))
            {
                $video = $codecFiles->{$quality};
                break;
            }
        }
        if (!$video)
        {
            foreach (get_object_vars($codecFiles) as $file)
            {
                $video = $file;
                break;
            }
        }
        return $video;
    }

    /**
     * Get remote content by URL
     * 
     * @param string $url remote page URL
     * @return string result content
     */
    public function getRemoteContent($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
        curl_setopt($ch, CURLOPT_USERAGENT, 'spider');
        $content = curl_exec($ch);

        curl_close($ch);

        return $content;
    }

}

Using:

$video = new VideoController;
var_dump($video->getVimeoDirectUrl('http://vimeo.com/90747156'));


For Python, to get direct(.mp4) URL for video, you could use vimeo-downloader package

from vimeo_downloader import Vimeo
url = 'https://vimeo.com/video_id'
v = Vimeo(url)

best_stream = v.streams[-1] # Select best video quality
print(best_stream.direct_url) 
# https://vod-progressive.akamaized.net.../2298326263.mp4

First you need to install it with:

pip install vimeo-downloader
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜