6 điểm bởi GN⁺ 2024-07-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • MeTube là một web UI tự host cho yt-dlp, cho phép tải media từ YouTube và hàng chục trang được hỗ trợ ngay trong trình duyệt
  • Hỗ trợ tải video, âm thanh, phụ đề, thumbnail; cũng có thể tải playlist và kênh với tùy chọn định dạng đầu ra và tùy chọn tải xuống có thể điều chỉnh
  • Có thể đăng ký theo dõi kênh và playlist để định kỳ kiểm tra mục mới, rồi tự động đưa các bản tải lên mới vào hàng đợi
  • Chạy bằng Docker hoặc docker-compose; cấu hình số lượt tải đồng thời, đường dẫn lưu, mẫu tên tệp, HTTPS, CORS, theme, mức log, v.v. bằng biến môi trường
  • Các tùy chọn yt-dlp được kết hợp theo thứ tự tùy chọn toàn cục, preset, rồi override theo từng lượt tải; override theo từng lượt tải cho phép nhập tùy chọn tùy ý nên chỉ nên bật trong môi trường đáng tin cậy

MeTube làm gì

  • MeTube là web UI tự host dựa trên yt-dlp
  • Có thể tải media từ YouTube và hàng chục trang mà yt-dlp hỗ trợ
  • Các tính năng chính gồm:
    • Tải video, âm thanh, phụ đề, thumbnail từ UI trên trình duyệt
    • Tải playlist và kênh
    • Cấu hình đường dẫn đầu ra và tùy chọn tải xuống
    • Đăng ký theo dõi kênh/playlist rồi định kỳ kiểm tra mục mới
    • Tự động thêm các bản tải lên mới vào hàng đợi tải xuống

Cách chạy

  • Có thể chạy ngay bằng Docker
docker run -d -p 8081:8081 -v /path/to/downloads:/downloads ghcr.io/alexta69/metube
  • Ví dụ docker-compose dùng image ghcr.io/alexta69/metube và mount /downloads trong container vào thư mục tải xuống trên host
services:
  metube:
    image: ghcr.io/alexta69/metube
    container_name: metube
    restart: unless-stopped
    ports:
      - "8081:8081"
    volumes:
      - /path/to/downloads:/downloads

Cấu hình tải xuống và lưu trữ

  • MAX_CONCURRENT_DOWNLOADS giới hạn số lượt tải có thể chạy đồng thời, mặc định là 3
  • Nếu DELETE_FILE_ON_TRASHCANtrue, khi đưa một mục trong phần “Completed” của UI vào thùng rác, tệp đã tải trên máy chủ cũng bị xóa
  • DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT đặt số mục tối đa có thể tải từ playlist; giá trị mặc định 0 nghĩa là không giới hạn
  • Các giá trị mặc định liên quan đến đăng ký theo dõi cũng được điều chỉnh bằng biến môi trường
    • SUBSCRIPTION_DEFAULT_CHECK_INTERVAL: khoảng thời gian tự động kiểm tra cho từng đăng ký, mặc định 60 phút
    • SUBSCRIPTION_SCAN_PLAYLIST_END: số mục playlist/kênh tối đa sẽ lấy khi kiểm tra đăng ký, mặc định 50
    • SUBSCRIPTION_MAX_SEEN_IDS: giới hạn số ID video lưu cho mỗi đăng ký, mặc định 50000
  • DOWNLOAD_DIR là đường dẫn lưu tải xuống; trong image Docker, mặc định là /downloads
  • Các lượt tải chỉ âm thanh có thể có đường dẫn lưu riêng bằng AUDIO_DOWNLOAD_DIR
  • Có thể dùng CUSTOM_DIRSCREATE_CUSTOM_DIRS để chọn hoặc tự động tạo thư mục con tải xuống trong UI
  • STATE_DIR lưu các tệp trạng thái bền vững như queue.json, pending.json, completed.json, subscriptions.json
  • TEMP_DIR là đường dẫn cho tệp tải xuống trung gian; dùng SSD hoặc hệ thống tệp RAM có thể giúp cải thiện hiệu năng, nhưng hệ thống tệp RAM có thể ngăn việc tiếp tục tải xuống

