優酷視頻頁面不直接提供媒體檔案直連,需透過其內部 API 獲取加密的 fileid、sid、token 等參數組合成下載 URL。本文解析優酷播放清單 API 邏輯,提供完整 PHP 解析類別,支援 FLV/MP4 多清晰度、批次解析、快取機制。
video_id (如 id_XMjA5MjQ0OTQ0)https://v.youku.com/player/getPlayList/VideoIDS/{video_id} 取得播放清單 JSONstreamfileids、seed、segs、streamtypesseed 產生亂序字串,配合 streamfileids 還原真實 fileidsid (時間戳+隨機數)https://f.youku.com/player/getFlvPath/sid/{sid}_00/st/{format}/fileid/{fileid}?K={k}<?php
/**
* 優酷視頻真實鏈接解析器
* 支援 FLV/MP4/HD/3GP 多格式
*/
class YoukuParser {
const PLAYLIST_API = 'https://v.youku.com/player/getPlayList/VideoIDS/';
const DOWNLOAD_BASE = 'https://f.youku.com/player/getFlvPath/sid/%s_00/st/%s/fileid/%s?K=%s';
private $httpTimeout = 10;
private $cacheDir = __DIR__ . '/cache/';
private $cacheTtl = 3600; // 1小時
public function __construct() {
if (!is_dir($this->cacheDir)) @mkdir($this->cacheDir, 0777, true);
}
/**
* 解析優酷分享頁 URL
* @param string $shareUrl 如 https://v.youku.com/v_show/id_XMjA5MjQ0OTQ0.html
* @return array ['flv'=>url, 'mp4'=>url, 'hd2'=>url, ...] 或 false
*/
public function parse($shareUrl) {
// 1. 提取 video_id
if (!preg_match('#id_([^./]+)#', $shareUrl, $m)) {
return false;
}
$videoId = $m[1];
// 2. 獲取播放清單 (含快取)
$cacheFile = $this->cacheDir . 'playlist_' . $videoId . '.json';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $this->cacheTtl)) {
$json = file_get_contents($cacheFile);
} else {
$json = $this->httpGet(self::PLAYLIST_API . $videoId);
if ($json) file_put_contents($cacheFile, $json);
}
if (!$json) return false;
$data = json_decode($json, true);
if (empty($data['data'][0])) return false;
$video = $data['data'][0];
// 3. 解析各清晰度下載鏈接
$result = [];
foreach ($video['streamfileids'] as $format => $fileidEnc) {
if (!isset($video['segs'][$format])) continue;
$fileid = $this->decodeFileId($fileidEnc, $video['seed']);
$sid = $this->genSid();
$k = $video['segs'][$format][0]['k']; // 加密 key
$url = sprintf(self::DOWNLOAD_BASE, $sid, $format, $fileid, $k);
$result[$format] = $url;
}
return $result ?: false;
}
/** 解碼 fileid:依 seed 產生亂序字串,按索引取字元 */
private function decodeFileId($fileidEnc, $seed) {
$mixed = $this->genMixedString($seed);
$ids = explode('*', $fileidEnc);
array_pop($ids); // 最後一個空
$realId = '';
foreach ($ids as $idx) {
$realId .= $mixed[$idx];
}
return $realId;
}
/** 依 seed 產生 62 字元亂序字串 (a-zA-Z0-9/:._-) */
private function genMixedString($seed) {
$source = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/:._-1234567890';
$len = strlen($source);
$mixed = '';
for ($i = 0; $i < $len; $i++) {
$seed = ($seed * 211 + 30031) % 65536;
$index = (int)($seed / 65536 * strlen($source));
$c = $source[$index];
$mixed .= $c;
$source = str_replace($c, '', $source);
}
return $mixed;
}
/** 產生 sid:時間戳 + 5位隨機數 */
private function genSid() {
return time() . mt_rand(10000, 99999);
}
/** 簡易 HTTP GET */
private function httpGet($url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->httpTimeout,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
]);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
}
// ==================== 使用範例 ====================
$parser = new YoukuParser();
$url = 'https://v.youku.com/v_show/id_XMzg2OTQ3MjQw.html';
$links = $parser->parse($url);
if ($links) {
echo "解析成功:
";
foreach ($links as $fmt => $link) {
echo "$fmt: $link
";
}
} else {
echo "解析失敗:URL 格式錯誤或視頻不存在";
}
?>
| format 鍵值 | 容器/編碼 | 清晰度 | 備註 |
|---|---|---|---|
| flv | FLV / H.264 | 標清 | 最通用、相容性最好 |
| mp4 | MP4 / H.264 | 高清 | 現代瀏覽器原生支援 |
| hd2 | MP4 / H.264 | 超清 (720p/1080p) | 需會員或特定視頻 |
| 3gp | 3GP / H.263 | 流動裝置低畫質 | 較少用 |
$urls = [
'https://v.youku.com/v_show/id_X1.html',
'https://v.youku.com/v_show/id_X2.html',
// ...
];
$parser = new YoukuParser();
$results = [];
foreach ($urls as $url) {
$results[$url] = $parser->parse($url);
// 避免請求過快被限流
usleep(200000); // 0.2秒
}
// 儲存結果供前端播放器使用
file_put_contents('youku_links.json', json_encode($results, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
| 現象 | 原因 | 解決 |
|---|---|---|
| 返回 false / 空陣列 | 視頻已刪除、需會員、地區限制、URL 格式變更 | 瀏覽器開啟原 URL 確認可播放、檢查正則提取 video_id |
| 下載鏈接 403/404 | sid 過期、K 值失效、Referer/UA 檢查 | 即時解析即用、模擬瀏覽器 UA、加 Referer: https://v.youku.com/ |
| MP4 無法播放 | 瀏覽器不支援該編碼 (如 H.265/HEVC) | 優先使用 flv 或轉碼 |
優酷視頻真實鏈接解析核心在於 seed → 混淆字串 → fileid 還原 演算法。本文提供完整、可快取、可批次的 PHP 類別實作,支援多清晰度格式。實際應用中請嚴格遵守版權法規,優先使用官方授權管道獲取視頻資源。