对于音频、视频等多媒体资源,七牛云也提供了丰富的处理指令,包含但不限于如下指令:html
本篇从获取音视频元信息入手,顺序讲解各个处理指令。编程
使用avinfo接口能够很是方便地获取一个音视频资源的相关元信息:json
http://<Bucket>.qiniudn.com/<Key>?avinfo 或 http://<Domain>/<Key>?avinfo
以美剧《黑名单》第1季第12集的预告片(flv资源)为例,在浏览器中打开以下URL:segmentfault
http://qiniu-developer.u.qiniudn.com/samples/黑名单-S01E12.flv?avinfo
将返回一个JSON格式组织的元信息对象:api
{ "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "codec_type": "video", "codec_time_base": "1001/60000", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 1280, "height": 720, ...省略过长内容... }, { "index": 1, "codec_name": "aac", "codec_long_name": "Advanced Audio Coding", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "mp4a", "codec_tag": "0x6134706d", "sample_fmt": "s16", "sample_rate": "44100", "channels": 2, ...省略过长内容... } ], "format": { "nb_streams": 2, "format_name": "mov,mp4,m4a,3gp,3g2,mj2", "format_long_name": "QuickTime/MPEG-4/Motion JPEG 2000 format", "start_time": "0.000000", "duration": "29.070000", "size": "8702170", "bit_rate": "2394818", "tags": { "major_brand": "mp42", "minor_version": "0", "compatible_brands": "isommp42", "creation_time": "2014-01-13 08:43:21" } } }
能够看到音频、视频和封装格式信息被准确地描述出来。浏览器
avthumb接口支持的基本音视频处理包括:七牛云存储
之前文的flv资源为例,若只想简单地转码为mp4格式,可使用以下URL达成目的:缓存
http://qiniu-developer.u.qiniudn.com/samples/黑名单-S01E12.flv?avthumb/mp4
接收到这样的请求后,七牛云将对指定资源执行实时转码操做,缓存结果后将新资源返回给请求端。点击查看转码效果。ruby
注意:服务器
上传时,经过在上传策略中指定persistentOps字段的值,能够触发七牛云对上传资源进行指定的数据处理。还能够同时指定persistentNotifyUrl字段的值,以便将持久化处理结果及时通知给业务端处理。
之前文的flv资源为例,若想预先转换成mp4格式并持久存储结果(计入存储空间),可使用如下两个Ruby程序来完成。
#!/usr/bin/env ruby # encoding : utf-8 # persistent_notify_server.rb require 'json' require 'xmlrpc/httpserver' class PersistentNotifyHandler @@count = 0 public def ip_auth_handler(io) # 任何请求都容许处理 return true end # ip_auth_handler def request_handler(request, response) # 读取请求报文 body = request.data.read_nonblock(65536) # 从新格式化JSON对象 json = JSON.generate( JSON.parse(body), { indent: ' ', object_nl: "\n", array_nl: "\n", } ) # 输出 puts json # 计数 @@count += 1 # 构造响应报文(可选) response.body = 'OK' end # request_handler def self.count() return @@count end # self.count end # PersistentNotifyHandler svr = HttpServer.new( PersistentNotifyHandler.new(), # 请求处理器 9090, # 端口 '0.0.0.0' # 监听IP ) svr.start while (PersistentNotifyHandler.count() == 0) puts 'waiting for notification...' sleep(60) end svr.shutdown
#!/usr/bin/env ruby # encoding : utf-8 # put_flv_file.rb require 'json' require 'net/http' require 'base64' require 'openssl' # 根据传入参数,构造一个上传策略(触发预转持久化处理) def put_policy(bucket, expires, persistentOps, persistentNotifyUrl) # 生成一个Hash对象 put_policy = Hash.new() # 仅指定目标存储空间,即“新增资源”语意: # 资源不存在则建立 # 资源已存在,且与上传内容不一致则失败 put_policy['scope'] = "#{bucket}" # 计算受权有效期截止时间,UNIX时间戳格式 put_policy['deadline'] = (Time.now() + expires).tv_sec() # 指定预转持久化处理的指令 put_policy['persistentOps'] = persistentOps # 指定预转持久化处理的结果通知URL put_policy['persistentNotifyUrl'] = persistentNotifyUrl # 序列化为JSON字符串 return JSON.generate(put_policy) end # put_policy # 根据传入的上传策略,生成对应的上传受权凭证 def upload_token(access_key, secret_key, put_policy) # 对上传策略作UrlSafe-Base64编码 encoded_put_policy = Base64.urlsafe_encode64(put_policy) # 使用SHA1做为HASH函数,生成签名 sign = OpenSSL::HMAC.digest( 'sha1', secret_key, encoded_put_policy ) # 对签名作UrlSafe-Base64编码 encoded_sign = Base64.urlsafe_encode64(sign) # 拼出上传受权凭证,以“:”做为分隔符 return "#{access_key}:#{encoded_sign}:#{encoded_put_policy}" end # upload_token BUCKET = 'qiniu-ts-demo' # 使用时请更换成真实的存储空间名 EXPIRES = 3600 ACCESS_KEY = 'MY_ACCESS_KEY' # 使用时请更换成真实的AccessKey SECRET_KEY = 'MY_SECRET_KEY' # 使用时请更换成真实的SecretKey PERSISTENT_OPS = 'avthumb/mp4' # 持久化处理指令 PERSISTENT_NOTIFY_URL = 'http://fake.com:9090' # 使用时请更换成真实的域名和端口 # 生成上传受权凭证 upload_token = upload_token( ACCESS_KEY, SECRET_KEY, put_policy( BUCKET, EXPIRES, PERSISTENT_OPS, PERSISTENT_NOTIFY_URL ) ) # 指定请求报文中的各个参数 file_name = '黑名单-S01E12.flv' # 使用时请更换成真实的文件 file_content = File.open(file_name, 'rb') do |fh| fh.read() end puts 'file size is %s' % file_content.size boundary = 'a-string-never-exists-in-the-uploading-file' # 生成请求报文体 req_body = <<HTTP_BODY --#{boundary} Content-Disposition: form-data; name="token" #{upload_token} --#{boundary} Content-Disposition: form-data; name="key" #{file_name} --#{boundary} Content-Disposition: form-data; name="file"; filename="#{file_name}" Content-Type: video/x-flv Content-Transfer-Encoding: binary HTTP_BODY # 转换换行符 req_body.gsub!(/\n/, "\r\n") req_body = req_body.force_encoding('ASCII-8BIT') + file_content + "\r\n--#{boundary}--\r\n" # 生成Headers req_headers = Hash.new() req_headers['Host'] = "up.qiniu.com" req_headers['Content-Type'] = "multipart/form-data; boundary=#{boundary}" req_headers['Content-Length'] = "#{req_body.size}" # 发送请求 http_client = Net::HTTP.new('up.qiniu.com', 80) resp = http_client.post( '/', req_body, req_headers ) # 解析响应 puts "HTTP Code=#{resp.code}" puts "HTTP Msg=#{resp.msg}" puts "HTTP Body=#{resp.body()}"
先启动服务器,而后执行上传程序,等待一段时间后即可收到预转成功的通知结果:
[Mon Jan 20 19:10:19 2014] HttpServer 0.0.0.0:9090 client:39573 115.238.138.231<115.238.138.231> connect { "id":"16i99r7gjlrc8r9213", "code":0, "desc":"The fop was completed successfully", "items":[ { "cmd":"avthumb/mp4", "code":0, "desc":"The fop was completed successfully", "error":"", "hash":"lpqijRaQ4c_CPoKDL1bLWK7TUoI3", "key":"UAA-4hndfVc5V6DJX0EvslAUBBI=/ll8spobyuu_F112ZWyG6Va4qk4Ch" } ] } [Mon Jan 20 19:10:19 2014] HttpServer 0.0.0.0:9090 client:39573 disconnect [Mon Jan 20 19:10:52 2014] HttpServer 0.0.0.0:9090 stop
其中,Key字段给出持久化的mp4资源的名字,便可以经过以下URL访问转换好的mp4视频:
http://qiniu-ts-demo.qiniudn.com/UAA-4hndfVc5V6DJX0EvslAUBBI=/ll8spobyuu_F112ZWyG6Va4qk4Ch
点击查看转码效果。
经过三个实例,初步讲解了音视频处理的基本接口(avinfo/avthumb),读者应该有能力自行编程实现上传与触发预转持久化处理。
七牛云存储 © 2014 署名-非商业性使用-禁止演绎
容许自由转载,请注明做者及出处。