Tên tệp và tùy chọn yt-dlp

  • OUTPUT_TEMPLATE là mẫu tên tệp tải xuống, mặc định là %(title)s.%(ext)s
  • Có thể đặt mẫu riêng cho tải chương, playlist và kênh
    • OUTPUT_TEMPLATE_CHAPTER

    • OUTPUT_TEMPLATE_PLAYLIST

      • OUTPUT_TEMPLATE_CHANNEL
      • Tùy chọn yt-dlp được chỉ định dưới dạng đối tượng JSON
      • Các tầng tùy chọn được áp dụng theo thứ tự từ phạm vi rộng đến hẹp
      1. Tùy chọn toàn cục: giá trị mặc định cho mọi lượt tải
      2. Preset: các nhóm tùy chọn có tên, được chọn theo từng lượt tải trong UI
      3. Override theo từng lượt tải: tùy chọn nhập tự do chỉ áp dụng cho một lượt tải cụ thể
      • Nếu có khóa xung đột, cấu hình cụ thể hơn sẽ được ưu tiên
      • Override theo từng lượt tải ưu tiên hơn preset
      • Preset ưu tiên hơn tùy chọn toàn cục
      • Nếu đặt giá trị tùy chọn trong JSON là null, tùy chọn đó sẽ bị xóa khỏi lượt tải tương ứng
      • YTDL_OPTIONS_FILEYTDL_OPTIONS_PRESETS_FILE theo dõi thay đổi tệp và tự động tải lại, nên không cần khởi động lại container
      • Nếu dùng cả tệp lẫn biến môi trường và định nghĩa cùng khóa hoặc cùng tên preset, cấu hình trong tệp sẽ được ưu tiên

Preset và override

  • Preset hiển thị dưới “Option Presets” trong Advanced Options của UI
  • Các preset ví dụ thực hiện những tác vụ sau:
    • sponsorblock: loại bỏ các đoạn sponsor, selfpromo, interaction
    • embed-subs: tải phụ đề tiếng Anh và tiếng Đức rồi nhúng vào tệp video
    • limit-rate: giới hạn tốc độ tải xuống khoảng 5 MB/s
  • Khi chọn nhiều preset, chúng được áp dụng theo thứ tự, và cùng một tùy chọn sẽ bị preset phía sau ghi đè preset phía trước
  • Nếu đặt ALLOW_YTDL_OPTIONS_OVERRIDEStrue, trường JSON nhập tự do “Custom yt-dlp Options” sẽ xuất hiện trong UI
  • Override theo từng lượt tải mặc định bị vô hiệu hóa
  • Khi bật tính năng này, người truy cập UI có thể cung cấp tùy chọn API yt-dlp tùy ý; tùy theo tùy chọn, có thể thực thi lệnh tùy ý bên trong container, vì vậy chỉ nên kích hoạt trong môi trường đáng tin cậy
  • MeTube ép buộc hành vi extract_flat, noplaylist riêng trong bước lấy metadata ban đầu, và preset không thể ghi đè các khóa của bước này

Cookie, tích hợp trình duyệt, chạy nhanh

  • Khi cần tải các video bị hạn chế hoặc riêng tư, có thể dùng cookie trình duyệt
    • Xuất cookie thành cookies.txt bằng tiện ích mở rộng Firefox hoặc Chrome
    • Tải lên bằng Upload Cookies trong Advanced Options của MeTube
    • Xóa cookie đã tải lên bằng Delete Cookies trong cùng phần
  • Tiện ích mở rộng trình duyệt cho phép nhấp chuột phải trên video để gửi trực tiếp sang MeTube
    • Để dùng trên trang HTTPS, instance MeTube phải nằm sau reverse proxy HTTPS
    • Tiện ích mở rộng gửi yêu cầu từ origin chrome-extension://... hoặc moz-extension://..., nên cần cấu hình CORS_ALLOWED_ORIGINS=*
  • Có thể cài tiện ích Chrome từ Google Chrome Webstore hoặc cài từ mã nguồn
  • Có thể cài tiện ích Firefox từ Firefox Addons hoặc dùng mã nguồn
  • iOS Shortcut có thể gửi URL sang MeTube từ menu chia sẻ của Safari
  • Bookmarklet gửi trang web hiện đang mở sang MeTube; trên trang HTTPS, MeTube phải được cấu hình HTTPS hoặc nằm sau reverse proxy HTTPS
  • Bookmarklet gửi yêu cầu cross-origin từ origin của trang hiện tại sang MeTube, nên cần thêm origin của trang sẽ dùng vào CORS_ALLOWED_ORIGINS
  • MeTube extension cho Raycast cho phép thêm video trực tiếp từ Raycast

