早期視頻網站 (優酷、土豆) 使用 Flash (SWF) 播放器,嵌入第三方網站需獲取播放器 SWF 地址。雖然 Flash 已淘汰,但解析邏輯對理解 URL 模式、正則提取、域名路由仍有參考價值。
youku.com 或 tudou.com。v.youku.com/v_show/id_...) vs 播放器頁 (player.youku.com/...)。/**
* 從優酷/土豆頁面 URL 獲取標準 SWF 播放器地址
* @param string $url 用戶提交的視頻頁面或播放器 URL
* @return string|false SWF 地址或失敗返回 false
*/
function getSwfPlayerUrl($url) {
if (empty($url)) return false;
// 1. 解析 URL 組件
$parts = parse_url($url);
if (!$parts || empty($parts['host'])) return false;
$host = strtolower($parts['host']);
$path = $parts['path'] ?? '';
// 2. 優酷
if (strpos($host, 'youku.com') !== false) {
// 已是播放器頁
if (strpos($host, 'player.youku.com') !== false) {
return $url;
}
// 視頻頁:提取 id_
if (preg_match('/v_show\/id_([^\/]+)\.html/i', $path, $m)) {
return 'https://player.youku.com/player.php/sid/' . $m[1] . '/v.swf';
}
// 兼容舊版 embed URL
if (preg_match('/player\.php\/sid\/([^\/]+)/i', $path, $m)) {
return 'https://player.youku.com/player.php/sid/' . $m[1] . '/v.swf';
}
return $url; // 無法識別,原樣返回
}
// 3. 土豆
if (strpos($host, 'tudou.com') !== false) {
// 已是 SWF
if (stripos($path, 'v.swf') !== false) {
return $url;
}
// 頁面 URL 模式:/programs/view/... 或 /v/... 或 /albumplay/...
// 提取 icode (視頻唯一標識)
$icode = null;
if (preg_match('/\/(?:v|programs\/view|albumplay)\/([^\/]+)/i', $path, $m)) {
$icode = $m[1];
} elseif (preg_match('/icode=([^&]+)/i', $parts['query'] ?? '', $m)) {
$icode = $m[1];
}
if ($icode) {
// 土豆播放器模式:v (視頻) / p (專輯) - 簡單判斷
$mode = (strpos($path, '/v/') !== false || strpos($path, '/programs/view') !== false) ? 'v' : 'p';
return "https://www.tudou.com/{$mode}/{$icode}/v.swf";
}
return $url;
}
// 4. 其他域名:原樣返回
return $url;
}
// 測試用例
$tests = [
'https://v.youku.com/v_show/id_XMTIzNDU2.html' => 'https://player.youku.com/player.php/sid/XMTIzNDU2/v.swf',
'https://player.youku.com/player.php/sid/XMTIzNDU2/v.swf' => 'https://player.youku.com/player.php/sid/XMTIzNDU2/v.swf',
'https://www.tudou.com/v/abc123' => 'https://www.tudou.com/v/abc123/v.swf',
'https://www.tudou.com/programs/view/xyz789/' => 'https://www.tudou.com/v/xyz789/v.swf',
'https://www.tudou.com/albumplay/album123/' => 'https://www.tudou.com/p/album123/v.swf',
'https://www.bilibili.com/video/BV1xx' => 'https://www.bilibili.com/video/BV1xx', // 非目標站點
];
foreach ($tests as $input => $expected) {
$result = getSwfPlayerUrl($input);
$status = ($result === $expected) ? '✓' : '✗';
echo "{$status} Input: {$input}\n";
echo " Output: {$result}\n";
echo " Expected: {$expected}\n\n";
}
| 環節 | 原文問題 | 改進方案 |
|---|---|---|
| 域名匹配 | 正則 /https://(.*?)?.(.*?)?.com/ 過於寬鬆,易誤匹配 | parse_url() 獲取 host,精確 strpos() 判斷 |
| 視頻 ID 提取 | 多層 explode、count 判斷脆弱 | 針對性正則捕獲組,直接提取 ID |
| 土豆模式判斷 | 首字符判斷 p/v 不準確 | 根據路徑關鍵字 (/v/, /programs/view) 判斷 |
| 代碼結構 | 單一巨大函數,邏輯混雜 | 分站點處理,提前返回,清晰可維護 |
優酷、土豆早已全面遷移至 HTML5 播放器 (iframe embed)。當前嵌入方式:
<iframe src="https://player.youku.com/embed/VIDEO_ID"></iframe>本文代碼僅供歷史邏輯參考,實際項目請使用官方提供的嵌入代碼或 API。
視頻 URL 解析核心是:標準化 URL 解析 → 領域知識提取關鍵標識 → 重構目標 URL。避免手工拆分字符串,善用 parse_url()、具體正則捕獲組,代碼更健壯、可維護。