我正在尝试从Android平板电脑录制音频并将其发送到python服务器。 在字节数据包的开头,我包含了一些关于Android应用程序状态的相关信息(一个名为“actives”的字节数组 - 但考虑到Java服务器正在收到它,这应该不相关)。 android代码如下:
int read = recorder.read(buffer, 0, buffer.length); for (int a = 0; a < actives.length; a++) { outBuffer[a+1] = (byte)actives[a]; logger = logger + Byte.toString(actives[a]) + ","; } int furthest=0; for(int a =0; a < buffer.length; a++){ outBuffer[actives.length+1+a]=buffer[a]; if(buffer[a]!=0)furthest=a; } packet = new DatagramPacket(outBuffer, read, serverAddress, PORT); Log.d("writing", logger+Byte.toString(outBuffer[7])+".length"+Integer.toString(1+furthest+actives.length+1)); Log.d("streamer","Packet length "+outBuffer.length); try { socket.send(packet); }catch (IOException e){ Log.e("streamer", "Exception: " + e); } Log.d("streamer","packetSent");我使用Java服务器在另一端收到一个干净的信号。 收到的java输出图片:!( http://i.imgur.com/31UWzya.png )这是我的Java服务器:
DatagramSocket serverSocket = new DatagramSocket(3001); int byteSize=970; byte[] receiveData = new byte[byteSize]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); while(true){ // recieve data until timeout try { serverSocket.receive(receivePacket); String rcvd = "rcvd from " + receivePacket.getAddress(); System.out.println("receiver"+"Received a packet!" +rcvd); break; } catch (Exception e) { // timeout exception. System.out.println("Timeout reached without packet!!! " + e); timeoutReached=true; break; } } if(timeoutReached)continue; currTime = System.currentTimeMillis(); data = receivePacket.getData();这是我的Python服务器的输出:!( http://i.imgur.com/RYkcCCE.png )这里是代码:
import socket ip="192.ip.address" port=3001; sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); sock.bind(('',port)); while(True): data,addr=sock.recvfrom(970); print("address",addr); print("received a data!"); print(data);在python脚本的最后一行,我试图将“print(data)”更改为“print(data.decode())”,在这种情况下我收到此错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)我没有同时运行这些服务器我的猜测是它必须使用无符号整数和Java执行某些操作而python没有这样做。 在Python中有没有办法可以转换这些数据,因为data.decode()不起作用? 或者,我应该能够以某种方式转换Java中的数据? 我尝试过的stackoverflow上的答案都没有奏效。
I am trying to record audio from an Android tablet and send it to a python server. At the start of the byte packet, I include some relevant information about the state of the Android app (A byte array called "actives" -- but considering it's receiving fine by a Java server, this should not be relevant). The android code is as follows:
int read = recorder.read(buffer, 0, buffer.length); for (int a = 0; a < actives.length; a++) { outBuffer[a+1] = (byte)actives[a]; logger = logger + Byte.toString(actives[a]) + ","; } int furthest=0; for(int a =0; a < buffer.length; a++){ outBuffer[actives.length+1+a]=buffer[a]; if(buffer[a]!=0)furthest=a; } packet = new DatagramPacket(outBuffer, read, serverAddress, PORT); Log.d("writing", logger+Byte.toString(outBuffer[7])+".length"+Integer.toString(1+furthest+actives.length+1)); Log.d("streamer","Packet length "+outBuffer.length); try { socket.send(packet); }catch (IOException e){ Log.e("streamer", "Exception: " + e); } Log.d("streamer","packetSent");I receive a clean signal on the other end using a Java server. Image of received java output: !(http://i.imgur.com/31UWzya.png) This is my Java server:
DatagramSocket serverSocket = new DatagramSocket(3001); int byteSize=970; byte[] receiveData = new byte[byteSize]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); while(true){ // recieve data until timeout try { serverSocket.receive(receivePacket); String rcvd = "rcvd from " + receivePacket.getAddress(); System.out.println("receiver"+"Received a packet!" +rcvd); break; } catch (Exception e) { // timeout exception. System.out.println("Timeout reached without packet!!! " + e); timeoutReached=true; break; } } if(timeoutReached)continue; currTime = System.currentTimeMillis(); data = receivePacket.getData();Here is my Python server's output: !(http://i.imgur.com/RYkcCCE.png) And here is the code:
import socket ip="192.ip.address" port=3001; sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); sock.bind(('',port)); while(True): data,addr=sock.recvfrom(970); print("address",addr); print("received a data!"); print(data);In the last line of the python script, I have tried to change "print(data)" to "print(data.decode())", in which case I get this error:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)I am not running these servers at the same time My guess is that it has to do something with Java using unsigned ints and python not doing that. Is there a way in Python that I can convert this data, because data.decode() is not working? Alternatively I should be able to convert the data in Java somehow? None of the answers on stackoverflow that I have tried have worked.
最满意答案
解码是正确的方法。 在你的Android应用程序中明确提到字符编码。 UTF-8是使用的标准Charset。
你的日志很清楚。 您正在尝试将数据包解码为ASCII(这是decode()函数的默认编码),但我猜它的ISO_8859_1或UTF-8(更有可能)。
接下来在你的Android应用程序中尝试data.decode('utf8', 'ignore') 。 注意: 'ignore'是一个可选参数,仅在调试时使用,因为它会忽略格式错误(损坏)的数据并尝试转换单个字符。 如果要在生产中使用decode(),请使用' strict'或不使用第二个参数( 'strict'是默认值)。
代替'utf8'尝试其他Python编码的其他选项。
This was pretty brutal to attack head-on. I tried specifying the encoding in Java (before sending) like another SO post suggested, but that didn't help. So I side-stepped the problem by converting my Android byte array into a comma-separated string, then converting the string back into UTF-8 bytes.
sendString=""; for(int a =0; a < buffer.length; a++){ sendString=sendString+Byte.toString(buffer[a])+","; } byte[] outBuffer = sendString.getBytes("UTF-8");Make sure you reset your string to null ("") each time you go through the while loop, or your ish will get very slow af.
Then in Python,right after receiving:
data=data.decode("utf8");Although I am stringifying 980 characters, it does not appear to add much to the processing time... although I do wish that I could send the raw bytes, as speed is very important to me here. I'll leave the question open in case someone can come up with a better solution.
UDP数据包在Java中收到,但在Python中已损坏(UDP Packet received okay in Java but corrupted in Python)我正在尝试从Android平板电脑录制音频并将其发送到python服务器。 在字节数据包的开头,我包含了一些关于Android应用程序状态的相关信息(一个名为“actives”的字节数组 - 但考虑到Java服务器正在收到它,这应该不相关)。 android代码如下:
int read = recorder.read(buffer, 0, buffer.length); for (int a = 0; a < actives.length; a++) { outBuffer[a+1] = (byte)actives[a]; logger = logger + Byte.toString(actives[a]) + ","; } int furthest=0; for(int a =0; a < buffer.length; a++){ outBuffer[actives.length+1+a]=buffer[a]; if(buffer[a]!=0)furthest=a; } packet = new DatagramPacket(outBuffer, read, serverAddress, PORT); Log.d("writing", logger+Byte.toString(outBuffer[7])+".length"+Integer.toString(1+furthest+actives.length+1)); Log.d("streamer","Packet length "+outBuffer.length); try { socket.send(packet); }catch (IOException e){ Log.e("streamer", "Exception: " + e); } Log.d("streamer","packetSent");我使用Java服务器在另一端收到一个干净的信号。 收到的java输出图片:!( http://i.imgur.com/31UWzya.png )这是我的Java服务器:
DatagramSocket serverSocket = new DatagramSocket(3001); int byteSize=970; byte[] receiveData = new byte[byteSize]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); while(true){ // recieve data until timeout try { serverSocket.receive(receivePacket); String rcvd = "rcvd from " + receivePacket.getAddress(); System.out.println("receiver"+"Received a packet!" +rcvd); break; } catch (Exception e) { // timeout exception. System.out.println("Timeout reached without packet!!! " + e); timeoutReached=true; break; } } if(timeoutReached)continue; currTime = System.currentTimeMillis(); data = receivePacket.getData();这是我的Python服务器的输出:!( http://i.imgur.com/RYkcCCE.png )这里是代码:
import socket ip="192.ip.address" port=3001; sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); sock.bind(('',port)); while(True): data,addr=sock.recvfrom(970); print("address",addr); print("received a data!"); print(data);在python脚本的最后一行,我试图将“print(data)”更改为“print(data.decode())”,在这种情况下我收到此错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)我没有同时运行这些服务器我的猜测是它必须使用无符号整数和Java执行某些操作而python没有这样做。 在Python中有没有办法可以转换这些数据,因为data.decode()不起作用? 或者,我应该能够以某种方式转换Java中的数据? 我尝试过的stackoverflow上的答案都没有奏效。
I am trying to record audio from an Android tablet and send it to a python server. At the start of the byte packet, I include some relevant information about the state of the Android app (A byte array called "actives" -- but considering it's receiving fine by a Java server, this should not be relevant). The android code is as follows:
int read = recorder.read(buffer, 0, buffer.length); for (int a = 0; a < actives.length; a++) { outBuffer[a+1] = (byte)actives[a]; logger = logger + Byte.toString(actives[a]) + ","; } int furthest=0; for(int a =0; a < buffer.length; a++){ outBuffer[actives.length+1+a]=buffer[a]; if(buffer[a]!=0)furthest=a; } packet = new DatagramPacket(outBuffer, read, serverAddress, PORT); Log.d("writing", logger+Byte.toString(outBuffer[7])+".length"+Integer.toString(1+furthest+actives.length+1)); Log.d("streamer","Packet length "+outBuffer.length); try { socket.send(packet); }catch (IOException e){ Log.e("streamer", "Exception: " + e); } Log.d("streamer","packetSent");I receive a clean signal on the other end using a Java server. Image of received java output: !(http://i.imgur.com/31UWzya.png) This is my Java server:
DatagramSocket serverSocket = new DatagramSocket(3001); int byteSize=970; byte[] receiveData = new byte[byteSize]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); while(true){ // recieve data until timeout try { serverSocket.receive(receivePacket); String rcvd = "rcvd from " + receivePacket.getAddress(); System.out.println("receiver"+"Received a packet!" +rcvd); break; } catch (Exception e) { // timeout exception. System.out.println("Timeout reached without packet!!! " + e); timeoutReached=true; break; } } if(timeoutReached)continue; currTime = System.currentTimeMillis(); data = receivePacket.getData();Here is my Python server's output: !(http://i.imgur.com/RYkcCCE.png) And here is the code:
import socket ip="192.ip.address" port=3001; sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); sock.bind(('',port)); while(True): data,addr=sock.recvfrom(970); print("address",addr); print("received a data!"); print(data);In the last line of the python script, I have tried to change "print(data)" to "print(data.decode())", in which case I get this error:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)I am not running these servers at the same time My guess is that it has to do something with Java using unsigned ints and python not doing that. Is there a way in Python that I can convert this data, because data.decode() is not working? Alternatively I should be able to convert the data in Java somehow? None of the answers on stackoverflow that I have tried have worked.
最满意答案
解码是正确的方法。 在你的Android应用程序中明确提到字符编码。 UTF-8是使用的标准Charset。
你的日志很清楚。 您正在尝试将数据包解码为ASCII(这是decode()函数的默认编码),但我猜它的ISO_8859_1或UTF-8(更有可能)。
接下来在你的Android应用程序中尝试data.decode('utf8', 'ignore') 。 注意: 'ignore'是一个可选参数,仅在调试时使用,因为它会忽略格式错误(损坏)的数据并尝试转换单个字符。 如果要在生产中使用decode(),请使用' strict'或不使用第二个参数( 'strict'是默认值)。
代替'utf8'尝试其他Python编码的其他选项。
This was pretty brutal to attack head-on. I tried specifying the encoding in Java (before sending) like another SO post suggested, but that didn't help. So I side-stepped the problem by converting my Android byte array into a comma-separated string, then converting the string back into UTF-8 bytes.
sendString=""; for(int a =0; a < buffer.length; a++){ sendString=sendString+Byte.toString(buffer[a])+","; } byte[] outBuffer = sendString.getBytes("UTF-8");Make sure you reset your string to null ("") each time you go through the while loop, or your ish will get very slow af.
Then in Python,right after receiving:
data=data.decode("utf8");Although I am stringifying 980 characters, it does not appear to add much to the processing time... although I do wish that I could send the raw bytes, as speed is very important to me here. I'll leave the question open in case someone can come up with a better solution.
发布评论