Web server, HTTPS, reverse proxy

  • Các thiết lập liên quan đến web server được điều chỉnh bằng biến môi trường
    • Giá trị mặc định của HOST0.0.0.0
    • Giá trị mặc định của PORT8081
    • URL_PREFIX dùng để triển khai ở đường dẫn con phía sau reverse proxy
    • PUBLIC_HOST_URLPUBLIC_HOST_AUDIO_URL thay đổi URL cơ sở của liên kết tải tệp đã hoàn tất
  • Nếu đặt HTTPStrue và chỉ định CERTFILE, KEYFILE, MeTube sẽ chạy ở chế độ HTTPS
  • Reverse proxy có thể được dùng để kết thúc HTTPS hoặc cho mục đích xác thực
  • Image linuxserver/swag bao gồm các đoạn cấu hình subfolder, subdomain cho MeTube và cấu hình xác thực Authelia
  • Ví dụ NGINX proxy đường dẫn /metube/ tới http://metube:8081, đồng thời đặt các header UpgradeConnection để WebSocket hoạt động
  • Cũng có ví dụ reverse proxy cho Apache và Caddy

Cập nhật, khắc phục sự cố, phát triển cục bộ

  • MeTube phụ thuộc vào yt-dlp, và do layout của các trang video thay đổi, yt-dlp cần được cập nhật thường xuyên
  • Khi có bản phát hành ổn định mới của yt-dlp, image Docker mới của MeTube sẽ được phát hành tự động
  • Có thể dùng watchtower để giữ container luôn ở trạng thái mới nhất
  • Để theo kênh nightly của yt-dlp, đặt thời điểm thực hiện nâng cấp hằng ngày và khởi động lại MeTube trong YTDL_NIGHTLY_UPDATE_TIME theo định dạng HH:MM
  • Với các vấn đề về xác thực, hậu xử lý, quyền, YTDL_OPTIONS, nên debug trực tiếp trong yt-dlp trước, rồi đưa các tùy chọn hoạt động được sang MeTube
  • Build và chạy cục bộ cần Node.js 22+Python 3.13
  • UI được build bằng pnpm; cài dependency Python bằng uv sync, rồi chạy bằng uv run python3 app/main.py
  • Image Docker có thể được build cục bộ bằng docker build -t metube ., và UI cũng được build trong quá trình này

