ruby on rails aliyun 视频点播上传

签名请看: 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 "
#{percentage}%
" # 显示视频 success_template = (file_name) -> return "#{file_name}上传成功,请等待转码,依据视频大小大约1-10分钟。" # 上传失败 fail_template = () -> return "
  • 上传失败
  • " $(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

     

    你可能感兴趣的:(ruby,on,rails)