Я пытаюсь прочитать аудиопоток RTP из ffmpeg в командной строке, используя javaCV. Я создаю DatagramSocket, который слушает указанный порт, но не может получить аудио кадры.
Я пытался использовать разные типы буферов для воспроизведения звука на моих динамиках, но я получаю много сообщений об ошибке «Неверное возвращаемое значение 0 для потокового протокола» без звука в моих динамиках.
Я запускаю следующую команду для потоковой передачи аудиофайла:
ffmpeg -re -i /some/file.wav -ar 44100 -f мулав -f rtp rtp: //127.0.0.1: 7780
И выдержка из моего кода:
открытый класс FrameGrabber реализует Runnable {
private static final TimeUnit SECONDS = TimeUnit.SECONDS;
private InetAddress ipAddress;
private DatagramSocket serverSocket;
public FrameGrabber(Integer port) throws UnknownHostException, SocketException {
super();
this.ipAddress = InetAddress.getByName("192.168.44.18");
serverSocket = new DatagramSocket(port, ipAddress);
}
public AudioFormat getAudioFormat() {
float sampleRate = 44100.0F;
// 8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
// 8,16
int channels = 1;
// 1,2
boolean signed = true;
// true,false
boolean bigEndian = false;
// true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}
@Override
public void run() {
byte[] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength()));
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(dis);
grabber.setFormat("mulaw");
grabber.setSampleRate((int) getAudioFormat().getSampleRate());
grabber.setAudioChannels(getAudioFormat().getChannels());
SourceDataLine soundLine = null;
try {
grabber.start();
if (grabber.getSampleRate() > 0 && grabber.getAudioChannels() > 0) {
AudioFormat audioFormat = new AudioFormat(grabber.getSampleRate(), 16, grabber.getAudioChannels(), true, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
soundLine = (SourceDataLine) AudioSystem.getLine(info);
soundLine.open(audioFormat);
soundLine.start();
}
ExecutorService executor = Executors.newSingleThreadExecutor();
while (true) {
try {
serverSocket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
Frame frame = grabber.grab();
//if (frame == null) break;
if (frame != null && frame.samples != null) {
ShortBuffer channelSamplesFloatBuffer = (ShortBuffer) frame.samples[0];
channelSamplesFloatBuffer.rewind();
ByteBuffer outBuffer = ByteBuffer.allocate(channelSamplesFloatBuffer.capacity() * 2);
float[] samples = new float[channelSamplesFloatBuffer.capacity()];
for (int i = 0; i < channelSamplesFloatBuffer.capacity(); i++) {
short val = channelSamplesFloatBuffer.get(i);
outBuffer.putShort(val);
}
if (soundLine == null) return;
try {
SourceDataLine finalSoundLine = soundLine;
executor.submit(() -> {
finalSoundLine.write(outBuffer.array(), 0, outBuffer.capacity());
outBuffer.clear();
}).get();
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
}
}
}
/*
executor.shutdownNow();
executor.awaitTermination(1, SECONDS);
if (soundLine != null) {
soundLine.stop();
}
grabber.stop();
grabber.release();*/
} catch (ExecutionException ex) {
System.out.println("ExecutionException");
ex.printStackTrace();
} catch (org.bytedeco.javacv.FrameGrabber.Exception ex) {
System.out.println("FrameGrabberException");
ex.printStackTrace();
} catch (LineUnavailableException ex) {
System.out.println("LineUnavailableException");
ex.printStackTrace();
}/* catch (InterruptedException e) {
System.out.println("InterruptedException");
e.printStackTrace();
}*/
}
public static void main(String[] args) throws SocketException, UnknownHostException {
Runnable apRunnable = new FrameGrabber(7780);
Thread ap = new Thread(apRunnable);
ap.start();
}
}
На этом этапе я пытаюсь воспроизвести аудиофайл в своих динамиках, но получаю следующие журналы:
Задача: FrameGrabber.main ()
Неверное возвращаемое значение 0 для потокового протокола
Неверное возвращаемое значение 0 для потокового протокола
Введите # 0, мулав, из 'java.io.DataInputStream@474e6cea':
Длительность: н / д, битрейт: 352 кб / с
Поток # 0: 0: Аудио: pcm_mulaw, 44100 Гц, 1 канал, s16, 352 кбит / с
Неверное возвращаемое значение 0 для потокового протокола
Неверное возвращаемое значение 0 для потокового протокола
Неверное возвращаемое значение 0 для потокового протокола
Неверное возвращаемое значение 0 для потокового протокола
...
Что я делаю не так?
Заранее спасибо!