Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
app/Sns/VideoExtractor/YoukuExtractor.php
<?php
namespace App\Sns\VideoExtractor;
use GuzzleHttp\Cookie\CookieJar;
use Exception;
/**
* Example:
* url: http://v.youku.com/v_show/id_XMTc1ODE5Njcy.html
* result:
* "source" => "youku"
* "source_id" => "XMTc1ODE5Njcy"
* "play_url" => "http://gslb.miaopai.com/stream/n~0hO7sfV1nBEw4Y29-Hqg__.mp4"
* "cover" => "http://bsyimg6.cdn.krcom.cn/images/n~0hO7sfV1nBEw4Y29-Hqg___m88y.jpg"
* "url_type" => "mp4"
*/
class YoukuExtractor extends BaseExtractor implements ExtractorInterface
{
const URL_REGEX =
'/https?:\/\/(?:v|player).youku.com\/' .
'(?:v_show\/id_|player\.php\/sid\/)' .
'([-A-Za-z0-9~]+)(?:\.html|\/v\.swf|)/';
//const USER_AGENT = 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1';
const MEDIA_TYPE = 'mp4';
const MEDIA_SOURCE = 'youku';
/**
* 根据视频 Url 获取视频信息
*
* @param $url
*
* @return array
*/
public function extractVideo()
{
$fingerprint = $this->fingerprint();
$sourceId = $fingerprint['source_id'];
$randUpcaseLetter = chr(rand($LETTER_A = 65, $LETTER_Z = 90));
$cookieJar = CookieJar::fromArray([
'__ysuid' => time() . $randUpcaseLetter,
'xreferrer' => 'http://www.youku.com'
], 'youku.com');
list($stream, $response) = $this->requestUrl(
'http://log.mmstat.com/eg.js', ['cookies' => $cookieJar]
);
list($etag) = $response->getHeader('ETag');
# The etag header is '"foobar"'; let's remove the double quotes
$etag = substr($etag, 1, -1);
$baseParams = [
'vid' => $sourceId,
'ccode' => '0401',
'client_ip' => '192.168.1.1',
'utid' => $etag,
'client_ts' => time() / 1000,
];
$headers = [
'Referer' => $this->url,
];
list($stream, $response) = $this->requestUrl(
'https://ups.youku.com/ups/get.json', [
'cookies' => $cookieJar,
'query' => $baseParams,
'headers' => $headers,
]
);
$json = json_decode($stream);
$data = $json->data;
$error = object_get($data, 'error');
if (!empty($error)) {
$note = object_get($error, 'note');
throw new Exception("Youku:{$note}");
}
$info = $data->video;
// 目前只播放抓取回的第一段视频
$stream = $data->stream[0];
dump($stream);
return $fingerprint + [
'play_url' => $stream->m3u8_url,
'cover' => $info->logo,
'title' => $info->title,
'url_type' => static::MEDIA_TYPE,
];
}
/**
* 通过 url 获取 source 和 source_id, fingerprint = ['source', 'source_id']
*
* @param $url
* @return array
*/
public function fingerprint()
{
preg_match(static::URL_REGEX, $this->url, $matches);
return [
'source' => static::MEDIA_SOURCE,
'source_id' => $matches[1],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment