首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

優酷視頻絕對地址獲取深度解析:ActionScript 反編譯、Seed 混淆演算法與多段組裝

     編輯:PHP 綜合知識

本文從 ActionScript 反編譯角度,深度還原優酷播放器核心邏輯:getPlayList API 回應結構、Seed 混淆演算法、Key1/Key2 異或解密、分段 K 值處理與最終 URL 組裝。適合需自行維護解析器的開發者參考。

1. 入口:獲取播放清單

$baseUrl = 'https://v.youku.com/player/getPlayList/VideoIDS/';
$videoId = $_GET['vid'] ?? 'XMjY0ODE1MDA0'; // 測試用 ID

$ch = curl_init($baseUrl . $videoId);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => true,           // 需要 Header 解析 Set-Cookie 等
    CURLOPT_REFERER        => 'https://v.youku.com/v_show/id_' . $videoId,
    CURLOPT_USERAGENT      => $_SERVER['HTTP_USER_AGENT'],
]);
$response = curl_exec($ch);
curl_close($ch);

2. 從回應提取關鍵參數(正則解析 JSON 片段)

// 回應為 JSON 夾雜在 HTML/JS 中,需正則提取
preg_match('~"seed"\s*:\s*(\d+)~i', $response, $mSeed);
preg_match('~"(flv|mp4|hd2)"\s*:\s*"([^"]+)"~i', $response, $mEncoded);
preg_match('~"key1"\s*:\s*"([^"]+)"~i', $response, $mKey1);
preg_match('~"key2"\s*:\s*"([^"]+)"~i', $response, $mKey2);

$seed      = (int)$mSeed[1];
$format    = $mEncoded[1];      // flv / mp4 / hd2
$encrypted = $mEncoded[2];      // 加密的 fileid 字串
$key1      = $mKey1[1];
$key2      = $mKey2[1];

3. 解密類別:Decoder(ActionScript 邏輯移植)

class Decoder
{
    private int $seed;
    private string $mixed = '';

    public function __construct(int $seed)
    {
        $this->seed = $seed;
    }

    // LCG 產生下一隨機比例 [0,1)
    private function nextRatio(): float
    {
        $this->seed = (($this->seed * 211) + 30031) % 65536;
        return $this->seed / 65536;
    }

    // 生成 64 字元混淆字串 (cg_hun)
    private function buildMixed(): void
    {
        $source = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\:._-1234567890';
        $this->mixed = '';
        for ($i = 0; $i < strlen($source); $i++) {
            $idx = (int)($this->nextRatio() * strlen($source));
            $this->mixed .= $source[$idx];
            $source = substr_replace($source, '', $idx, 1);
        }
    }

    // 解密 fileid:按 * 分割索引,從 mixed 取字元
    public function decodeFileId(string $encrypted): string
    {
        $this->buildMixed();
        $parts = explode('*', $encrypted);
        array_pop($parts); // 移除尾部空值
        $result = '';
        foreach ($parts as $idx) {
            $result .= $this->mixed[(int)$idx] ?? '';
        }
        return $result;
    }

    // 解密 Key:key1 (hex) 異或 0xA55AA5A5,拼接 key2
    public function decodeKey(string $key1, string $key2): string
    {
        $val = hexdec($key1);
        $val ^= 0xA55AA5A5; // -1520786011 (有號整數)
        return $key2 . dechex($val);
    }
}

4. 組裝最終下載地址

$decoder = new Decoder($seed);
$fileId  = $decoder->decodeFileId($encrypted);
$key     = $decoder->decodeKey($key1, $key2);

// 構造 SID:時間戳 + 隨機 + 固定後綴
$sid = time() . mt_rand(10, 99) . '1000' . mt_rand(30, 80) . '00';

// 畫質分段代碼:00=第一段, 01=第二段... 0f=第十五段
$segCode = '00';

// 最終 URL 結構
$url = "https://f.youku.com/player/getFlvPath/sid/{$sid}_{$segCode}/st/{$format}/fileid/{$fileId}?K={$key}";
echo $url;

5. 多段視頻處理(關鍵更新)

新版 API 回應中 segs.{format} 為陣列,每段擁有獨立 k 值:

"segs": {
  "mp4": [
    {"no":"0","size":"18367795","seconds":"421","k":"281ff2875db680bb261c02ce"},
    {"no":"1","size":"19045091","seconds":"421","k":"45398cdd4aa44968261c02ce"}
  ]
}

正確做法:遍歷每一段,使用該段的 k 組裝 URL,下載後用 ffmpeg 合併:

foreach ($data->data[0]->segs->$format as $seg) {
    $segUrl = "https://f.youku.com/player/getFlvPath/sid/{$sid}_{$seg->no}/st/{$format}/fileid/{$fileId}?K={$seg->k}";
    // 下載該段...
}
// 合併:ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

反編譯關鍵發現總結

AS3 類/方法功能PHP 對應
Decoder.__construct(seed)初始化 LCG 種子__construct($seed)
ran()產生下一隨機比例nextRatio()
cg_hun()生成混淆字串buildMixed()
decode(fileid)解密 fileiddecodeFileId()
decode_key(key1,key2)異或解密 KeydecodeKey()

維護建議

  1. 封裝為獨立庫:將解密邏輯隔離,便於演算法更新時單點修改。
  2. 單元測試覆蓋:收集多個真實 API 回應樣本,建立黃金測試向量,確保重構不破壞功能。
  3. 監控失效率:記錄解析失敗案例(正則不匹配、解密結果為空),設定告警。
  4. 優先遷移至 yt-dlp:社群維護、支援多站點、自動處理分段合併、字幕、年齡限制等邊界情況。

法律與道德提醒

本文僅供技術研究與教學用途。繞過平台授權機制下載受版權保護內容,可能違反《中華人民共和國著作權法》第 47 條及《信息網絡傳播權保護條例》。商業專案請務必取得正規授權或使用平台提供的開放 API。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved