最近更新:2017.04.27 pm, by very80
需求
- 文件上傳到OSS并轉(zhuǎn)碼完成后,由程序及時(shí)將預(yù)覽文件傳送到 192.168.10.55,供本地審核使用;
- 在備份服務(wù)器上,定時(shí)下載審核通過(啟用)的素材源文件;
流程
- 客戶上傳視頻,阿里云轉(zhuǎn)碼完成后,在回調(diào)處理中,將素材相關(guān)信息通過內(nèi)部接口存入數(shù)據(jù)庫表 oss_syncqueue;
也可以通過調(diào)用 api.xxx.com 的接口進(jìn)行保存;
[請(qǐng)求方式]:POST
[POST數(shù)據(jù)]:
"programid"=>2, // ss_program 表的id
"tasktype"=>2, // 1=源文件,2=素材文件
"bucket"=>'xxx-data-upload', // OSS-bucket 名稱
"name"=>'2017-04-24/7281280473e073f.mov', // Object name,相當(dāng)于文件名,從oss-sdk 接口中獲取到的數(shù)據(jù)
"url"=>'http://xxx-data-upload.oss-cn-shanghai.aliyuncs.com/2017-04-14/7281280473e073f.mov', // OSS url,從oss-sdk 接口中獲取到的數(shù)據(jù)
"etag"=>'"F93CD36C35A60D8-49"', // etag,從oss-sdk 接口中獲取到的數(shù)據(jù)
"lastmodified"=>'2017-04-14T10:02:09.000Z', // 上次更新時(shí)間,從oss-sdk 接口中獲取到的數(shù)據(jù)
"type"=>'Multipart', // 文件類型,從oss-sdk 接口中獲取到的數(shù)據(jù)
"size"=>156264049, // 文件大小,從oss-sdk 接口中獲取到的數(shù)據(jù)
[返回結(jié)果]:json 文本串 :{"queueid":24} // 插入到數(shù)據(jù)庫表 oss_syncqueue 后,新任務(wù)的id
- OSS同步任務(wù)創(chuàng)建接口收到請(qǐng)求后,插入到數(shù)據(jù)庫表 oss_syncqueue,表結(jié)構(gòu)見 附錄一;
- api.xx.com 提供隊(duì)列查詢接口 getSyncTask,根據(jù)請(qǐng)求參數(shù),返回若干隊(duì)列任務(wù);
- 192.168.10.55 和 源文件備份服務(wù)器上的nodeJS進(jìn)程輪詢 getSyncTask 接口, 按時(shí)間順序獲取最早的且狀態(tài)為1的任務(wù),每10秒查詢一次;
- 查詢到新任務(wù)時(shí),根據(jù)任務(wù)表中的數(shù)據(jù),調(diào)用 ali-oss sdk 的 signatureUrl(bucket, object) 接口,生成簽名url;
- 在本機(jī)安裝 aria2,并配置提供 jsonrpc 服務(wù);
- nodeJS請(qǐng)求本機(jī) aria2c 的 jsonrpc 接口,加入其下載任務(wù)隊(duì)列,將自動(dòng)開始下載,代碼示例見 附錄三;
- 在上一步中,添加下載任務(wù)時(shí),設(shè)置 --on-download-complete 參數(shù),以在aria2下載完成后,調(diào)用命令行執(zhí)行以下操作:
7.1 更改db中的任務(wù)狀態(tài)
7.1.1 aria2c.conf 中的相關(guān)配置:
on-download-complete=E:\web\vjhero\trunk\tools\oss_sync\code\download_complete.bat
on-download-error=E:\web\vjhero\trunk\tools\oss_sync\code\download_error.bat
7.1.2 .bat 腳本
# download_complete.bat
@echo off
node E:\web\vjhero\trunk\tools\oss_sync\code\index.js op=common/ossSyncComplete env=test.local filename="%3"
# download_error.bat
@echo off
node E:\web\vjhero\trunk\tools\oss_sync\code\index.js op=common/ossSyncError env=test.local filename="%3"
//
#download_complete.sh
#!/bin/sh
node /app/bin/vjnode/index.js op=common/ossSyncComplete env=10 filename="$3"
#download_complete.sh
#!/bin/sh
node /app/bin/vjnode/index.js op=common/ossSyncError env=10 filename="$3"
7.2 視頻提取關(guān)鍵幀,計(jì)算特征碼,入庫,檢查重復(fù),并將檢查結(jié)果通過遠(yuǎn)程接口調(diào)用存入數(shù)據(jù)庫;
部署
運(yùn)行環(huán)境
1.1 源文件下載:運(yùn)行于windows系統(tǒng),添加系統(tǒng)計(jì)劃任務(wù),每天0點(diǎn)5分開始運(yùn)行,超過8點(diǎn)則程序退出,但之前已加入的下載會(huì)持續(xù)直到最終完成;
1.2 素材文件下載:運(yùn)行于192.168.10.55(win2008r2),任務(wù)隊(duì)列中的下載任務(wù)實(shí)時(shí)執(zhí)行本地文件存儲(chǔ)策略
2.1 從OSS上的文件名中解析出目錄名,形如 2017-04-20/203a25bb.mp4, 建立目錄,并保存文件
2.2 如果磁盤空間不足,采取線下手動(dòng)處理服務(wù)器上安裝 nodeJS 運(yùn)行環(huán)境
3.1 nodeJS版本:V6.10.2
3.2 確保安裝依賴模塊:npm install co ali-oss websocket node-mysql
直接從代碼庫里拉取,則 node_modules 中已包含以上模塊,無需再次安裝
3.3 參數(shù)配置:在代碼目錄,%pathto%/inc/conf/conf.*.js 中,修改數(shù)據(jù)庫連接、本地存儲(chǔ)目錄、aria2的rpc參數(shù)等;
'oss_sync':{
'save_to_dir':'D:\\files\\',
'download_server':{
'ADDRESS':'ws://127.0.0.1:6800/jsonrpc',
'METHOD': 'aria2.addUri',
'AUTH_TOKEN':'token:xxxdownloader'
},
'db_task_type':'THUMB',
'period':[0, 800] // true: 不限制時(shí)間
}
3.4 運(yùn)行腳本,其中 env 參數(shù)用于區(qū)別加載不同環(huán)境的配置參數(shù),包括下載目錄、數(shù)據(jù)庫連接等參數(shù)
node c:\vjtools\oss_sync\app\index.js env=55
// 在0.136 上
node /app/vjnode/index.js op=queue/handle env=ONLINE &
- 解壓 aria2 程序壓縮包到任意目錄
4.1 aria2.conf 重要配置參數(shù)
max-concurrent-downloads=1
max-connection-per-server=5
input-file=G:\newFile\aria2.session
save-session=G:\newFile\aria2.session
enable-rpc=true
rpc-listen-port=6800
rpc-secret=xxxdownloader
4.2 運(yùn)行方式:windows 命令行,提供jsonrpc服務(wù),完整命令行為:
%pathto%\aria2c --conf-path=e:\web\Lab\aria2-1.31.0\aria2.conf
或
%pathto%\aria2c --conf-path=c:\tools\oss_sync\aria2-1.31.0\aria2.conf
# 在我的開發(fā)環(huán)境里,是這樣的:
e:\web\Lab\aria2-1.31.0\aria2c.exe --conf-path=e:\web\Lab\aria2-1.31.0\aria2.conf
# 在 192.168.0.55 上,是這樣的:
c:\vjtools\oss_sync\aria2-1.31.0\aria2c.exe --conf-path=c:\vjtools\oss_sync\aria2-1.31.0\aria2.conf
4.3 注意,在不同的環(huán)境,需要修改 aria2.conf 中的session文件路徑,不然會(huì)啟動(dòng) aria2 錯(cuò)誤
- 后臺(tái)管理
5.1 任務(wù)列表顯示,便于監(jiān)控
5.2 統(tǒng)計(jì):已完成、未完成、失敗的數(shù)量及大小等 - 從本地加載預(yù)覽視頻:
6.1 在 192.168.0.55 上,IIS配置站點(diǎn),根目錄為 D:\flv,主機(jī)頭為空,端口80;
6.2 在審核員主機(jī),修改本機(jī)hosts,將 dmp4.vjshi.com 指向 192.168.0.55,即可;
處理OSS轉(zhuǎn)碼上線后的歷史預(yù)覽文件
- 篩選:192.168.0.55 上,預(yù)覽視頻文件截止2017-04-26,當(dāng)天有 1516 個(gè)文件;
SELECT id,filename,fileext,posttime,filesize FROM ss_program WHERE posttime>=UNIX_TIMESTAMP('2017-4-25 0:0:0') AND posttime<=UNIX_TIMESTAMP('2017-4-25 23:59:59')
- 執(zhí)行查詢:
# 預(yù)覽視頻
# 4月27號(hào)的
INSERT INTO oss_syncqueue(programid,tasktype,bucket,name,size,created,status) SELECT id,2,'vjshi-data-mp4-dis',CONCAT(DATE_FORMAT(FROM_UNIXTIME(posttime), '%Y-%m-%d'),'/',filename,'.',fileext),filesize,unix_timestamp(),1 FROM ss_program WHERE posttime>=UNIX_TIMESTAMP('2017-4-27 0:0:0') AND posttime<=UNIX_TIMESTAMP('2017-4-27 23:59:59') AND isconvert='y';
# 4月28號(hào)到30號(hào)的
INSERT INTO oss_syncqueue(programid,tasktype,bucket,name,size,created,status) SELECT id,2,'vjshi-data-mp4-dis',CONCAT(DATE_FORMAT(FROM_UNIXTIME(posttime), '%Y-%m-%d'),'/',filename,'.',fileext),filesize,unix_timestamp(),1 FROM ss_program WHERE posttime>=UNIX_TIMESTAMP('2017-4-28 0:0:0') AND posttime<=UNIX_TIMESTAMP('2017-4-30 23:59:59') AND isconvert='y';
# 截至 2017-5-3 18:0:0
INSERT INTO oss_syncqueue(programid,tasktype,bucket,name,size,created,status) SELECT id,2,'vjshi-data-mp4-dis',CONCAT(DATE_FORMAT(FROM_UNIXTIME(posttime), '%Y-%m-%d'),'/',filename,'.',fileext),filesize,unix_timestamp(),1 FROM ss_program WHERE posttime>=UNIX_TIMESTAMP('2017-5-1 0:0:0') AND posttime<=UNIX_TIMESTAMP('2017-5-3 18:0:0') AND isconvert='y';
# 截至 2017-5-4 14:30:0
INSERT INTO oss_syncqueue(programid,tasktype,bucket,name,size,created,status) SELECT id,2,'vjshi-data-mp4-dis',CONCAT(DATE_FORMAT(FROM_UNIXTIME(posttime), '%Y-%m-%d'),'/',filename,'.',fileext),filesize,unix_timestamp(),1 FROM ss_program WHERE posttime>UNIX_TIMESTAMP('2017-5-3 18:0:0') AND posttime<UNIX_TIMESTAMP('2017-5-4 14:30:0') AND isconvert='y';
# 2017.5.4 青年節(jié)快樂 -- 增加字段記錄素材最初添加時(shí)間
alter table oss_syncqueue add column programposttime int(12) unsigned not null default 0 after programid;
# 更新該字段時(shí)間
update oss_syncqueue as S set programposttime=(select posttime from ss_program as P where S.programid=P.id);
# 更新 0427 這天失敗的記錄,嘗試從 vjshi-data-mp4 中下載:
## 先查詢一下:
SELECT * FROM oss_syncqueue WHERE status=101 AND programposttime>=UNIX_TIMESTAMP('2017-4-27 0:0:0') AND programposttime<=UNIX_TIMESTAMP('2017-4-28 0:0:0');
UPDATE oss_syncqueue SET bucket='',status=1 WHERE status=101 AND programposttime>=UNIX_TIMESTAMP('2017-4-27 0:0:0') AND programposttime<=UNIX_TIMESTAMP('2017-4-28 0:0:0');
# 可以更新了
UPDATE oss_syncqueue SET bucket='vjshi-data-mp4',status=1 WHERE tasktype=2 AND status=101 AND programposttime>=UNIX_TIMESTAMP('2017-4-27 0:0:0') AND programposttime<=UNIX_TIMESTAMP('2017-4-28 0:0:0');
附錄一:數(shù)據(jù)表 oss_syncqueue
use vjhero;
set names utf8;
CREATE TABLE IF NOT EXISTS `oss_syncqueue` (
`id` int(12) unsigned NOT NULL AUTO_INCREMENT,
`programid` int(12) unsigned NOT NULL DEFAULT '0' COMMENT '資源id',
`tasktype` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '1=源文件,2=預(yù)覽文件',
`bucket` varchar(50) NOT NULL COMMENT '所在',
`name` varchar(100) NOT NULL COMMENT 'Object name',
`lastmodified` char(24) NOT NULL COMMENT '文件更改時(shí)間',
`etag` char(32) NOT NULL COMMENT 'etag',
`type` varchar(32) NOT NULL COMMENT 'Object 類別(Normal,Multipart)',
`url` varchar(100) NOT NULL COMMENT 'OSS 完整路徑',
`size` int(12) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
`created` int(12) unsigned NOT NULL DEFAULT '0' COMMENT '創(chuàng)建時(shí)間',
`status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '1=待下載,10=下載中,100=下載完成,101=下載失敗',
`costtime` int(12) unsigned NOT NULL DEFAULT '0' COMMENT '下載消耗時(shí)間(單位:秒)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
# 2017.5.4 青年節(jié)快樂 -- 增加字段記錄素材最初添加時(shí)間
alter table oss_syncqueue add column programposttime int(12) unsigned not null default 0 after programid;
# 更新該字段時(shí)間
update oss_syncqueue as S set programposttime=(select posttime from ss_program as P where S.programid=P.id);
附錄二:aria2命令行下載文件
aria2c "http://xxx-data-upload.oss-cn-shanghai.aliyuncs.com/test/1121686_xxx_bce798826fa97314d17.mov?OSSAccessKeyId=LTAI9FQWL5nbY6kt&Expires=1493004269&Signature=fDO2mJ6f1v%2Fg6cjWe4%2B9YK%2FNNNA%3D" -d g:\newFile -o 1.mov -c
aria2c "http://xxx-data-upload.oss-cn-shanghai.aliyuncs.com/test/1121686_xxx_bce798826fa97314b0de365c6ef00d17.mov?OSSAccessKeyId=LTAI9FbY6kt&Expires=1493007542&Signature=uKk4nG8TldoFI%3D" -d g:\newFile -o 3.mov -c
aria2c "https://nj01ct01.baidupcs.com/file/15b78561c8c24987174a66db?bkt=p3-0000730a4e336669f1&fid=1778458740-250528-8644880266&time=1493005774&sign=FDTAXGERLBHS-DCbedcff06b081203-WJ7te8HYgi07eXJJi76Gzxs4Xws%3D&to=63&size=56666824&sta_dx=56666824&sta_cs=4&sta_ft=apk&sta_ct=2&sta_mt=0&fm2=MH,Yangquan,Netizen-anywhere,,sichuan,ct&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=0000730a4ee11529bb956caffc3a336669f1&sl=83034191&expires=8h&rt=pr&r=145752607&mlogid=2632217428387618541&vuk=1778458740&vbdid=2477955945&fin=Qrsqloud-wandoujia-release-3-9-0.apk&fn=Qrsqloud-wandoujia-release-3-9-0.apk&rtype=1&iv=0&dp-logid=2632217428387618541&dp-callid=0.1.1&hps=1&csl=300&csign=Ugb%2BRCcZ876hmoDLg7t4l%2B2FC%2B4%3D&by=themis" -d g:\newFile -o 390.apk -c --file-allocation=falloc
附錄三:通過 nodejs 調(diào)用 jsonrpc
- 安裝node-websocket 模塊
npm install websocket
- 封裝 websocket 為 ./inc/lib/websocket.js,實(shí)現(xiàn)了 connect,send 等主要的調(diào)用方法
- 程序示例
var websocket = require('./websocket');
var options = {
'dir':'G:\\newfile\\2017-04-14',
'out':'f4f4cf36275.mov'
};
websocket.connect('ws://127.0.0.1:6800/jsonrpc', function() {
websocket.send({
method : 'aria2.addUri',
params : ['token:xxxxxxx',['http://data-upload.oss-cn-shanghai.aliyuncs.com/2017-04-24%2Ff4f4b06244b275.mov?OSSAccessKeyId=LTAbY6kt&Expires=1493104082&Signature=PuUv%2FgkzVRTI9x8%3D'], options]
}, function(result) {
console.log(result);
websocket.close();
});
});
- 接口返回?cái)?shù)據(jù)
{
obj:{
id: '61a05552-37fa-4060-b8e9-871a35730dc1',
jsonrpc: '2.0',
result: '15f6171e0da5a6a0'
},
err: false
}
附錄四:其他
- noejs 在對(duì)大文件(數(shù)據(jù)塊)做操作時(shí),存在內(nèi)存泄漏風(fēng)險(xiǎn),因此僅用于隊(duì)列處理;
- 任務(wù)隊(duì)列、文件下載的進(jìn)度管理及相關(guān)異常處理
- 每天定時(shí)掃描文件,檢查是否已經(jīng)完成,對(duì)未完成的,再次通過jsonrpc接口提交下載任務(wù),下載器將自動(dòng)續(xù)傳下載
- oss-sdk 生成的簽名url有效期過后將無法下載,目前默認(rèn)為1小時(shí)(3600)