顯示具有 yt-dlp 標籤的文章。 顯示所有文章
顯示具有 yt-dlp 標籤的文章。 顯示所有文章

2024年8月16日 星期五

Python 開發筆記 - 引用 yt-dlp extractor 資源,呼叫特定函數功能

我想 yt-dlp 應當不用做太多簡介,他本身容納了各種影音網站的分析器,以前也片段片段的研究:
原本有個任務是讓同事處理,他在忙碌就幫忙試了一下,整體上就問問 ChatGPT 就得到想要的八成的範例程式,接著再小幅修改一下使用方式就收工。有了 ChatGPT 後,幾乎可以不用做什麼筆記,忘了就在問一下即可,當然,能不能一問就得到結果,就回歸到詢問者的功力了。

例如情境:

透過 yt-dlp extractor 內的 facebook.py ,幫我列出 facebook video 內的格式,以協助進行產品多媒體格式的偵錯

如此 ChatGPT 就給我不錯的程式碼,修改一下,搞定:

```
% git clone https://github.com/yt-dlp/yt-dlp.git

% cat test-facebook.py
import sys
import argparse

def get_video_formats(url):
    from yt_dlp.YoutubeDL import YoutubeDL
    from yt_dlp.extractor.facebook import FacebookIE

    # 创建一个 YoutubeDL 实例
    ydl_opts = {}
    with YoutubeDL(ydl_opts) as ydl:
        # 实例化 FacebookIE 类,并传递 ydl 对象作为 downloader
        facebook_ie = FacebookIE(ydl)
        
        # 使用 extract 方法提取视频信息
        video_info = facebook_ie.extract(url)
        
        # 获取可用的格式
        formats = video_info.get('formats', [])
        
        # 打印所有格式的id和分辨率
        for fmt in formats:
            # 获取格式的分辨率,如果没有就使用 'N/A'
            resolution = fmt.get('height', 'N/A')
            print(f"Format ID: {fmt['format_id']}, Resolution: {resolution}p")

if __name__ == "__main__":
    # 设置命令行参数解析
    parser = argparse.ArgumentParser(description='Extract video formats from a Facebook video URL using yt-dlp.')
    parser.add_argument('--path', required=True, help='Path to the yt-dlp directory')
    parser.add_argument('--facebook-url', required=True, help='Facebook video URL')

    args = parser.parse_args()

    # 将 yt-dlp 的路径插入 sys.path
    sys.path.insert(0, args.path)

    # 调用函数来获取视频格式
    get_video_formats(args.facebook_url)

% python3 test-facebook.py --path ./yt-dlp/ --facebook-url 'https://www.facebook.com/TED/videos/1464960234158173'
[facebook] Extracting URL: https://www.facebook.com/TED/videos/1464960234158173
[facebook] 1464960234158173: Downloading webpage
Format ID: hd, Resolution: N/Ap
Format ID: sd, Resolution: N/Ap
Format ID: 492667606832062v, Resolution: 720p
Format ID: 1654227388706906v, Resolution: 720p
Format ID: 849737406808391v, Resolution: 720p
Format ID: 1263117531679597v, Resolution: 1080p
Format ID: 1036187750774836a, Resolution: Nonep
```

收工!

這樣往後有哪些 extrator 內有一些有趣的 function ,就可以這樣呼叫出來使用,省去自己在重複刻輪子,且如果有需要更新維護,僅需把 yt-dlp code 更新到最新即可,保留異質系統整合彈性

此外 yt-dlp 本身指令有支援 JSON output ,若 yt-dlp JSON output 已夠用,也不需要向上述那樣用法,上述筆記純粹是一個範例,像是取得中間資料結構等等。

2023年5月3日 星期三

yt-dlp 開發筆記 @ Python3, macOS 13.2.1

yt-dlp 是知名的網路影音網站研究的專案,內含不少各大網站的爬蟲技術。若某個服務失效想要貢獻的話,可這樣操作,邊改 code 變測試:

% git clone https://github.com/yt-dlp/yt-dlp.git
% cd yt-dlp
% python3 yt_dlp/__main__.py 'URL' --skip-download -j

