Video Uploads với Rails and Ziggeo
Bài đăng này đã không được cập nhật trong 7 năm
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 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-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