對於音頻、視頻等多媒體資源,七牛雲也提供了豐富的處理指令,包含但不限於如下指令: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 署名-非商業性使用-禁止演繹
容許自由轉載,請註明做者及出處。