1 bình luận

 
GN⁺ 2024-07-30
Ý kiến trên Hacker News
  • Tube Archivist cũng đáng để cân nhắc. Nếu chỉ định tải vài video thì có vẻ hơi quá, nhưng tôi đang dùng nó để lưu trữ và lập chỉ mục các kênh công nghệ mình thích
    Nó cho phép tìm kiếm toàn văn và metadata không chỉ trên bản chép lời/phụ đề mà còn cả bình luận, tiêu đề và mô tả, và bực mình thay là nó tốt hơn rất nhiều so với thứ Alphabet cung cấp
    https://www.tubearchivist.com/

    • Khi xem TubeArchivist, tôi không thích việc nó cần 3 container. Sau đó tôi tìm thấy Pinchflat trên subreddit selfhosted, nó chạy trong một container duy nhất nên dễ triển khai và đến giờ vẫn hoạt động tốt
      https://github.com/kieraneglin/pinchflat
    • Tôi muốn tránh cái này. Cách đặt tên tệp của nó dựa trên giả định là có cơ sở dữ liệu tồn tại
      Nếu là kho lưu trữ tạm thì còn hiểu được, nhưng với một công cụ tự gọi mình là phần mềm “lưu trữ”, thì nó phải giả định rằng chính nó có thể không tồn tại lâu hơn dữ liệu mà nó định bảo tồn
      Tôi đã kỳ vọng nó giống một bản clone PeerTube có chức năng tải xuống, nhưng xem kết quả xong thì cụt hứng, và việc gắn các cấu hình cùng script thông minh vào yt-dlp mới là cách làm công việc lưu trữ cho ra hồn
    • Google sẽ không bao giờ tạo điều kiện để người ta dùng sản phẩm của họ theo cách có cấu trúc và nâng cao một cách thuận tiện. Cách đó quá có lợi cho người dùng và trao quá nhiều quyền kiểm soát cho họ. Google ghét điều đó
    • Hôm nay còn có một lựa chọn khác đã được đăng trên trang chủ: Yark: YouTube Archiver with Offline UI
      https://news.ycombinator.com/item?id=41100820
    • Tôi đã nghĩ đến chuyện chuyển sang Tube Archivist từ lâu, nhưng tôi có vài TB video YouTube đã gom bằng TubeSync, nên không muốn tải lại
      May là tôi có chuỗi định dạng đã dùng khi lưu tên tệp, và vì TubeSync dùng backend Django và PostgreSQL nên có lẽ vẫn nối lại được với YouTube ID. Dù vậy việc migration vẫn trông như một cơn ác mộng thực sự
  • Thứ tôi thật sự muốn là YouTube TiVo
    Tôi có khoảng 100 kênh mà mình gần như theo dõi như một kiểu tín ngưỡng nhưng lại đăng video rất thưa, và tôi tuyệt đối không muốn bỏ lỡ video của những kênh đó
    Tôi cũng không muốn phải bới trong hàng trăm video mới từ các kênh đăng ngày 4 lần để tìm ra 1-2 video mình thực sự muốn xem trên YouTube. Cuối cùng thì vẫn sẽ bỏ lỡ
    Sẽ rất tuyệt nếu có một feed ưu tiên chỉ gom những thứ tôi thực sự muốn xem hoặc cần xem, và còn tốt hơn nữa nếu có thể tải hết về để xem qua DLNA
    Giúp chúng ta không bỏ lỡ thứ mình thích không phải là cách YouTube vận hành. Cách YouTube vận hành là bắt bạn xem những video 3 phút bị kéo dài thành 18-22 phút, đồng thời trói feedback ngay trước mặt bạn

    • Chẳng phải đăng ký kênh YouTube là giải quyết được chuyện đó sao? Chỉ cần đăng ký 100 kênh đó và bookmark trang đăng ký kênh là bạn sẽ có một feed ưu tiên chỉ gồm những thứ mình muốn xem
      Nếu bạn không muốn tạo tài khoản thì cũng được, khi đó NewPipe có thể phù hợp hơn, nhưng YouTube vẫn có một trang riêng hiển thị video từ các kênh bạn tự chọn theo thứ tự thời gian, nên nói rằng “giúp chúng ta không bỏ lỡ thứ mình thích không phải là cách YouTube vận hành” thì hơi lạ
    • NewPipe rất hợp cho mục đích này. Nếu bỏ cột “Default Kiosk” khỏi nội dung trang chính và chỉ để lại “What's New”, bạn sẽ chỉ thấy video từ các kênh đã đăng ký. Phần đăng ký của NewPipe hoàn toàn không tích hợp với tài khoản Google
    • Tôi nhớ là YouTube vẫn dùng RSS. Bạn có thể thử cách đó
    • Tôi đang dùng Invidious cho mục đích này. Nó có feed ưu tiên chỉ dành cho các kênh đã đăng ký nên rất ổn
      Khả năng khám phá nội dung không tốt lắm, nhưng nếu đó không phải use case bạn cần thì đáng để thử
    • Có tiện ích fraidycat được tạo ra chính xác để làm việc đó
      https://fraidyc.at/
  • Có một điều tôi không hiểu. Tại sao phải host trên server? Chẳng phải chỉ cần là một ứng dụng độc lập chạy trên Windows/Linux/macOS là được sao?
    Gần đây tôi mới bắt đầu dùng yt-dlp và đã nghĩ đến việc thử làm một ứng dụng đơn giản. Có đáng để làm không? Đã có sẵn lựa chọn thay thế kiểu này chưa?

    • Nếu muốn, một thiết bị Windows/Linux/OSX hoặc máy ảo/container chạy trên đó đều có thể trở thành server. Làm vậy thì bên phát triển không cần phải làm riêng UX cho web và UX native
      Nhiều người chạy ứng dụng self-host trên server bên ngoài, homelab, hoặc kết hợp cả hai, rồi cấu hình tài nguyên đó như một hạ tầng có sẵn backup, v.v. Nếu PC/laptop/tablet/điện thoại chỉ là client hoặc cache tương đối đơn giản, thì khi bị mất hay hỏng chỉ cần lấy lại nội dung cục bộ đã đồng bộ với server, nên việc thay thế sẽ dễ hơn. Đây là một trong những lý do kiểu self-host này được ưa chuộng
      Tôi từng thấy vài ứng dụng desktop bọc quanh yt-dlp. Tôi chưa trực tiếp dùng nên khó nói về độ ổn định hay độ tin cậy, nhưng trừ khi bạn muốn tự làm cho vui, có lẽ nên tìm kiếm trước. Có thể thứ bạn muốn đã tồn tại rồi
    • Celluloid sẽ tự động dùng yt-dlp để stream khi bạn yêu cầu mở một URL được hỗ trợ. Parabolic là công cụ tải xuống chuyên dụng dùng yt-dlp
      https://flathub.org/apps/details/io.github.celluloid_player....
      https://flathub.org/apps/org.nickvision.tubeconverter
    • Nếu chỉ tải video YouTube thì thậm chí không nhất thiết phải dùng yt-dlp. Có thể làm với ít mã và độ phức tạp hơn nhiều, và tôi đang dùng một chương trình C rất nhỏ. Một shell script nhỏ cũng hoạt động đủ tốt
      Điều không ai nhắc tới là yt-dlp hiện không còn tải được itag 22, còn itag 18 thì đã bị giới hạn tốc độ. Vì vậy yt-dlp phải tải riêng file âm thanh và file video rồi ghép lại bằng ffmpeg
      Doanh thu quảng cáo YouTube vừa hụt ước tính đồng thuận. Khả năng truy cập video YouTube có thể sẽ còn tệ hơn trong tương lai
      Nếu bạn không có thói quen chọn định dạng cụ thể thì rất có thể sẽ không nhận ra điều này. Ví dụ, có những người suốt nhiều năm chỉ dùng itag 18 và 22
    • Cũng có Freetube
      https://freetubeapp.io/
    • Có thể bạn muốn tải và lưu video trên NAS hoặc home server thay vì thiết bị đang dùng
      Một web app được Docker hóa sẽ dễ phát triển và bảo trì hơn rất nhiều so với việc làm riêng client desktop/mobile cho Windows, macOS, Android, iOS và Linux
  • Sẽ hay nếu có giao diện tích hợp với Jellyfin. Kiểu như tìm kiếm YouTube, tải bằng yt-dlp, rồi stream qua Jellyfin mà không có quảng cáo

    • Tôi gần như đang dùng theo cách đó, chỉ là bước yt-dlp vẫn còn thủ công. Nếu có plugin Jellyfin thì sẽ rất tuyệt
  • Khá ngầu đấy. Hiện tôi đang dùng https://cobalt.tools và cái này cũng ổn

    • Hoàn hảo. Nó có tùy chọn tải định dạng audio gốc của YouTube mà không chuyển mã sang mp3
  • Tôi mới biết Brave trên iOS có nút playlist cho phép tải video YouTube về lưu trên thiết bị. Có PiP, phát offline và không quảng cáo
    Nó dùng giấy phép mở dựa trên backend iOS của Mozilla, nên tôi thắc mắc vì sao không có nhiều ứng dụng làm như vậy hơn. Họ đã tìm ra cách để Apple chấp nhận, và CEO cũng từng đăng ở đây để bảo vệ rằng kỹ thuật đó là hợp lệ
    Về bản chất, nó chỉ hoạt động sau khi tải video bên trong website YouTube thông thường, và giống như một nút chế độ đọc áp dụng cho nội dung video, không chỉ riêng YouTube mà cho bất kỳ nội dung video nào

  • Tôi hơi ngạc nhiên vì có nhiều công cụ mirror YouTube đến vậy. Nếu dùng mấy thứ này thì lý do gì để tải xuống/lưu trữ video thay vì cứ stream trực tiếp từ YouTube?
    Tôi hiểu là đôi khi nên lưu lại để phòng lúc bị xóa khỏi YouTube, nhưng với tôi thì chuyện đó rất hiếm. Xem xong là thôi, sau này không xem lại được cũng không ảnh hưởng gì mấy

    • Có nhiều lý do để tải xuống hoặc lưu trữ thay vì stream từ YouTube
      Thứ nhất, loại bỏ quảng cáo là lý do khá lớn với nhiều người
      Thứ hai, như đã viết ở trên, nếu video hoặc cả kênh bị gỡ vì khiếu nại bản quyền hay báo cáo khác, thì bạn sẽ không thể stream lại được nữa. Tùy vào nội dung bạn xem, điều này có thể quan trọng với ai đó hơn nhiều so với bạn
      Thứ ba, có thể tải xuống để xem offline. Ứng dụng YouTube chính thức cũng làm được, nhưng phải trả phí Premium, mức giá đó có vẻ quá đáng, và vẫn bị ảnh hưởng bởi vấn đề bị xóa
      Thứ tư là lập chỉ mục cục bộ. Nếu bạn muốn tham chiếu lại hoặc chia sẻ video sau này, thì việc tự sắp xếp theo cấu trúc của mình có thể tiện hơn là giữ bookmark các bản sao trên YouTube hoặc phải tìm kiếm lại mỗi lần
      Có thể là sự kết hợp của các lý do trên, và cũng có thể còn những lý do khác mà tôi chưa nghĩ tới hoặc không nhớ ra
    • Với tôi thì cũng giống lý do người ta từng dùng VCR. Không phải để “vi phạm bản quyền”, mà là để lưu lại xem sau hoặc xem khi không có mạng hay mạng chậm
      Phần lớn những gì tôi tải về là xem một lần rồi xóa
    • Ở mạng gia đình có trẻ em, chúng tôi chặn YouTube và thay vào đó cho truy cập DadTube do mình tự tuyển chọn
    • Bạn nói khó hiểu vì sao công cụ này tồn tại, nhưng lại vừa tự nêu ra chính lý do lớn nhất khiến nó cần phải tồn tại
      Ngoài ra cũng có lúc không thể stream YouTube. Mạng bị đứt, đang dùng gói di động quốc tế quá đắt, hoặc đơn giản là muốn bỏ mấy quảng cáo tệ hại
    • giới hạn mức sử dụng băng thông. Nếu bạn muốn bật lặp đi lặp lại cùng một playlist MV thì sẽ tốn kha khá dung lượng giới hạn
  • Liên quan: Yark: YouTube Archiver with Offline UI
    https://news.ycombinator.com/item?id=41100820

  • Nếu gói một trong các máy chủ dựa trên yt-dlp bằng một công cụ tạo image kiểu Pi-hole thật đơn giản cùng với một ứng dụng client frontend phát lại đủ tốt, thì theo tôi nó có thể bùng nổ mạnh, giống như cách Pi-hole đã lan rộng tới những người dùng ít thiên về kỹ thuật
    Kiểu như mua một chiếc Raspberry Pi, ghi image vào thẻ microSD, chọn các kênh YouTube yêu thích, cài ứng dụng client, rồi toàn bộ nội dung YouTube bạn thích sẽ được cung cấp cục bộ mà không có quảng cáo

  • Hiện tại tôi đang dùng TubeSync. Tính năng thì đơn giản và cũng khá nhiều lỗi, nhưng với tôi nó hoạt động đủ tốt
    Việc cần làm chỉ là đăng ký theo dõi một kênh hoặc playlist, tải video xuống một đường dẫn cụ thể, và mỗi ngày kiểm tra nội dung mới một lần
    UX cần thiết chỉ nằm ở phần thiết lập kênh; sau đó chỉ cần lưu file rồi để Plex tự xử lý. Có ai biết lựa chọn nào tốt hơn không?