0

Video Uploads với Rails and Ziggeo

I. Giới thiệu

Youtube là một trong những trang chia sẻ, lưu trữ và quản lý video. Trong bài viết này, chúng ta sẽ tìm hiểu về nền tảng hỗ trợ video khác là Ziggeo. Nó cung cấp API cho phép lưu trữ, quản lý video cùng với khả năng nhúng vào trang web. Ngoài ra, nó còn cung cấp một vài tính năng như bình luận, quản lý, quyền truy cập callback, tích hợp với bên thứ ba, ... Ziggeo hiện đang cung cấp bản miễn phí cho phép upload video với tổng thời gian là 100 phút.

II. Quản lý video với Ziggeo

1. Cài đặt gem

Thêm gem Ziggeo vào Gemfile để làm việc với Ziggeo API.

Ngoài ra có thể gem dotenv-rails để quản lý lưu trữ biến môi trường

Ta có thể sử dụng devise để hỗ trợ quản lý authenticate, khi đó thêm

  # application_controller.rb
  before_action :authenticate_user!

2. Cài đặt Ziggeo

Đăng ký tài khoản Ziggeo, tạo một ứng dụng, khi đó, Ziggeo sẽ cung cấp 3 khóa sau, thêm chúng vào file .env

# File .env
ZIGGEO_KEY=123
ZIGGEO_SECRET=abc
ZIGGEO_ENCRYPTION=345

Nhúng CSS và Javascirpt vào app:

# views/layouts/application.html.erb

<link rel="stylesheet" href="//assets-cdn.ziggeo.com/v1-stable/ziggeo.css" />
<script src="//assets-cdn.ziggeo.com/v1-stable/ziggeo.js"></script>
<script>ZiggeoApi.token = '<%= ENV['ZIGGEO_KEY'] %>';</script>

3. Upload và quản lý video

sử dụng thẻ ziggeo để tương tác và trang web với các options:

# views/videos/new.html.erb
<ziggeo ziggeo-width="320" ziggeo-height="240" ziggeo-limit="60" ziggeo-perms="allowupload"></ziggeo>

Trong đó:

  • ziggeo-width và ziggeo-height là kích thước khung hiển thị video trên page
  • ziggeo-limit: giới hạn thời gian video chạy
  • ziggeo-perms = allowupload : cho phép người dùng upload video đã có sẵn

các video đã được upload sẽ được hiển thị trong tab videosModeration trên dashboard của ziggeo. Tại đây có đẩy đủ thông tin liên quan đến video và các sự kiện video sử dụng cho trang web

Để nhúng video vào trong page ta sử dụng thuộc tính ziggeo-video với gía trị uid của video đó

<ziggeo ziggeo-video='123abc' ziggeo-width="320" ziggeo-height="240" ziggeo-popup></ziggeo>

Thuộc tính ziggeo-popup cho phép video chạy trong popup

4. Xử lý sự kiện

Ziggeo cung cấp đầy đủ các sự kiện Javascript mà ta có thể sử dụng như play, pause, uploaded, camera_nosignal, ...

Nếu muốn tạo thanh hiển thị thời gian xử lý video upload, ta có thể sử dụng event upload_progress, hiển thị bao nhiêu bytes được upload

# javascripts/videos.coffee
jQuery(document).on 'turbolinks:load', ->
  ZiggeoApi.Events.on "upload_progress", ( uploaded, total, data ) ->
    $('progress').removeClass('hidden-xs-up').attr 'value', (uploaded / total) * 100

ZiggeoApi là biến toàn cục có thể sử dụng được khi JS Ziggeo được load

Nếu muốn chuyển hướng trang web sau khi video được upload:

ZiggeoApi.Events.on "submitted", ( data ) -> window.location.href = '/'

Để biết thêm chi tiết, ta có thể tìm hiểu tại docs

5. Truy vấn API

Muốn lấy danh sách video được upload:

# videos_controller.rb
def index
  ziggeo = Ziggeo.new(ENV['ZIGGEO_KEY'], ENV['ZIGGEO_SECRET'], ENV['ZIGGEO_ENCRYPTION'])
  @videos = ziggeo.videos.index
  # biến @videos chứa mảng hash lưu trữ video uid và các thông tin meta khác
end

Hiển thị video trong index:

# views/videos/index.html.erb
<h1>Videos</h1>

<%= link_to 'Add video', new_video_path %>

