Tải và upload video tự động lên youtube với youtube-dl và youtube-api - Bài 2 : Upload video với Yt - The reliable YouTube API Ruby client

Ở bài trước https://viblo.asia/nhs3108/posts/gEmzOxEAGpv, chúng ta đã cùng tìm hiểu về youtube-dl - một chương trình dòng lệnh sử dụng để download video từ YouTube và khá nhiều trang nổi tiếng khác như Instagram , MTV, Soundcloud và Redtube, thậm chí là Facebook .v.v, đồng thời chúng ta cũng cùng nhau xây dựng một web application có khả năng nhận URL hay ID của video youtube để download bằng Ruby On Rails, với thư viện youtube-dl.rbđược cung cấp cho ngôn ngữ lập trình ruby. Ở bài này, chúng ta sẽ tìm hiểu về Yt - The reliable YouTube API Ruby client, có thể coi như một thư viện của ruby, được xây dựng để làm việc với youtube api, cung cấp khả năng tìm kiếm, lấy thông tin và đặc biệt là upload video - thứ mà chúng ta sẽ tìm hiểu ở bài này.

Tham khảo Github repository của yt tại https://github.com/Fullscreen/yt Documentation http://fullscreen.github.io/yt/videos.html

1. Cài đặt

Tại terminal, bạn sử dụng lệnh

gem install yt

Hoặc nếu bạn đã cài đặt từ trước, bạn có thể sử dụng lệnh

gem update yt

để chắc chắn rằng bạn đang sử dụng phiên bản mới nhất.

Để khai báo rằng chúng ta sẽ sử dụng yt gem vào ứng dụng RoR, ở Gemfile, bạn thêm đoạn sau

gem 'yt', '~> 0.29.1'

Ok. Vây là xong.

2. Sử dụng

Nếu các bạn có theo dõi bài viết thứ nhất của mình, chắc hẳn các bạn sẽ để ý đoạn code trong DownloadsController

class DownloadsController < ApplicationController
  def index
    
  end

  def new
    
  end

  def create
    video_url = params[:video_url] # Lấy url từ form gửi lên
    video = Yt::Video.new url: video_url # Lấy thông tin video từ url
    YoutubeDL.download video_url, output: "videos/#{video.id}" # Lưu video từ url, đặt video vào thư mục video với tên là id của video đó trên youtube
    redirect_to downloads_path # Trở về trang index
  end
end

video = Yt::Video.new url: video_url chính là mình đang sử dụng thư viện yt mà chúng ta đa nhắc đến trong bài viết này để lấy thông tin video từ URL gửi lên từ form.

2.1 Cấu hình

Đầu tiên, hay truy cập https://console.developers.google.com/apis/credentials và tạo API keys cùng với OAuth 2.0 client IDs giống như mình nhé

Tiếp tục truy cập https://developers.google.com/oauthplayground/ để lấy refresh token (bằng cách này, chúng ta sẽ không phải xác thực thủ công mỗi lần authenticate nữa) Mình hướng dẫn các bước lấy youtube refresh token nhé. Các bạn chỉ cần follow theo hình thôi 😃 Rồi điền Client ID và Client Secret vào nhé Đánh tick như mình và nhấn vào button Authorize APIs

Tiếp theo nó sẽ hiện cho bạn 1 dialog Bạn chọn kênh mà đó là target channel bạn upload video Và đồng ý cho phép Google sẽ chuyển bạn tới Step 2, Chọn exchange và nhận refresh token

2.2 Viết code

OK. Giờ chúng ta đã đầy đủ những thông tin quan trọng để config cho Yt Đây là code trong ApplicationController của mình. Các bạn tham khảm và điền các thông tin của bạn vào nhé

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :null_session

  YOUTUBE_CREDENTIAL = {
  	api_key: "Your API Key",
  	client_id: "Your Client ID",
  	client_secret: "Your Client Secret",
  	refresh_token: "Your Refresh Token",
  	redirect_url: "http://localhost:8080/youtube/oauth2callback"
  }

  Yt.configure do |config|
    config.log_level = :debug
  end
  Yt.configuration.client_id = YOUTUBE_CREDENTIAL[:client_id]
  Yt.configuration.client_secret = YOUTUBE_CREDENTIAL[:client_secret]

  def account
    @account ||= Yt::Account.new refresh_token: YOUTUBE_CREDENTIAL[:refresh_token]
  end

  def output_video name
    "public/videos/#{name}"
  end
end

Mình giải thích chút nhé. Đoạn

 YOUTUBE_CREDENTIAL = {
  	api_key: "Your API Key",
  	client_id: "Your Client ID",
  	client_secret: "Your Client Secret",
  	refresh_token: "Your Refresh Token",
  	redirect_url: "http://localhost:8080/youtube/oauth2callback"
  }

là mình tạo ra 1 Hash có chứ các thông tin về kênh youtube và config nó bằng

  Yt.configuration.client_id = YOUTUBE_CREDENTIAL[:client_id]
  Yt.configuration.client_secret = YOUTUBE_CREDENTIAL[:client_secret]
  def account
    @account ||= Yt::Account.new refresh_token: YOUTUBE_CREDENTIAL[:refresh_token]
  end

Định nghĩa đối tượng account xác thực để thực hiện cho các công việc tiếp theo.

Rồi nhé.

Trong UploadsController mình (mình đặt tạm tại action new nhé)

def new
    account.upload_video "URL to video file", title: 'My video'
    redirect_to uploads_path
end

Thế thôi, rất đơn giản. Chi tiết tham khảo thêm tại http://fullscreen.github.io/yt/videos.html Giờ thì bạn hãy tùy biến theo cách của bạn thôi. Dưới đây mình sẽ hướng dẫn sử dụng Sidekiq để thực hiện việc upload

3. Sử dụng Sidekiq + Redis chạy Background Job để upload video

Ok. Nếu bạn thử những gì mình hướng dẫn ở trên, bạn sẽ thấy rằng thật phiền phức làm sao nếu như đó là 1 video dài bởi bạn sẽ mất khá nhiều time chờ hàm upload xử lý xong để trở về trang index, thậm chí bạn chẳng thể truy cập thêm request nào trong ứng dụụng web của bạn. Vậy thì hãy nghĩ tới việc xử lý upload 1 cách bất đồng bộ nhé. Sidekiq, Redis là gì và cài đặt ra sao? Các bạn hãy search thêm trên google nhé. Một tutorial gợi ý cho bạn đây http://railscasts.com/episodes/366-sidekiq

Thêm gem nhé

gem 'sidekiq'

Ok. Tại terminal, chạy

bundle

bundle exec sidekiq

để khởi động sidekiq

Xây dựng DownloadWorker như mình nhé

class UploadsWorker
  include Sidekiq::Worker
  sidekiq_options queue: "high"
  
  def perform account, url, video_name
    # Tham kháo documentation tại http://fullscreen.github.io/yt để hiểu thêm về hàm upload_video
    # Bạn có thể set title, tag, description các kiểu cho video nhé. 
    account.upload_video "url", title: video_name
  end
end

Update lại hàm new của UploadsController

def create
    UploadsWorker.perform_async account, video_name # Chạy hàm perform của UploadWorker 1 cách bất đồng bộ
    redirect_to uploads_path
 end

Ok vậy là đã xong. Thanks for your time! Tham thảo sample tại https://github.com/nhs3108/DownUpYoutubeVideo