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

PHP 解析優酷視頻真實 FLV/MP4 下載鏈接:API 參數逆向與完整實作代碼

     編輯:PHP 綜合知識

優酷視頻頁面不直接提供媒體檔案直連,需透過其內部 API 獲取加密的 fileid、sid、token 等參數組合成下載 URL。本文解析優酷播放清單 API 邏輯,提供完整 PHP 解析類別,支援 FLV/MP4 多清晰度、批次解析、快取機制。

核心流程

  1. 從分享頁 URL 提取 video_id (如 id_XMjA5MjQ0OTQ0)
  2. 請求 https://v.youku.com/player/getPlayList/VideoIDS/{video_id} 取得播放清單 JSON
  3. 解析 JSON 中的 streamfileids、seed、segs、streamtypes
  4. 依演算法由 seed 產生亂序字串,配合 streamfileids 還原真實 fileid
  5. 產生 sid (時間戳+隨機數)
  6. 組合下載 URL:https://f.youku.com/player/getFlvPath/sid/{sid}_00/st/{format}/fileid/{fileid}?K={k}

完整 PHP 解析類別

<?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 鍵值容器/編碼清晰度備註
flvFLV / H.264標清最通用、相容性最好
mp4MP4 / H.264高清現代瀏覽器原生支援
hd2MP4 / H.264超清 (720p/1080p)需會員或特定視頻
3gp3GP / 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));

法律與道德提醒

  • 優酷視頻受版權保護,解析下載鏈接僅供技術研究、個人備份、合法授權範圍內使用。
  • 請遵守《網絡安全法》、《著作權法》及優酷服務條款,勿用於商業盜鏈、熱鏈、批量下載分發。
  • 優酷 API 參數演算法可能隨時變更,本代碼僅供學習參考,生產環境請使用官方開放平台 API (如有)。

常見問題

現象原因解決
返回 false / 空陣列視頻已刪除、需會員、地區限制、URL 格式變更瀏覽器開啟原 URL 確認可播放、檢查正則提取 video_id
下載鏈接 403/404sid 過期、K 值失效、Referer/UA 檢查即時解析即用、模擬瀏覽器 UA、加 Referer: https://v.youku.com/
MP4 無法播放瀏覽器不支援該編碼 (如 H.265/HEVC)優先使用 flv 或轉碼

小結

優酷視頻真實鏈接解析核心在於 seed → 混淆字串 → fileid 還原 演算法。本文提供完整、可快取、可批次的 PHP 類別實作,支援多清晰度格式。實際應用中請嚴格遵守版權法規,優先使用官方授權管道獲取視頻資源。

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