【问题标题】:How can I find download links for vimeo videos?如何找到 vimeo 视频的下载链接?
【发布时间】:2010-12-16 11:42:08
【问题描述】:

我看到今天 vimeo 改变了他们流式传输视频的方式,我不能再流式传输他们的视频了。当我生成视频的链接时,我看到了,例如:

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

它将我重定向到一个显示“权限被拒绝”的页面。我尝试使用 curl,但没有任何成功。我嗅探了流量,发现流量来自以下内容:

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

有人知道如何获取视频文件的有效 URL 吗?

我目前获取视频的方式是:

  1. 选择链接http://vimeo.com/video_id。
  2. 只获取video_id。
  3. 获取视频 http://vimeo.com/moogaloop/load/clip:video_id; 的 XML。
  4. 解析 XML 并找到必要的信息:

    • request_signature
    • request_signature_expires
    • 是高清
  5. 生成链接:

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

如果我通过浏览器手动执行此操作,它可以工作,但如果我通过脚本执行此操作,则不会。

【问题讨论】:

  • moogalooop 链接现在无法使用。
  • 此方法不受 Vimeo 官方支持,随时可能中断而不会发出警告。唯一官方支持的以编程方式访问视频文件的方法是通过API

标签: php video download vimeo


【解决方案1】:

浏览器的扩展名Vimeo video downloader(现在移至Simple Vimeo Downloader)有助于做到这一点。

在 Chrome 或 Edge 浏览器中安装扩展程序后,点击页面中的Download 按钮。最后,您可以下载所需质量的视频。

这个扩展还可以帮助你下载需要输入密码的私人vimeo视频,当然你需要知道密码。这里没有破解。

【讨论】:

    【解决方案2】:

    SuperUser 上的答案已经过时,所以我想我会在这里发布(没有足够的声誉在那里发布)

    所以我刚刚使用 Chrome devtools 记录了 XHR 请求,第一个请求是 json 文件,其中包含指向 akamai CDN 托管视频的链接以及 akamai 提供的令牌。这个令牌很重要。它是包含时间戳的哈希,因此需要快速下载此处视频的链接,否则请求将被拒绝。

    此 JSON 文件的格式为:

    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
    

    然后我只是在 JSON (1080p) 中寻找最高质量的对象并下载该文件。格式:

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

    请注意,X 是我为保护隐私而替换的数字。

    【讨论】:

      【解决方案3】:

      一种快速而肮脏的方法是:

      $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);
          }
      }
      

      【讨论】:

        【解决方案4】:

        花了几个小时找出如何获得 vimeo 的直接链接后,我找到了一个很好的解决方案。因此,这里是想要直接从 vimeo 下载和流式传输视频 src 的用户的步骤。请记住,他们会阻止所有 IP 地址以及可能以这种方式下载视频的主机,所以我刚刚停止使用他们的服务,我再也不会使用它们了 :)。

        获取视频源的步骤:

        1. 选择链接http://vimeo.com/video_id
        2. 只获取video_id
        3. 获取视频http://vimeo.com/moogaloop/load/clip:video_id;的xml
        4. 解析 xml 并找到我需要的必要信息:

          • request_signature
          • request_signature_expires
          • isHD
        5. 然后我生成链接:

          $video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
          
        6. 那么如果你是php dev,你就这样通过exec调用wget命令

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

        7. 然后您阅读日志并找出您正在寻找的链接。您可以简单地解析日志文件。直接链接在“Location:”和“[following]”之间

        8. 您返回直接链接并清理日志文件:)

        注意:请再次记住,这不会永远有效。他们迟早会阻止你的 ip :)。

        【讨论】:

        • 链接:$video_link = "vimeo.com/moogaloop/play/clip:".$video_id."/…."" 现在不能使用
        • 现在您可以使用http://vimeo.com/api/v2/video/{video_id}.xml 获取基本信息,但它不包含 request_signature 或 request_signature_expires
        【解决方案5】:

        这个 javascript 适合我。

        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

        【讨论】:

          【解决方案6】:

          警告 Vimeo 不支持上述方法。无法保证它们现在可以工作,或者将来会继续工作。它们可以(并且很可能会)随时中断,无需事先通知。

          唯一官方支持的访问视频文件 URL 的方法是通过 API。

          如果您尝试访问您拥有的视频的 URL,您必须拥有 PRO 帐户。

          如果您尝试访问不属于您的视频的网址,您应该embed the video 或open it with the Vimeo iOS app。

          【讨论】:

          • 举个例子,专业会员如何通过 API 获得可流式传输的文件链接。根据 API 参考,根本不可能。
          【解决方案7】:

          仅供参考,上面的例子不起作用,但它很接近。您需要发送假 cookie。所以基本上当您访问带有 XML 的页面时,您需要获取 cookie,然后发送您之前在访问最终视频 url 时收到的那些 cookie。下面是你在 PHP 中使用 curl 的方法(使用 Yii):

          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;
              }
          

          【讨论】:

            【解决方案8】:

            不需要任何脚本,更不用说 PHP。

            我想下载受保护的视频(嵌入特定网站),由于“隐私设置”,即使在 vimeo.com 上也无法播放。

            只需启动开发者工具(Opera Dragonfly、Chrome 开发者工具等),选择 Network 即可:

            http://pdl.vimeocdn.com/23062/181/302074466.mp4?token2=1424299768_bbeb6039c037cd429cd560d668ec851e&aksessionid=1f4d289cd1a3abe1
            方法:获取
            状态文本:206 部分内容
            类型:视频/mp4

            只需复制第一个 URL 并使用一些工具下载(我使用了“wget”)。
            已保存。

            【讨论】:

            • 在开发者工具中打开网络面板后可能需要点击“播放”。
            【解决方案9】:

            算法如下:

            • 输入数据:vimeoUrl。
            • content = getRemoteContent(vimeoUrl)。
            • 解析内容以从 data-config-url 中查找和提取值 属性。
            • 导航到 data-config-url 并将内容加载为 JSON 对象: $video = json_decode($this->getRemoteContent($video->getAttribute('data-config-url')));
            • 返回 $video->request->files->h264->sd->url — 这将返回一个 标清质量视频的直接链接。

            这是我的简单课程,目前正在工作:

            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;
                }
            
            }
            

            使用:

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

            【讨论】:

              【解决方案10】:

              对于 Python,要获取视频的直接 (.mp4) URL,您可以使用 vimeo-downloader 包

              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
              

              首先你需要安装它:

              pip install vimeo-downloader
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-01-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-09-30
                • 2014-10-10
                • 2013-03-17
                相关资源
                最近更新 更多