Flux audio en direct java
Je suis la mise en œuvre de streaming en live à partir de MICRO pour java serveur à un autre PC. Mais je ne suis que l'audition d'un bruit blanc.
J'ai joint à la fois le client et le serveur programme
Client:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
public class Mic
{
public byte[] buffer;
private int port;
static AudioInputStream ais;
public static void main(String[] args)
{
TargetDataLine line;
DatagramPacket dgp;
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 44100.0f;
int channels = 2;
int sampleSize = 16;
boolean bigEndian = true;
InetAddress addr;
AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8) * channels, rate, bigEndian);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line matching " + info + " not supported.");
return;
}
try
{
line = (TargetDataLine) AudioSystem.getLine(info);
int buffsize = line.getBufferSize()/5;
buffsize += 512;
line.open(format);
line.start();
int numBytesRead;
byte[] data = new byte[buffsize];
addr = InetAddress.getByName("127.0.0.1");
DatagramSocket socket = new DatagramSocket();
while (true) {
//Read the next chunk of data from the TargetDataLine.
numBytesRead = line.read(data, 0, data.length);
//Save this chunk of data.
dgp = new DatagramPacket (data,data.length,addr,50005);
socket.send(dgp);
}
}catch (LineUnavailableException e) {
e.printStackTrace();
}catch (UnknownHostException e) {
//TODO: handle exception
} catch (SocketException e) {
//TODO: handle exception
} catch (IOException e2) {
//TODO: handle exception
}
}
}
et côté serveur pas de problème. Il fonctionne parfaitement avec android client AudioRecord.
Server:
import java.io.ByteArrayInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class Server {
AudioInputStream audioInputStream;
static AudioInputStream ais;
static AudioFormat format;
static boolean status = true;
static int port = 50005;
static int sampleRate = 44100;
static DataLine.Info dataLineInfo;
static SourceDataLine sourceDataLine;
public static void main(String args[]) throws Exception
{
System.out.println("Server started at port:"+port);
DatagramSocket serverSocket = new DatagramSocket(port);
/**
* Formula for lag = (byte_size/sample_rate)*2
* Byte size 9728 will produce ~ 0.45 seconds of lag. Voice slightly broken.
* Byte size 1400 will produce ~ 0.06 seconds of lag. Voice extremely broken.
* Byte size 4000 will produce ~ 0.18 seconds of lag. Voice slightly more broken then 9728.
*/
byte[] receiveData = new byte[4096];
format = new AudioFormat(sampleRate, 16, 1, true, false);
dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(format);
sourceDataLine.start();
//FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
//volumeControl.setValue(1.00f);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
ByteArrayInputStream baiss = new ByteArrayInputStream(receivePacket.getData());
while (status == true)
{
serverSocket.receive(receivePacket);
ais = new AudioInputStream(baiss, format, receivePacket.getLength());
toSpeaker(receivePacket.getData());
}
sourceDataLine.drain();
sourceDataLine.close();
}
public static void toSpeaker(byte soundbytes[]) {
try
{
System.out.println("At the speaker");
sourceDataLine.write(soundbytes, 0, soundbytes.length);
} catch (Exception e) {
System.out.println("Not working in speakers...");
e.printStackTrace();
}
}
}
OriginalL'auteur | 2015-01-24
Vous devez vous connecter pour publier un commentaire.
Donc, j'ai rempli le micro avec une onde sinusoïdale (ou quelque chose qui, dans un sens vague, ressemble à une onde sinusoïdale), et que votre programme fonctionne très bien.
Mes changements spécifiques ont donc été:
Évidemment, je l'ai interprété à tort comme une de 512 octets au long de la pièce et bâclé de l'onde sinusoïdale, mais la chose est, il produit exactement le son qu'il était censé--une abrutissante râle à un emplacement déterminé.
Cela à l'esprit, je ne soupçonne pas que le problème est explicitement dans votre code. La première chose que je tiens à vérifier est la ligne à laquelle votre système est saignée pour l'audio. Avez-vous plusieurs microphones branché? Une webcam micro, peut-être? Vous pourriez saisir un utilitaire comme PulseAudio Volume de Contrôle pour vérifier. Si vous n'avez pas déjà cochée sur la fonctionnalité de votre micro, vous pouvez le faire aussi; ils ont une durée de vie sur eux.
Il n'est pas rare du tout pour brouiller les bits dans un flux audio, il n'est ni difficile; mais je ne vois pas où vous pourriez faire.
On pensait peut-être à modifier votre programme pour tenter de jouer le son en local, avant de l'envoyer vers le serveur. De cette façon, vous pouvez au moins de déterminer si le problème est pré - ou post-Mic.
OriginalL'auteur Michael Eric Oberlin
Lorsque le client et le serveur utilisent des tampons de données de tailles différentes, on obtiendra tronquée et peut provoquer un ou deux pour produire des artefacts.
Votre serveur taille de la mémoire tampon est définie à
byte[] receiveData = new byte[4096];
Votre client taille de la mémoire tampon est pour une raison quelconque dynamique, et se mit à
byte[] data = new byte[buffsize];
Définir client taille de la mémoire tampon statique 4096 pour correspondre au serveur:
byte[] data = new byte[4096];
Ou assurez-vous qu'ils sont tous les deux de la même taille...
OriginalL'auteur user3674935
Donc c'est une vieille question, mais la résolution de ce m'a aidé un peu, et je suppose que ce que j'ai trouvé peut aider les autres.. c'est comment j'ai résolu les problèmes que vous avez décrit:
Sur ma machine, changer
à
résolu le blanc de problème de bruit (il était de toute évidence un ordre des octets de l'émission)
Si c'est le seul changement que vous faites, l'audio va avoir une faible hauteur, cela est dû au fait que sur le Micro côté vous collecter les 2 canaux et sur le haut-Parleur côté vous jouez à travers un canal.
À résoudre que de simplement modifier cette ligne:
à
Et puis le son doit être clair et compréhensible
OriginalL'auteur Don Joe
Je suggère que vous devez d'abord écrire dans un fichier les données audio de l'enregistreur sur le client. Cela vous permettra de vérifier si la capture audio est OK. Vous pouvez convertir PCM WAV en utilisant des utilitaires comme sox.
OriginalL'auteur Tim
Il est important d'adapter le format audio sur à la fois le client et le serveur, par exemple le changement de l'un à Client.java pour:
format = new AudioFormat(sampleRate, 16, 1, true, false);
Vous devez également utiliser la même taille de tampon sur les deux programmes.
OriginalL'auteur Mauricio