签名请看: https://blog.csdn.net/tang05709/article/details/88366228
module Aliyun
class AliyunVideoAchieve < AliyunSign
def initialize
@access_key_id = Rails.configuration.application['ALIYUN_OSS_ACCESS_KEY_ID']
@access_key_secret = Rails.configuration.application['ALIYUN_OSS_ACCESS_KEY_SECRET']
@send_url = 'http://vod.cn-shanghai.aliyuncs.com'.freeze
end
'''
获取视频上传地址和凭证,并创建视频信息
title: 视频标题
file_name: 视频源文件名必须带扩展名
options: FileSize: 视频文件大小; Description: 视频描述,长度不超过1024个字节, CoverURL:自定义视频封面URL地址
options: CateId:视频分类ID;Tags:视频标签,多个用逗号分隔;TemplateGroupId:转码模板组ID; UserData:自定义设置,为JSON字符串,支持消息回调等设置
options: StorageLocation:存储地址。当不为空时,会使用该指定的存储地址上传视频文件
return RequestId:请求ID; VideoId:视频ID;UploadAddress:上传地址;UploadAuth:上传凭证
'''
def create_upload_video(title, file_name, options = {})
#http://vod.cn-shanghai.aliyuncs.com/?Action=CreateUploadVideo&Title=exampleTitle&FileName=example.avi&FileSize=10485760&Format=JSON&<公共参数>
#Action 系统规定参数。取值:CreateUploadVideo
#Title视频标题,长度不超过128个字节 utf8
#FileName视频源文件名必须带扩展名,且扩展名不区分大小写。MP4,3GP,MPEG,AVI,FLV,m3u8
#FileSize 视频文件大小
# 返回 RequestId:请求ID, VideoId:视频ID, UploadAddress:上传地址, UploadAuth:上传凭证
param = {
Action: 'CreateUploadVideo',
Title: title,
FileName: file_name,
AccessKeyId: @access_key_id
}
key = @access_key_secret + '&'
options = create_sign_url("POST", param, key, 'video')
result = Faraday.post(@send_url, options)
res = JSON.parse(result.body)
if res["UploadAddress"].blank?
[]
else
res
end
end
'''
刷新视频上传凭证
video_id 视频ID
'''
def refresh_upload_video(video_id)
# http://vod.cn-shanghai.aliyuncs.com/?Action=RefreshUploadVideo&VideoId=93ab850b4f6f44eab54b6e91d24d81d4&Format=JSON&<公共参数>
# Action 系统规定参数。取值: RefreshUploadVideo
# VideoId 视频ID
# 返回 RequestId:请求ID, UploadAddress:上传地址, UploadAuth:上传凭证
param = {
Action: 'RefreshUploadVideo',
VideoId: video_id,
AccessKeyId: @access_key_id
}
key = @access_key_secret + '&'
options = create_sign_url("POST", param, key, 'video')
result = Faraday.post(@send_url, options)
res = JSON.parse(result.body)
if res["UploadAddress"].blank?
[]
else
res
end
end
end
end
表单
class VideoMediaInput < SimpleForm::Inputs::Base
def input(wrapper_options = nil)
# 获取data属性
data = options[:data] || {}
class_name = self.class.name.underscore.dasherize
# [link, spinner, hidden, list_panel].join&.html_safe
template.content_tag(:div, class: "media #{class_name} video-media-picker") do
# 获取值
value = object.send(attribute_name)
value_v = value.to_json if value.is_a?(Array)
# 上传按钮
picker_button = content_tag :div,
'',
class: 'button media-picker-button',
id: attribute_name.to_s + '_uploader',
data: data
template.concat picker_button
# file表单
picker_file = content_tag :input,
'',
class: "media-picker-file",
type: 'file',
accept: 'video/*'
template.concat picker_file
# 隐藏域
input_field = @builder.hidden_field(attribute_name, value: value_v)
template.concat input_field
end
end
end
前端
# 生成文件名称
random_string = () ->
chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
pwd = ''
for num in [1..28]
pwd += chars.charAt(Math.floor(Math.random() * chars.length))
return pwd
# 获取后缀并重新命名文件
get_new_file_name = (file) ->
pos = file.lastIndexOf('.')
new_file_name = ''
if (pos != -1)?
file_name = random_string()
suffix = file.substring(pos)
new_file_name = file_name + suffix
return new_file_name
# 获取凭证
get_video_sign = (title, file_name, uploadInfo, uploader) ->
$.post("/xxx",
{ title: title, 'file_name': file_name},
(data) ->
if(data)
# 从点播服务获取的uploadAuth、uploadAddress和videoId,设置到SDK里
uploader.setUploadAuthAndAddress(uploadInfo, data.UploadAuth, data.UploadAddress, data.VideoId)
)
# 刷新凭证
get_refresh_video_sign = (uploadInfo, uploader) ->
$.post("/xxx",
{ video_id: uploadInfo.videoId},
(data) ->
if(data)
uploader.setUploadAuthAndAddress(uploadInfo, data.UploadAuth, data.UploadAddress, uploadInfo.videoId)
)
# 超时刷新凭证
get_expired_video_sign = (videoId, uploader) ->
$.post("/xxx",
{ video_id: videoId},
(data) ->
if(data)
uploader.resumeUploadWithAuth(data.UploadAuth)
)
# 进度条
progress_template = (loadedPercent) ->
percentage = Math.ceil(loadedPercent * 100) + "%"
return "<div class='progress-box'><div class='progress'></div><div class='progress-value'>#{percentage}%</div></div>"
# 显示视频
success_template = (file_name) ->
return "#{file_name}上传成功,请等待转码,依据视频大小大约1-10分钟。"
# 上传失败
fail_template = () ->
return "<li>上传失败</li>"
$(document).on 'turbolinks:load', ->
upload_init = (el, video) ->
title = video.name
file_name = get_new_file_name(title)
uploader = new AliyunUpload.Vod({
# 阿里账号ID ,值的来源https://help.aliyun.com/knowledge_detail/37196.html
userId: "1663930772708781",
# 上传到点播的地域, 默认值为'cn-shanghai',//eu-central-1,ap-southeast-1
region: "cn-shanghai",
# 分片大小默认1M,不能小于100K
partSize: 1048576,
# 并行上传分片个数,默认5
parallel: 5,
# 网络原因失败时,重新上传次数,默认为3
retryCount: 3,
# 网络原因失败时,重新上传间隔时间,默认为2秒
retryDuration: 2,
# 开始上传
'onUploadstarted': (uploadInfo) ->
if (uploadInfo.videoId)
#如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
data = get_refresh_video_sign(uploadInfo, uploader)
else
#如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
data = get_video_sign(title, file_name, uploadInfo, uploader)
# 文件上传成功
'onUploadSucceed': (uploadInfo) ->
# 获取值
input_field = el.find('input[type=hidden]')
input_field.val(uploadInfo.videoId)
html = success_template(uploadInfo.object)
el.next('small').find('.image-list ul').html(html)
# 文件上传失败
'onUploadFailed': (uploadInfo, code, message) ->
html = fail_template()
el.next('small').find('.image-list ul').html(html)
# 文件上传进度,单位:字节
'onUploadProgress': (uploadInfo, totalSize, loadedPercent) ->
html = progress_template(loadedPercent)
el.next('small').find('.image-list ul').html(html)
# 上传凭证超时
'onUploadTokenExpired': (uploadInfo) ->
data = get_expired_video_sign(uploadInfo.videoId, uploader)
# 全部文件上传结束
'onUploadEnd': (uploadInfo) ->
console.log('onUploadEnd')
})
uploader.addFile(video, null, null, null, '')
uploader.startUpload()
$('.video-media-picker').each ->
el = $(this)
file_obj = $(this).find('.media-picker-file')
file_obj.change (event) ->
video = event.currentTarget.files[0]
if video.name != 'undefined' && video.size < 157286400
upload_init(el, video)
当然需要引入相应的js
把js加载下来放在app/assets/javascripts目录下, 然后引入
//= require aliyun_video/lib/es6-promise.min.js
//= require aliyun_video/lib/aliyun-oss-sdk-5.3.1.min.js
//= require aliyun_video/aliyun-upload-sdk-1.5.0.min.js