gpt4 book ai didi

java - 实时java android流

转载 作者:行者123 更新时间:2023-11-30 03:19:00 26 4
gpt4 key购买 nike

我正在尝试通过连接服务器 (Java) - 客户端 (Android) 实时制作音频循环。服务器(PC/Java)客户端向客户端(手机/Android)发送数据并返回。

我放一段代码说明一下:- 服务器

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* This class implements a TCP Server.<p>
*/
public class GTCPServer {

public static final int SERVER_PORT = 4444; // Port number
private boolean running = true; // Boolean to control stream

private ServerSocket serverSocket;

// Input-Output streams:
private DataInputStream dis;
private DataOutputStream dos;

// Buffer:
private byte[] bytes;
private static final int BUFFER_SIZE = 512 * 4; // Size

/**
* Constructor. Starts Server.
*/
public GTCPServer() {
bytes = new byte[BUFFER_SIZE]; // Create buffer

// Put values to test:
bytes[0] = 3;
bytes[BUFFER_SIZE - 1] = 7;

try {
// Create Server Socket and wait connections.
serverSocket = new ServerSocket(SERVER_PORT);
System.out.println("Conecting...");

// Within accept methode we are waiting connection.
// When it's ready, create Client Socket:
Socket client = serverSocket.accept();
System.out.println("Receiving...");

try {
// Streams:
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} // GTCPServer()

/**
* Send (write) a byte[] buffer within TCP.
* @param buffer - Data.
* @param offset - Position.
* @param count - Number of bytes to write.
*/
public void write(byte[] buffer, int offset, int count) {
try {
dos.write(buffer, offset, count); // Write
} catch (IOException e) {
e.printStackTrace();
}
} // write()

} // GTCPServer
  • 客户:

    import android.util.Log;
    import java.io.*;
    import java.net.InetAddress;
    import java.net.Socket;

    import com.appacoustic.java.g.G;

    public class GTCPClient_A {

    public static final String SERVER_IP = "192.168.1.101"; // Server IP (PC)
    public static final int SERVER_PORT = 4444; // Port number
    private boolean running = true; // Boolean to control stream

    // Input-output streams:
    private DataInputStream dis;
    private DataOutputStream dos;

    // Buffer:
    private byte[] bytes;
    private static final int BUFFER_SIZE = 512 * 4; // Size

    /**
    * Constructor.
    */
    public GTCPClient_A() {
    bytes = new byte[BUFFER_SIZE]; // Create buffer
    } // GTCPClient_A()

    /**
    * Execute Thread. It isn't override because we are using a subclass (connectTask) wich extends AsyncTask.
    */
    public void run() {
    try {
    // Get InetAddress (IPv4 Server)
    InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
    Log.e("GTCPClient_A", "Conecting...");

    // Create a Socket ti connect with Server:
    Socket socket = new Socket(serverAddr, SERVER_PORT);

    try {
    dis = new DataInputStream(socket.getInputStream());
    dos = new DataOutputStream(socket.getOutputStream());

    int lap = 0; // Para llevar la cuenta de las vueltas

    while (running) {
    dis.read(bytes); // Leemos por TCP
    System.out.println("IN_ini_["+lap+"]: "+bytes[0]);
    System.out.println("IN_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);

    G.toc = System.currentTimeMillis();
    G.ticToc();
    G.tic = G.toc;

    dos.write(bytes); // Escribimos por TCP
    System.out.println("OUT_ini_["+lap+"]: "+bytes[0]);
    System.out.println("OUT_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);

    lap++;
    }
    } catch (Exception e) {
    Log.e("GTCP", "SERVIDOR: Error", e);
    } finally {
    socket.close();
    }
    } catch (Exception e) {
    Log.e("GTCP", "CLIENTE: Error", e);
    }
    } // run()

    } // GTCPClient_A

我已经通过蓝牙和 TCP 对其进行编程,但效果不佳。延迟太多(大约 5 秒)。令我惊讶的是,当尝试在 Java 而不是 Android 中部署客户端时,确实有效(代码几乎相同)。事实上,我对着麦克风说话(我安排了 JASIOHost ASIO 驱动程序),从我有服务器的计算机,TCP 数据传输到同一 WiFi 内的另一台计算机,返回并听到服务器计算机中实时完美的扬声器。

所以,问题似乎出在 Android 上。但我想要的是使用智能手机或平板电脑作为客户端。

我也在客户端测试过这条线:android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);//优先级

找个磨损尝试不成功的解决方案...

最佳答案

最后的解决方案是 UDP。它比 TCP 或蓝牙更快。我把你的代码放在这里。现在 ServerAndroid:

public class GUDPServer_A {

private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)

private DatagramSocket serverSocket; // Socket Servidor
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida

private boolean running = true; // Booleano para indicar que se está a la escucha del Cliente

// Buffers:
public static final int BUFFER_SIZE = 1024 * 4;
public static byte[] bytes_in;
public static byte[] bytes_out;

public GUDPServer_A() {
bytes_in = new byte[BUFFER_SIZE];
bytes_out = new byte[BUFFER_SIZE];
try {
serverSocket = new DatagramSocket(PORT_NUMBER); // Sólo se hace una vez ya que siempre estamos mandando por el mismo puerto
System.out.println("Servidor UDP en marcha.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPServer_A()

/**
* Ejecución del hilo. El método no está sobreescrito porque usamos una subclase (connectTask) que extiende de AsyncTask.
*/
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // Le damos prioridad "-19" al Thread (Lo máximo es -20)

int lap = 0; // Para llevar la cuenta de las vueltas
while (running) {
read(bytes_in); // Recibimos el paquete desde UDP

// Procesamos (de momento lo dejamos igual, simplemente clonamos):
bytes_out = bytes_in.clone();

G.toc = System.currentTimeMillis();
G.ticToc();
G.tic = G.toc;

write(bytes_out); // Enviamos el paquete de vuelta

Log.d("Vuelta:", ""+lap);
lap++;
}
} // run()

/**
* Envía (escribe) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, inPacket.getLength(), inPacket.getAddress(), inPacket.getPort());

try {
serverSocket.send(outPacket); // Enviamos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // write()

/**
* Recibe (lee) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);

try {
serverSocket.receive(inPacket); // Recibimos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // read()

/**
* Cierra la conexión.
*/
public void stop() {
if (serverSocket != null) {
serverSocket.close();
}
} // stop()

} // GUDPServer_A

并且ClientJava:

public class GUDPClient {

private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)

private DatagramSocket clientSocket; // Socket Cliente
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida

private InetAddress host; // Dirección IP del Servidor (LG L5)
public static final String IP_LG = "192.168.1.102"; // IP del Servidor (LG L5)
public static final String IP_TABLET = "192.168.1.105"; // IP del Servidor (Tablet)

/**
* Constructor.
*/
public GUDPClient() {
try {
clientSocket = new DatagramSocket(); // No hace falta darle un nº de puerto (se lo damos al paquete)
host = InetAddress.getByName(IP_LG); // Obtenemos el host del Servidor (LG L5)
//host = InetAddress.getByName(IP_TABLET); // Obtenemos el host del Servidor (Tablet)

System.out.println("Cliente UDP conectado.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPClient()

/**
* Envía (escribe) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, buffer.length, host, PORT_NUMBER);

try {
clientSocket.send(outPacket); // Enviamos el paquete por UDP
} catch (IOException e) {
e.printStackTrace();
}
} // write()

/**
* Recibe (lee) un buffer de bytes por UDP.
* @param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);

try {
clientSocket.receive(inPacket); // Recibimos el paquete procesado desde UDP
} catch (IOException e) {
e.printStackTrace();
}
} // read()

/**
* Cierra la conexión.
*/
public void stop() {
if (clientSocket != null) {
clientSocket.close();
}
} // stop()

} // GUDPClient

一件重要的事情是设置快速线程。

安卓:android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

Java: thread.setPriority(Thread.MAX_PRIORITY);

关于java - 实时java android流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19501438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com