今日、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を取得する方法を知っていますか?
現在ビデオを取得している方法は次のとおりです。
http://vimeo.com/video_id
を選択します。video_id
のみを取得します。http://vimeo.com/moogaloop/load/clip:video_id;
のXMLを取得します。xMLを解析し、必要な情報を見つけます。
リンクを生成します。
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
ブラウザで手動でこれを行うと機能しますが、スクリプトで行うと機能しません。
Vimeoへの直接リンクを取得する方法を見つけるために数時間を費やした後、良い解決策を見つけました。そのため、vimeoからビデオsrcを直接ダウンロードしてストリーミングしたいユーザー向けの手順があります。この方法でビデオをダウンロードしているすべてのIPアドレスとホストをブロックしていることに注意してください。そのため、サービスの使用を停止しただけなので、再び使用することはありません。
ビデオソースを取得する手順:
http://vimeo.com/video_id
_video_id
_のみを取得しますhttp://vimeo.com/moogaloop/load/clip:video_id;
_xmlを解析すると、必要な情報が見つかります。
request_signature
_request_signature_expires
_isHD
次に、リンクを生成します。
_$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
_
次に、php devの場合、この方法でexecを介してwgetコマンドを呼び出します。
exec("wget -b '$video_link' -a 'wget.log' -O -");
次に、ログを読み、探しているリンクを見つけます。ログファイルを単純に解析できます。直接リンクは「Location:」と「[following]」の間にあります
直接リンクを返し、ログファイルを消去します:)
注:これは永久に機能しないことに注意してください。遅かれ早かれ、彼らはあなたのIPをブロックします:)。
この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>";
警告上記の方法はVimeoではサポートされていません。彼らが現在働いているか、将来も仕事を続けるという保証はありません。予告なしに、いつでも壊れる可能性があります(そしておそらく壊れるでしょう)。
ビデオファイルのURLにアクセスする公式にサポートされている唯一の方法は、 [〜#〜] api [〜#〜] を使用することです。
所有している動画のURLにアクセスしようとしている場合は、PROアカウントが必要です。
自分が所有していない動画のURLにアクセスしようとしている場合は、 動画を埋め込む または Vimeo iOSアプリで開く を使用する必要があります。
参考までに、上記の例は機能しませんが、近いです。偽のCookieを送信する必要があります。そのため、基本的にXMLを使用してページにアクセスするときは、Cookieを取得し、最後のビデオURLにアクセスするときに以前に受け取ったCookieを送信する必要があります。だから、PHP(Yiiを使用)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;
}
PHPはもちろん、スクリプトも必要ありません。
「プライバシー設定」のためにvimeo.comでも再生できない保護されたビデオ(特定のWebサイトに埋め込まれている)をダウンロードしたかった。
開発者ツール(Opera Dragonfly、Chrome開発者ツール、その他)を起動するだけで、ネットワークを選択します。
http://pdl.vimeocdn.com/23062/181/302074466.mp4?token2=1424299768_bbeb6039c037cd429cd560d668ec851e&aksessionid=1f4d289cd1a3abe1
メソッド:Get
ステータステキスト:206部分的なコンテンツ
タイプ:video/mp4
最初のURLをコピーして、何らかのツールでダウンロードします(「wget」を使用しました)。
保存しました。
アルゴリズムは次のようになります。
これが私の簡単なクラスで、この瞬間に機能します:
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'));
SuperUserでのこれに対する回答は古くなっていたので、ここに投稿すると思いました(そこに投稿するには評判が足りません)
だから、XHRリクエストをChrome devtoolsで記録しました。最初のリクエストは、akamaiが提供するトークンとともにakamai CDNホスト動画へのリンクを含むjsonファイルに対するものでした。このトークンは重要です。タイムスタンプを含むハッシュであるため、ここの動画へのリンクは、すぐにダウンロードする必要があるか、リクエストが拒否されます。
この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はプライバシーのために置き換えた数字です。
迅速で汚いアプローチは次のとおりです。
$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);
}
}