2014-06-17 73 views
1

我正嘗試在服務器上使用django + mongoengine將視頻文件上傳到網格中。將文件數據流式傳輸到mongodb網格中

客戶端:JavaScript來讀/塊的文件,並使用AJAX將數據發送到服務器

_upload : function() { 
    chunk = self.file.slice(self.start, self.end); 
    reader = new FileReader(); 
    reader.readAsDataURL(chunk); 
    reader.onload = function(e) { 
     this.request = new XMLHttpRequest(); 
     this.request.open('POST', '/ajax/video_upload/'); 
     this.request.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
     this.request.overrideMimeType('application/octet-stream'); 
     this.request.send(JSON.stringify({ 'chunk': e.target.result, 'id' : self.file_id })); 
     this.request.onload = function() { 

     if(self.start >= self.file_size && self.preventedOverflow) { 
     return; 
     } 

     self.start = self.end; 
     self.end = self.end + self.chunkSize; 

     self._upload(); 
    }; 
} 

服務器端:

def uploadVideo(request): 
if request.body and request.is_ajax: 
    data = json.loads(request.body) 
    m = Multimedia.objects.get(id = data['id']) 
    m.media.new_file() 
    m.media.write(data['chunk']) 
    m.media.close() 
    m.save() 
    return HttpResponse() 

錯誤:

ERROR:django.request:Internal Server Error: /ajax/video_upload/ 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 115, in get_response 
    response = callback(request, *callback_args, **callback_kwargs) 
    File "/home/praveen/Desktop/gatherify/gatherify/../ajax/views.py", line 33, in uploadVideo 
    m.media.write(data['chunk']) 
    File "/usr/local/lib/python2.7/dist-packages/mongoengine-0.8.7-py2.7.egg/mongoengine/fields.py", line 1172, in write 
    self.newfile.write(string) 
    File "build/bdist.linux-i686/egg/gridfs/grid_file.py", line 327, in write 
    "order to write %s" % (text_type.__name__,)) 
TypeError: must specify an encoding for file in order to write unicode 

我不知道如何指定編碼官方文檔沒有提到任何有關它。 (http://mongoengine-odm.readthedocs.org/guide/gridfs.html

的另一個問題是,當我嘗試寫在下一個Ajax請求下一大塊,我得到一個錯誤:

GridFSError: This document already has a file. Either delete it or call replace to overwrite it 

任何幫助表示讚賞。謝謝:)

回答

2

在將它寫入FileField之前對data['chunk']字符串進行編碼。

m.media.new_file() 
m.media.write(data['chunk'].encode("UTF-8")) 
m.media.close() 

至於你的第二個問題,你已經在gridfs中創建了一個文件。像錯誤信息說你必須要m.media.delete()它或者m.media.replace(<a new gridfs entry>)它。如果你想追加它,你可能需要將文件內容作爲字符串,將新塊添加到字符串,然後創建一個新的m.media gridfs文件。您無法直接編輯網格內容。

0
  1. 你需要寫在UTF-8
  2. 你不應該關閉從newfile中獲得的GridOut實例的數據你寫只是第一塊
  3. 後,你應該爲每個新文件創建一個greenlet上傳
  4. 在寫入塊後產量
  5. 發送ack以接收下一個塊也有一些'id'來標識greenlet。
  6. 喚醒greenlet併發送新塊
  7. 發送「文件結束」一旦沒有大塊留
  8. 關閉GridOut現在。
  9. 退出greenlet