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 ...
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-awidth="320" ziggeo-height="240" ziggeo-limit="60" ziggeo-perms="allowupload"></ziggeo>
Trong đó:
- ziggeo-awidth 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 videos và Moderation 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-awidth="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-awidth="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-awidth="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-awidth="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.