<%= render partial: 'video', collection: @videos, as: :video %>

# views/videos/_video.html.erb
<div class="card">
  <div class="card-block">
    <ziggeo ziggeo-video='<%= video['token'] %>'
            ziggeo-width="320"
            ziggeo-height="240" ziggeo-popup>
    </ziggeo>
</div>

6. Gắn video với user

Thêm trường uid vào user để xác định định danh cho user:

# models/user.rb
before_create -> { self.uid = generate_uid }

private

def generate_uid
  loop do
    uid = Digest::MD5.hexdigest(self.email + self.created_at.to_s + rand(10000).to_s)
    return uid unless User.exists?(uid: uid)
  end
end

Khi đó muốn gắn quyền sở hữu cho video ta sử dụng thuộc tính ziggeo-tags

# views/videos/new.html.erb
<ziggeo ziggeo-limit="60" ziggeo-width="320" ziggeo-height="240" ziggeo-perms="allowupload" ziggeo-tags="<%= current_user.uid %>"></ziggeo>

Trong controller, ta lấy danh sách video theo tags

# videos_controller.rb
def index
  ziggeo = Ziggeo.new(ENV['ZIGGEO_KEY'], ENV['ZIGGEO_SECRET'], ENV['ZIGGEO_ENCRYPTION'])
  @videos = ziggeo.videos.index(tags: current_user.uid)
end

Tuy nhiên có một vấn đề là Ziggeo API không thể lấy được các video được xác nhận với người quản trị. Có một cách để giải quyết là sử dụng server callback để lưu trữ thông tin video vào trong database.

Ta cần tạo model và bảng Video để lưu thông tin video

rails g model Video user:belongs_to uid:string duration:decimal ziggeo_created_at:datetime approved:boolean

Chạy rake db:migrate để tạo bảng Video

Thêm video_callback path

# config/routes.rb
namespace :api do
  resources :video_callbacks, only: [:create]
end

Khi có một event mới, params event_type có giá trị là video_ready, khi đó trong params sẽ chứa thông tin của video, ta sẽ lưu thông tin này vào trong database

class Api::VideoCallbacksController < ActionController::Base
  def create
    type = params['event_type']
        respond_to do |format|
          @result = if type == 'video_ready'
                      Video.from_api(params['data']['video'])
                    end
          format.html { @result ? head(:no_content) : head(500) }
        end
  end
end

trong đó, class method from_api được định nghĩa trong video model

# models/video.rb
def self.from_api(data)
  user = User.find_by(uid: data['tags'][0])
  video = user.videos.find_or_initialize_by(uid: data['token'])
  video.ziggeo_created_at = Time.at(data['created'])
  video.duration = data['duration']
  video.save
end

Khi 1 video được xác nhận hay hủy bỏ bởi người quản trị, thì một event sẽ được gửi về với type là video_approve, khi đó ta tìm kiếm video trong db dựa vào uid và gán cho approved là true

# controllers/api/video_callbacks_controller.rb
def create
  type = params['event_type']
  respond_to do |format|
    @result = if type == 'video_ready'
                Video.from_api(params['data']['video'])
              else
                if type == 'video_approve'
                  video = Video.find_by(uid: params['data']['video']['token'])
                  video.approve! if video
                else
                  true
                end
              end
    format.html { @result ? head(:no_content) : head(500) }
  end
end

Với thông tin video meta đã được lưu vào trong database, thì ta có thể trả về danh sách video dựa theo truy vấn database

# videos_controller.rb
def index
  @videos = current_user.videos.where(approved: true)
end

khi đó trong view sẽ được sửa lại

# views/videos/_video.html.erb
<div class="card">
  <div class="card-block">
    <ziggeo ziggeo-video='<%= video.uid %>'
            ziggeo-width="320"
            ziggeo-height="240" ziggeo-popup>
    </ziggeo>
    <p>
      <strong>Duration:</strong> <%= video.duration %>s<br>
      <strong>Created:</strong> <%= video.ziggeo_created_at  %>
    </p>
  </div>
</div>

III. Kết luận

Trên đây là một vài tính năng cơ bản mà Ziggeo hỗ trợ khi xử lý video trên web app

Ngoài ra, còn có thêm nhiều tính năng hữu ích khác, bạn có thể tham khảo dựa theo đường dẫn docs

Cảm ơn vì sự theo dõi của bạn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí