讀取本地文件爲Base64並轉成Blob創建File對象

最近公司項目需要使用第三方音頻評測,而Demo僅有Android原生和微信小程序的,而現有架構選用的是MUI框架。因此將Demo轉爲H5能夠使用的JS代碼是尤爲重要的(其實我們可以使用後臺服務器返回的方式來解決,但會給自身服務器帶來很大的壓力,因而我們將服務器的壓力依舊留給第三方)。

MUI框架使用中使用H5+ API中的各類接口,我們讀取錄製好的本地音頻文件,將使用resolveLocalFileSystemURL()方法

/**
* 通過URL參數獲取目錄對象或文件對象
* @param(url) 本地文件路徑,此處爲錄製音頻完成後返回的路徑
* @param(successCB) 成功的回調函數
* @param(errorCB) 失敗的回調函數
*/
void plus.io.resolveLocalFileSystemURL( url, succesCB, errorCB );

//應用
plus.io.resolveLocalFileSystemURL(fileName, function(entry) {
    //此處寫具體的業務操作
}, function(e) {
    mui.toast(e.message);
});

resolveLocalFileSystemURL()方法成功執行後返回DirectoryEntry | FileEntry對象(請求到的目錄或文件對象)。我們可以在操作之前進行各類判斷及方法調用,此處僅對FileEntry做解釋。

//屬性
entry.isFile; //操作對象是否爲文件
entry.isDirectory; //操作對象是否爲目錄
entry.name; //目錄操作對象的名稱
entry.fullPath; //目錄操作對象的完整路徑,文件系統的絕對路徑
entry.fileSystem; //文件操作對象所屬的文件系統對象

//方法
entry.getMetadata();//獲取文件的屬性
entry.toURL();  //獲取文件路徑轉換爲URL地址
entry.toLocalURL();  //獲取文件路徑轉換爲本地路徑的URL地址
entry.toRemoteURL();  //獲取文件路徑轉換爲網絡路徑URL地址
entry.file(); //獲取文件數據對象

在第三方接口說明中,是以前端File控件選擇的方式來讀取文件內容。而我們不需要這種方式,我們需要錄製音頻文件完成後直接調用接口來獲取返回結果。因此我們需要用resolveLocalFileSystemURL方法來獲取本地音頻文件內容。

entry.file(function(evt) {
    console.log(JSON.stringify(evt));
    //此處編寫業務操作
});

接下來我們需要使用H5+ API提供的FileReader來從文件系統中讀取文件內容。而該對象提供了兩種方法,以URL編碼格式讀取文件數據內容,最終以Base64返回;另一種以文本格式讀取文件數據內容。最後當文件讀取操作完成時將結果返回並轉成二進制。

var reader = new plus.io.FileReader();
reader.readAsDataURL(evt);
reader.onloadend = function(e) {
    // console.log(reader.result);
    var blob = base64toBlob(reader.result, "UTF-8");
    console.log(blob);
}
//Base64轉二進制
function base64toBlob(base64, type) {
    // 將base64轉爲Unicode規則編碼,切記需要將頭部文件類型做截取
    let bstr = atob(base64.substring(base64.indexOf(',') + 1), type),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n) // 轉換編碼後纔可以使用charCodeAt 找到Unicode編碼
    }
    return new Blob([u8arr], {
        type,
    })
}

我們使用resolveLocalFileSystemURL()獲取的文件對象實際上是c對象,因此我們以上操作都是爲了創建File對象。

var fs = new File([blob], evt.name, {
    type: evt.type
});

創建File對象後,我們根據第三方提供的接口來實現數據傳輸以及結果獲取。

//從頁面file類型的input中獲取文件對象
//此處與現有需求不符,因此改寫
//var auidoFile = $("#file_audioFile").get(0).files[0];
var fr = new FileReader();
fr.readAsArrayBuffer(fs);
fr.onload = function(evt) {
    console.log(JSON.stringify(evt));
    var audioData = evt.target.result;
        //獲取評測結果
    that.websocket.send(audioData);
};
fr.onloadend = function(e) {
    console.log(JSON.stringify(e));
    that.websocket.send(new ArrayBuffer(0));
}

到此處我們已經完成了音頻文件的傳輸以及結果的獲取,此節重點是如何根據文件路徑來創建文件對象。
① 通過plus.io.FileReader讀取文件內容;
② 將Base64轉成Blob字符串;
③ 創建File對象;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章