/
f1rment2
/
lab8
Обзор
Документация
Войти
/
f1rment2
/
lab8
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/AudioEngine.java
109 строк
4 KB
Ilya
First commit: P2P Voice Chat with Multicast and Codec
02 июн 2026, 00:00
02 июн 2026, 00:00
ecd9191
Код
Авторство
О чём код?
import javax.sound.sampled.*; import java.net.*; public class AudioEngine { private final int localUdpPort; private DatagramSocket udpSocket; private Thread recordThread; private Thread playThread; private volatile boolean isRunning = false; private boolean useCompression = true; // По умолчанию сжатие ВКЛ (Вариант 5) public AudioEngine(int localUdpPort) { this.localUdpPort = localUdpPort; try { this.udpSocket = new DatagramSocket(localUdpPort); } catch (SocketException e) { System.err.println("[Audio] Не удалось открыть UDP сокет: " + e.getMessage()); } } public void setCompression(boolean useCompression) { this.useCompression = useCompression; System.out.println("[Audio] Режим сжатия (8-бит): " + (useCompression ? "ВКЛ" : "ВЫКЛ")); } public boolean isCompressionEnabled() { return useCompression; } public void startAudio(String remoteIp, int remoteUdpPort) { if (isRunning) return; isRunning = true; // Настройка формата: 8000 Гц, 16 бит, Моно AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, false); DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format); DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format); // Поток отправки (Микрофон -> Сеть) recordThread = new Thread(() -> { try { TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(targetInfo); targetLine.open(format); targetLine.start(); byte[] buffer = new byte[1024]; InetAddress remoteAddress = InetAddress.getByName(remoteIp); System.out.println("[Audio] Запись звука запущена."); while (isRunning) { int read = targetLine.read(buffer, 0, buffer.length); if (read <= 0) continue; byte[] dataToSend; if (useCompression) { dataToSend = Codec.compress16to8(buffer); } else { dataToSend = new byte[read]; System.arraycopy(buffer, 0, dataToSend, 0, read); } DatagramPacket packet = new DatagramPacket(dataToSend, dataToSend.length, remoteAddress, remoteUdpPort); udpSocket.send(packet); } targetLine.close(); } catch (Exception e) { System.err.println("[Audio Запись] Остановлена: " + e.getMessage()); } }); // Поток воспроизведения (Сеть -> Динамики) playThread = new Thread(() -> { try { SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(sourceInfo); sourceLine.open(format); sourceLine.start(); byte[] incomingBuffer = new byte[1024]; System.out.println("[Audio] Воспроизведение звука запущено."); while (isRunning) { DatagramPacket packet = new DatagramPacket(incomingBuffer, incomingBuffer.length); udpSocket.receive(packet); byte[] rawPcm16; if (useCompression) { rawPcm16 = Codec.decompress8to16(packet.getData(), packet.getLength()); } else { rawPcm16 = new byte[packet.getLength()]; System.arraycopy(packet.getData(), 0, rawPcm16, 0, packet.getLength()); } sourceLine.write(rawPcm16, 0, rawPcm16.length); } sourceLine.close(); } catch (Exception e) { // Исключение при закрытии сокета — нормальный выход из вызова } }); recordThread.start(); playThread.start(); } public void stopAudio() { isRunning = false; if (recordThread != null) recordThread.interrupt(); if (playThread != null) playThread.interrupt(); System.out.println("[Audio] Потоки передачи аудио остановлены."); } }