Как программно прочитать аудиопоток RTP, используя javacv и ffmpeg? - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь прочитать аудиопоток 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 для потокового протокола ...

Что я делаю не так?

Заранее спасибо!

...