Javascript 在python中将blob保存到文件
我试图将通过ajax发送的blob保存为python中的文件。我以前也经历过这种情况 它导致Javascript 在python中将blob保存到文件,javascript,python,Javascript,Python,我试图将通过ajax发送的blob保存为python中的文件。我以前也经历过这种情况 它导致错误:结构格式中的错误字符 只需使用这个vid.write(video\u stream.decode('base64')) 不使用struct.pack保存文件,但当我打开视频时,它导致无法确定流的类型 ajax调用是这样的,但我想它看起来不错 function call_ajax(request_type,request_url,request_data) { var data_vid =
错误:结构格式中的错误字符
只需使用这个vid.write(video\u stream.decode('base64'))
不使用struct.pack
保存文件,但当我打开视频时,它导致无法确定流的类型
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;
}
任何帮助都将不胜感激。欢迎对任何缺陷或可能原因提出任何建议 您可以使用Python库对SaveBlob
类中的数据进行编码和解码:
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=
struct.pack的第一个参数是指定结构布局的。您只传递要打包的字节,因此这被解释为无效格式:
>>> 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
如果数据刚刚写入磁盘,则不太可能需要对其进行打包*或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()
您的视频播放器应该能够读取二进制文件并正确解释它
当传输机制需要ascii编码的数据时,Base64编码实际上用于传输二进制数据,因此仅将此编码应用于写入文件没有任何好处。如果您确实需要对数据进行base64编码,请使用Martin Evans在回答中建议的python包
*如果数据在不同平台之间移动,则可能需要打包数据。其他解决方案很有用,它会将文件写入磁盘,但可能会说文件格式不正确或由于缺少插件而无法播放文件 这与JavaScript有关(我不太习惯使用JavaScript),我想我必须将所有元数据都放在FormData中。我不知道为什么会这样。我找了个地方,找到了这个 如果能知道上面出了什么问题,那就太好了。我会接受任何其他解释这一点的答案
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);
感谢您让我了解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"})
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);