2012-09-27 3 views
6

HTML5 및 웹 작업자를 사용하여 매우 큰 파일을위한 html 업 로더를 만들려고합니다. Atm은 천천히 업로드하지만 많은 메모리를 소비합니다. 폼에 파일을 추가 할 때 전체 파일을 메모리로 전송한다고 생각합니다. Heres는 코드 : jswebworker.js :를 호출자바 스크립트 웹 작업자 파일 업로드

/*importScripts('webworkerFormData.js');*/ 

(function() { 
// Export variable to the global scope 
(this == undefined ? self : this)['FormData'] = FormData; 

var ___send$rw = XMLHttpRequest.prototype.send; 
XMLHttpRequest.prototype['send'] = function(data) { 
    if (data instanceof FormData) { 
     if (!data.__endedMultipart) data.__append('--' + data.boundary + '--\r\n'); 
     data.__endedMultipart = true; 
     this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + data.boundary); 
     data = new Uint8Array(data.data).buffer; 
    } 
    // Invoke original XHR.send 
    return ___send$rw.call(this, data); 
}; 

function FormData() { 
    // Force a Constructor 
    if (!(this instanceof FormData)) return new FormData(); 
    // Generate a random boundary - This must be unique with respect to the form's contents. 
    this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36); 
    var internal_data = this.data = []; 
    /** 
    * Internal method. 
    * @param inp String | ArrayBuffer | Uint8Array Input 
    */ 
    this.__append = function(inp) { 
     var i=0, len; 
     if (typeof inp === 'string') { 
      for (len=inp.length; i<len; i++) 
       internal_data.push(inp.charCodeAt(i) & 0xff); 
     } else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */ 
      if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */ 
       inp = new Uint8Array(inp); 
      for (len=inp.byteLength; i<len; i++) 
       internal_data.push(inp[i] & 0xff); 
     } 
    }; 
} 
/** 
* @param name  String         Key name 
* @param value String|Blob|File|Uint8Array|ArrayBuffer Value 
* @param filename String         Optional File name (when value is not a string). 
**/ 
FormData.prototype['append'] = function(name, value, filename) { 
    if (this.__endedMultipart) { 
     // Truncate the closing boundary 
     this.data.length -= this.boundary.length + 6; 
     this.__endedMultipart = false; 
    } 
    var valueType = Object.prototype.toString.call(value), 
     part = '--' + this.boundary + '\r\n' + 
      'Content-Disposition: form-data; name="' + name + '"'; 

    if (/^\[object (?:Blob|File)(?:Constructor)?\]$/.test(valueType)) { 

     return this.append(name, 
         new Uint8Array(new FileReaderSync().readAsArrayBuffer(value)), 
         filename || value.name); 
    } else if (/^\[object (?:Uint8Array|ArrayBuffer)(?:Constructor)?\]$/.test(valueType)) { 
     part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n'; 
     part += 'Content-Type: application/octet-stream\r\n\r\n'; 
     this.__append(part); 
     this.__append(value); 
     part = '\r\n'; 
    } else { 
     part += '\r\n\r\n' + value + '\r\n'; 
    } 
    this.__append(part); 
}; 
})(); 

movies = []; 
var timeStarted = 0; 
uploadingVar = false; 
const BYTES_PER_CHUNK = 64 * 1024 * 1024; 

function toTitleCase(str) 
{ 
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1);}); 
} 

function newUpload(blobOrFile, moviename, filename, i, fileType, sizeFile) { 
var xhr = new XMLHttpRequest(); 
path = '/moviehtml/newmupload.php?  moviename='+escape(moviename)+'&filename='+escape(filename)+'&num='+escape(i); 
xhr.open('POST', path, false); 
self.postMessage(blobOrFile.size); 
var fd = new FormData(); 
//xhr.setRequestHeader('Content-Type', fileType) 
//blobOrFile2 = FileReaderSync.readAsArrayBuffer(blobOrFile); 
fd.append("files1", blobOrFile); 
//fd.append("moviename", moviename); 
//fd.append("filename", filename); 
//fd.append("num",i); 

seconds = new Date()/1000; 
xhr.send(fd); 
self.postMessage(xhr.responseText) 
self.postMessage({'type':'partial','done':i*BYTES_PER_CHUNK, 'started':timeStarted, 'total':sizeFile}); 
var finish = Date()/1000; 
if (finish >= (seconds+100)){ 
    return false; 
} 
return true; 

} 
function newFileUpload(file, movieName, fileType, filename, exten){ 
if (movieName == movieName.match(/[a-zA-Z0-9\. \:]+/)){ 
    timeStarted = new Date().getTime(); 

var blob = file;// this.files[0]; 
//var filename = blob.name; 
var moviename = toTitleCase(movieName); 
// 1MB chunk sizes. 
const SIZE = blob.size; 
//alert(SIZE + ' '+document.getElementById('fileToUpload').files[0].size) 
var start = 0; 
var end = BYTES_PER_CHUNK; 
//alert(SIZE/BYTES_PER_CHUNK) 
var i = 1; 
while(start < SIZE) { 
    wow = newUpload(blob.slice(start, end), moviename, filename, i, fileType, SIZE); 

    start = end; 
    end = start + BYTES_PER_CHUNK; 
    i++; 
} 
var xhr = new XMLHttpRequest(); 
var fd2 = new FormData(); 
typeFile = filename.split('.').pop() 
fd2.append("type", blob.type); 
fd2.append("exten", typeFile); 
fd2.append("moviename", moviename); 
xhr.open('POST', '/moviehtml/finishedupload.php', false); 
xhr.send(fd2); 
} 
} 
function process(){ 
uploadingVar = true; 
while(movies.length > 0) { 

    upMovie = movies.pop(); 
    var file = upMovie[0]; 
    var movieName = upMovie[1]; 
    var fileType = upMovie[2]; 
    var filename = upMovie[3]; 
    var exten = upMovie[4]; 
    self.postMessage({'type':'start','size':file.size, 'name':movieName}); 

    newFileUpload(file, movieName, fileType, filename, exten); 
    self.postMessage({'type':'finish','name':movieName}) 
    self.postMessage(movieName + " Uploaded Succesfully"); 
} 
uploadingVar = false; 
} 

self.addEventListener('message', function(e) { 
movies.push(e.data); 
if (!uploadingVar){ 
process(); 

} 
}, false); 

내 기능 :

var worker = new Worker('jswebworker.js'); 
function testUpload(){ 
//newFileUpload(); 
var file = document.getElementById('fileToUpload').files[0]; 
worker.postMessage([file,toTitleCase(document.getElementById('movieName').value),  file.type, file.name, file.name.split('.').pop()]); 

} 

이 내 아파트에 대한 미디어 서버의 웹 페이지입니다. 원본을 모두 메모리에로드하지 않고 모양을 만드는 방법이 있기를 바라고 있습니다. 어떤 도움을 주셔서 감사합니다, 닉

+0

어디에서 해결책을 찾아 낼 수 있습니까? – Hadesara

+0

왜 간단한 코드를 제공하지 않습니까? 당신이 그렇게한다면 더 많은 사람들이 실제로 읽는다고 믿습니다. – stevemao

답변

1

나는 라이브러리 (여기는에 대한 github 페이지입니다)가 이미 수행하려는 작업을 수행하고있을 수도 있다고 생각합니다. 파일을 얼마나 많이 업로드했는지 모르기 때문에 벤치 마크만큼 통찰력을 드릴 수는 없습니다. 나는 이것이 당신을 도울 수 있기를 바랍니다.

관련 문제