聊聊前端視訊判重計算的事
起因
昨日微信群裡有人詢問技術問題,忙裡偷閒回了兩句,閒下來後感覺指的的路有點兒歪。深覺惶恐,顧整理一下思路,希望能減少一些謬誤。為了行文需要,沒有完全拘泥於群裡的原始問題,有故意跑偏意圖。
友情提示:本文看一半覺得有理,一定是被帶坑裡了;如果堅持看完,還能引發更多批評和思考,說明倖免於難 :)
問題
前端計算大檔案MD5有啥高效的辦法嗎?
載入800m檔案計算太慢了,放後端計算就要先上傳上去。
方案0:按需求,直接解。
百度一把,發現 spark-md5.js ,號稱全宇宙最快的前端類包,可以無需上傳檔案就快速獲取本地檔案md5……
document.getElementById('file').addEventListener('change', function () { var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice, file = this.files[0], chunkSize = 2097152,// Read in chunks of 2MB chunks = Math.ceil(file.size / chunkSize), currentChunk = 0, spark = new SparkMD5.ArrayBuffer(), fileReader = new FileReader(); fileReader.onload = function (e) { console.log('read chunk nr', currentChunk + 1, 'of', chunks); spark.append(e.target.result);// Append array buffer currentChunk++; if (currentChunk < chunks) { loadNext(); } else { console.log('finished loading'); console.info('computed hash', spark.end());// Compute hash } }; fileReader.onerror = function () { console.warn('oops, something went wrong.'); }; function loadNext() { var start = currentChunk * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); } loadNext(); });
方案1:加入限制維度
在想不清楚時,先參考行業標杆做法,後續再慢慢理解其為什麼要這麼做。

騰訊關於上傳視訊的限制
方案2:加入使用者體驗維度
再高的計算效能都架不住資料量的挑戰,更無法阻止使用者心中的怒火。
思路是,先忽略內部實現,從使用者視角,分析出能接受的時間限制,然後再思考解決方案。
在這個案例中,讓客戶等不現實,就需要從演算法上下手。需求是如何算MD5,但本質是判重。
可選的方案是,抽取檔案的某些片段來生成特徵值,再加上檔案大小等資訊,可解決大部分重複檔案的判定;代價是有誤判的風險,補充方案是,上傳後再依據一定條件再決定是否做完整的MD5值計算。優點的是客戶體驗好,缺點是系統架構複雜度增加。
足夠了嗎?等等……
方案3:靠近業務,尋找進一步優化的機會
前面3種方案的共性是,沒有充分利用視訊這類資料的專用維度,而是實際解決的是通用的檔案判重。優點是獲取了一定的通用性,缺點是錯過了更接地氣的方案。視訊資料都有其固定格式的,研究一下,從視訊檔案角度,收集更多元資料資訊參與判重計算,從而進一步計算算力。可以參考 ofollow,noindex">擴充套件閱讀2 ,可獲得很多靈感。
方案4:我們真的理解需求了嗎?
產品提的需求是視訊判重。問題是,怎麼判定兩個視訊重複呢?判定標準是什麼?以全文算MD5,是錯1位都會認為不重複,這樣會導致人覺得重複,而機器認為不一樣。
回到需求,其實是想避免重複的內容被上傳。人判定是否重複並不是對比MD5值是否一致,而是通過模糊對比而給出結果。於是需要和需求方確認更多細節:
1、視訊格式不同,內容一致,是否認為重複?
2、視訊清晰度不同,內容一致,是否認為重複?
3、視訊被剪輯摘錄,是否認為重複?多少重複才認為為重複?
4、……
OK?還差一步
我們設計出一個好的方案,於是信心滿滿的去找產品人員溝通。慢!
以理服人?NO!
產品提需求時,或多或少都會做一些調研工作。研發如直接否決需求,僅希望通過講道理,是很難達成共識的。所以改變思路,即 基於資料溝通 。
研發人員PK產品人員,多數都是失敗的故事。如果雙方不是對比誰更牛,而是共同面對事實、面對資料,聚焦在問題上,則很容易達成共識。
具體方案:提前用資料度量要解決的問題,量化估算方案的效果,包括:
1、設計的演算法有多少準確率?
2、對於客戶的價值是什麼?
3、對於後臺系統的影響有多大?節省了多少成本。
4、……
擴充套件閱讀
- spark-md5 http://npm.taobao.org/package/spark-md5
- OceanBase 2.0的高階資料壓縮特性 https://mp.weixin.qq.com/s/TId97PKIGB7OL5QjIkLLrg