【问题标题】:Sending/receiving .wav file from Android app to Django server using JSON使用 JSON 将 .wav 文件从 Android 应用程序发送/接收到 Django 服务器
【发布时间】:2016-02-01 02:35:08
【问题描述】:

我正在尝试将 .wav 文件从我的 Android 应用程序发送到 Django 服务器。主要问题是在服务器端不断收到这个错误:wave.Error: file does not start with RIFF id

从客户端的角度来看,这是我将 test_audio.wav 文件转换为 byte[]

的方式
HashMap<String, String> postParams = new HashMap<>();

InputStream inStream = testPronunciationView.getContext().getResources().openRawResource(R.raw.test_audio);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(inStream);

int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0) {
    out.write(buff, 0, read);
}
out.flush();
byte[] fileAudioByte = out.toByteArray();

// two options to transform in a string
// 1st option
String decoded = new String(fileAudioByte, "UTF-8");
// 2nd option
String decoded = toJSON(fileAudioByte);

// decoded = either one of above
postDataParams.put("Audio", decoded)

// ....
// prepare a POST request here to send to the server

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);

OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();

编辑: 创建 JSON 字符串的方法:

public static String toJSON(Object object) throws JSONException, IllegalAccessException
{
    String str = "";
    Class c = object.getClass();
    JSONObject jsonObject = new JSONObject();
    for (Field field : c.getDeclaredFields()) {
        field.setAccessible(true);
        String name = field.getName();
        String value = String.valueOf(field.get(object));
        jsonObject.put(name, value);
    }
    System.out.println(jsonObject.toString());
    return jsonObject.toString();
}

在服务器端我做:

audiofile_string = data['FileAudio']

audiofile_byte = list(bytearray(audiofile_string, 'utf8'))
temp_audiofile = tempfile.NamedTemporaryFile(suffix='.wav')
with open(temp_audiofile.name, 'wb') as output:
     output.write(''.join(str(v) for v in audiofile_byte))

# The following line throws the error
f = wave.open(temp_audiofile.name, 'r') # wave.py library

所以我认为我在转换或通话后做错了什么。有什么建议吗?谢谢

【问题讨论】:

  • 我写了一个答案但删除了它,因为我没有足够仔细地查看您的代码。看起来您甚至没有使用 JSON,但 JSON 无法处理这样的原始二进制数据。如果您使用的是 JSON,一种选择是在将二进制数据放入 JSON 之前对其进行 base64 编码。
  • @mittmemo 你是对的。我添加了用于将 Object 转换为 JSON 字符串的方法。

标签: android python json django audio


【解决方案1】:

您尝试使用 JSON 执行此操作是否有特定原因?您不能只将二进制数据填充到 JSON 字符串中。

如果您可以避免使用 JSON,那么只需使用 multipart/form-data 请求通过 HTTP POST 二进制数据。

如果由于某种原因您坚持使用 JSON,您可以使用 base64 编码来实现这一点。在您的 Android 应用程序中,您需要对二进制数据进行 base64 编码。这将产生一个字符串。然后,您可以在 JSON 中将此字符串发送到服务器。在服务器端,您需要从 JSON 中获取这个 base64 编码的字符串,base64 解码,然后将其保存到文件(或您想要对二进制数据执行的任何操作)。下面是一些小例子。

客户端:

int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0) {
    out.write(buff, 0, read);
}
out.flush();
byte[] fileAudioByte = out.toByteArray();

String encodedString = Base64.encodeToString(fileAudioByte, Base64.DEFAULT);

encodedStringString,然后您将其添加到 JSON 以发送到服务器。

服务器端:

import base64
...
audiofile_string = data['FileAudio']
audiofile_byte= base64.b64decode(audiofile_string)
# audiofile_byte now contains the bytes of the audio file, proceed to write to disk

【讨论】:

  • base64.b64decode(..) 是关键!非常感谢
  • @spaghettifunk 你好,先生,我正在做同样的工作。我需要有关如何在 django 服务器上接收编码的 .wav 文件然后解码回 wav 文件的帮助。在这种情况下使用哪个字段以及如何使用序列化程序?任何帮助将不胜感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多