以 2023/08/31 即將關站的 Xuite 為例,從 github.com/yt-dlp/yt-dlp/tree/master/yt_dlp/extractor/xuite.py 找一則 unit test 來跑:

% python3 yt_dlp/__main__.py 'http://vlog.xuite.net/embed/cE1xbENoLTI3NDQ3MzM2LmZsdg==?ar=0&as=0' -f mp4 --skip-download -j | jq '' | tail -n 25
  "format_id": "720",
  "height": 720,
  "protocol": "http",
  "resolution": "720p",
  "dynamic_range": "SDR",
  "aspect_ratio": null,
  "http_headers": {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.50 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-us,en;q=0.5",
    "Sec-Fetch-Mode": "navigate"
  },
  "video_ext": "mp4",
  "audio_ext": "none",
  "format": "720 - 720p",
  "_filename": "男女平權只是口號?專家解釋約會時男生是否該幫女生付錢 (中字) [27447336].mp4",
  "filename": "男女平權只是口號?專家解釋約會時男生是否該幫女生付錢 (中字) [27447336].mp4",
  "_type": "video",
  "_version": {
    "version": "2023.03.04",
    "current_git_head": "b423b6a48",
    "release_git_head": "392389b7df7b818f794b231f14dc396d4875fbad",
    "repository": "yt-dlp/yt-dlp"
  }
}

至於,若要貢獻給 yt-dlp 社群,可以仿其架構,挑一個 extractor 來模仿,過程要繼承 InfoExtractor 來做事,例如實作 _VALID_URL 和 _real_extract(self, url) 等等,可以挑幾個實作沒那麼複雜的網站研究一下流程:

2021年10月19日 星期二

Python 筆記 - 研究 yt-dlp / youtube-dl 流程與開發方式

幫同事查了一下程式邏輯,下手的方向:
  • 入口點在哪
  • 到底怎樣跑
  • 我要怎樣擴充或貢獻一個影音網站 extractor
github.com/yt-dlp/yt-dlp 來看,入口點就直接看 yt-dlp.sh 即可:

% git clone https://github.com/yt-dlp/yt-dlp
% cd yt-dlp 
% python3 yt_dlp/__main__.py 
Usage: __main__.py [OPTIONS] URL [URL...]

__main__.py: error: You must provide at least one URL.
Type yt-dlp --help to see a list of all options.

接著掃一下 yt_dlp/__main__.py 和 yt_dlp/__init__.py 就略懂他在處理 command line 的參數,而程式的本體是在 yt_dlp/YoutubeDL.py 檔案,一樣在追個 yt_dlp/YoutubeDL.py 裡的 class YoutubeDL 中的 def __init__() 裡,可以看到 self.add_default_info_extractors() 這步,如此就把 yt_dlp/extractor/ 眾多網站影音分析爬蟲狀態初始化好。

接著,給予一則影音網站連結:

% python3 yt_dlp/__main__.py https://www.facebook.com/UserID/videos/VideoID/

程式就會在 yt_dlp/YoutubeDL.py extract_info() 分析做事,像是把所有 extractor 都瀏覽一次,透過呼叫 ie.suitable(url) 的機制判斷。這時可以對應在 yt_dlp/extractor/common.py 中,看到 class InfoExtractor(object) 裡的 suitable() 定義並用 _match_valid_url() 和 _VALID_URL 實作,這時回去猜 yt_dlp/extractor/facebook.py 時,找不到 suitable() 也找不到 _match_valid_url() 時,就可以猜應該是 _VALID_URL 的實作方式了。

回到 yt_dlp/YoutubeDL.py 時,在 extract_info() 分析做事時,找到合適的 extractor 後,就會立即靠 ie.extract(url) 解析,而實際實作是靠 _real_extract()。再找一下 yt_dlp/extractor/facebook.py 中是否有定義 extract() 或 _real_extract(),即可當作解析網站的程式邏輯入口點。

最後,想要擴充某個網站或是修補加強某個網站,就可以去改對應的 extractor 了。並且可以把在當前目錄下,不斷靠 yt-dlp.sh 去實測,也滿方便的。