2017-09-07 78 views
1

pythonでファイルとしてajax経由で送信されたblobを保存しようとしています。 struct.packを使用せずにPythonでファイルにブロブを保存する

error: bad char in struct formatは、単にこのvid.write(video_stream.decode('base64')) を使用してPython: How do I convert from binary to base 64 and back?

class SaveBlob(APIView): 
    def post(self, request): 
     vid = open("file.webm", "wb") 
     video_stream = request.FILES['blob'].read() 
     video_stream = struct.pack(video_stream).encode('base64') 
     # vid.write(video_stream.decode('base64')) 
     vid.write(video_stream) 
     vid.close() 
     return Response() 

それは結果の前に、この通過していたことは、ファイルが保存されますが、私はビデオを開いたときには、ストリームの種類を判断できませんでしたになります。

ajaxコールはこのようになりますが、うまく見えます。

function call_ajax(request_type,request_url,request_data) { 

    var data_vid = new FormData(); 
    console.log(request_url); 
    data_vid.append('blob', request_data); 
    console.log(request_data); 

    var data= []; 
    try{ 
     $.ajax({ 
      type: request_type, 
      url: request_url, 
      data:data_vid, 
      cors:true, 
      processData: false, 
      contentType: false, 
      async:false, 
      beforeSend: function(xhr) { 
        xhr.setRequestHeader('X-CSRFToken',Cookies.get('csrftoken')) 
      }, 

      success: function(response){ 
       data =response; 
      } 
     }); 
    }catch(error){ 
     console.log(error); 
    } 
    return data; 
} 

ご協力いただければ幸いです。あらゆる欠陥や考えられる原因についての提案は大歓迎です。

答えて

1

あなたのSaveBlobクラスでデータをエンコードとデコードするPythonのbase64ライブラリを使用できます。

あなたの元 video_streamをバック与える
import base64 

video_stream = "hello" 

with open('file.webm', 'wb') as f_vid: 
    f_vid.write(base64.b64encode(video_stream)) 

with open('file.webm', 'rb') as f_vid: 
    video_stream = base64.b64decode(f_vid.read()) 

print video_stream 

hello 

この単純な例では、保存したファイルをだろう

aGVsbG8= 
1

struct.packの最初の引数は、構造体のレイアウトを指定するformat stringです。あなただけがパックしたいバイトを渡しているので、これは無効な形式として解釈されます。

>>> bs = b'\x01\x56\x56' 
>>> struct.pack(bs) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
struct.error: bad char in struct format 

有効なフォーマット文字列の修正この構築(ただし、あなたのデータに基づいて、フォーマット文字列を構築する必要があります注意してくださいそしてプラットフォーム):

>> n = len(bs) # 3 
>>> fmt = '{:d}s'.format(n) # '3s' 
>>> struct.pack(fmt, bs) 
b'\x01VV' 

それはそれだけでディスクに書き込まれていた場合、データを*を詰めるか、base64でエンコードするために必要ではないようです。

class SaveBlob(APIView): 
    def post(self, request): 
     with open("file.webm", "wb") as vid: 
      video_stream = request.FILES['blob'].read() 
      vid.write(video_stream) 
      return Response() 

ビデオプレーヤーは、バイナリファイルを読み込んで正しく解釈できるはずです。

Base64エンコーディングは、実際には転送メカニズムがASCIIエンコーディングされたデータを必要とする場合にバイナリデータを転送するためのものです。したがって、ファイルに書き込むためにこのエンコーディングを適用する利点はありません。あなたが本当にbase64でエンコードしてデータを、マーティン・エヴァンスが彼の答えに推奨していますようPythonのbase64パッケージを使用..

*に必要がある場合は異なるendiannessとプラットフォーム間で移動されていた場合にデータをパックする必要があるかもしれません。

+0

感謝 –

0

他の解決策は、ファイルが不正なファイル形式を示しているか、プラグインがないためにファイルを再生できないままファイルをディスクに書き込む場合に役立ちました。

FormDataですべてのメタデータを取得する必要があったJavaScript(これはあまり快適ではない)と関係していました。なぜ私はこの作品がうまくいきません。どこかで検索して、これがうまくいくことがわかっていた。

何が間違っているかを知ることは素晴らしいことです。これを説明する他の答えを受け入れるだろう。私はstruct.packの後ろに詳細を知らせるための

class SaveVideo(APIView): 
    def post(self, request): 
     filename = 'demo.mp4' 
     with open(filename, 'wb+') as destination: 
      for chunk in request.FILES['video-blob'].chunks(): 
       destination.write(chunk) 
     return Response({"status":"ok"}) 

Javascriptを

function xhr(url, data, callback) { 
     var request = new XMLHttpRequest(); 
      request.onreadystatechange = function() { 
       if (request.readyState == 4 && request.status == 200) { 
        callback(request.responseText); 
       } 
      }; 

    request.open('POST', url); 
    request.setRequestHeader('X-CSRFToken',Cookies.get('csrftoken')) 
    request.send(data); 
    } 

    var fileType = 'video'; 


    var fileName = 'ABCDEF.webm'; 

    var formData = new FormData(); 
    formData.append(fileType , fileName); 
    formData.append(fileType + '-blob', blob); 
    xhr(url,formData,callback_function); 
関連する問題