javacv icon indicating copy to clipboard operation
javacv copied to clipboard

Not able to receive streamed audio using FFmpegFrameGrabber

Open dbelbert opened this issue 1 year ago • 4 comments

Hi, I am using FFMpegRecorer to stream audio with "wav" format from one java application and using FFMpegGrabber in another java application to receive the stream but I am getting the following error while starting the FFMpegGrabber,

Error: [wav @ 00000166fe631c00] invalid start code [33][25]EB in RIFF header Error: [wav @ 00000166fe631c00] invalid start code [33][25]Eq in RIFF header avformat_open_input() error -1094995529: Could not open input "udp://127.0.0.1:1234". (Has setFormat() been called?) (For more details, make sure FFmpegLogCallback.set() has been called.)

What did I do wrong in the following code?

Code I am using on the streaming side:

public void stream() {
        AudioFormat      audioFormat = new AudioFormat(44100.0F, 16, 2, true, false);
        final int sampleRate = (int) audioFormat.getSampleRate();
        final int numChannels = audioFormat.getChannels();
        final int audioBufferSize = sampleRate * numChannels;
        final byte[] audioBytes = new byte[audioBufferSize];
        dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
        micDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
        micDataLine.open(audioFormat);
        micDataLine.start();
        FFmpegFrameRecorder  frameRecorderForStreamAudio = new FFmpegFrameRecorder("udp://127.0.01:1234", 2);
        frameRecorderForStreamAudio.setInterleaved(true);
        frameRecorderForStreamAudio.setFormat("wav");
        frameRecorderForStreamAudio.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        frameRecorderForStreamAudio.setAudioOption("preset", "veryfast");
        frameRecorderForStreamAudio.setAudioOption("tune", "zerolatency");
        frameRecorderForStreamAudio.setOption("force_key_frames", "0:00:01");
        frameRecorderForStreamAudio.setGopSize(1);
        frameRecorderForStreamAudio.start();
             timer = new Timer(true);
             timerTask = new TimerTask() {
             @Override
             public void run() {
                int nBytesRead = micDataLine.read(audioBytes, 0, micDataLine.available());
                int nSamplesRead = nBytesRead / 2;
                short[] samples = new short[nSamplesRead];
                ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
                ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);
                if (!isStreamingPaused) {
                    try {
           
                        frameRecorderForStreamAudio.recordSamples(sampleRate, numChannels, sBuff);

                    } catch (FFmpegFrameRecorder.Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        timer.schedule(timerTask, 1000, (long) 1000 / Constants.VIDEO_FRAME_RATE);
    }

Code I am using on the receiver end,

    class PlayAudio implements Runnable {
        protected volatile boolean runnable = false;

        @Override
        public void run() {
            synchronized (this) {
                try {
                    FFmpegFrameGrabberframeGrabberForReceiveAudio = new FFmpegFrameGrabber("udp://127.0.0.1:1234");
                    frameGrabberForReceiveAudio.setFormat("wav");
                    frameGrabberForReceiveAudio.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
                    System.setProperty("org.bytedeco.javacpp.logger.debug", "true");
                    FFmpegLogCallback.set();
                    **frameGrabberForReceiveAudio.start();**
              

              } catch (FFmpegFrameGrabber.Exception e) {
                    logger.log(Level.SEVERE, e.getMessage());
                }
                if (frameGrabberForReceiveAudio.getAudioChannels() > 0) {
                    final AudioFormat audioFormat = new AudioFormat(frameGrabberForReceiveAudio.getSampleRate(), 16, 
                    frameGrabberForReceiveAudio.getAudioChannels(), true, true);
                    final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
                    try {
                        speakerDataLine = (SourceDataLine) AudioSystem.getLine(info);
                        speakerDataLine.open(audioFormat);
                        speakerDataLine.start();
                    } catch (LineUnavailableException e) {
                        throw new RuntimeException(e);
                    }
                    try {
                        Frame f = frameGrabberForReceiveAudio.grab();
                        logger.info("Started receiving audio stream");
                        hideBtnVideoLoadingIndicator();
                        indicateMediaLive();
                        showBtnPauseStreamedMedia();
                        while (frameGrabberForReceiveAudio.grab() != null) {
                            ShortBuffer channelSamplesShortBuffer = (ShortBuffer) f.samples[0];
                            channelSamplesShortBuffer.rewind();
                            final ByteBuffer outBuffer = ByteBuffer.allocate(channelSamplesShortBuffer.capacity() * 2);
                            for (int i = 0; i < channelSamplesShortBuffer.capacity(); i++) {
                                short val = channelSamplesShortBuffer.get(i);
                                outBuffer.putShort(val);
                            }
                            if (!isStreamedAudioPaused) {
                                speakerDataLine.write(outBuffer.array(), 0, outBuffer.capacity());
                            }
//                        logger.info("Playing");
                        }
                    } catch (FFmpegFrameGrabber.Exception e) {
                        logger.info(e.getMessage());
                    }
                }
            }
        }
    }

I also tried to play the audio with ffplay udp://127.0.0.1:1234 from command line there I got the following errors,

[aac @ 0000024d68f7e5c0] Reserved bit set. [aac @ 0000024d68f7e5c0] Prediction is not allowed in AAC-LC. [aac @ 0000024d68f7e5c0] Number of scalefactor bands in group (43) exceeds limit (40). [aac @ 0000024d68f7e5c0] Reserved bit set. 0KB sq= 0B f=0/0 [aac @ 0000024d68f7e5c0] channel element 3.12 is not allocated [aac @ 0000024d68f7e5c0] channel element 2.9 is not allocated=0/0 [aac @ 0000024d68f7e5c0] Prediction is not allowed in AAC-LC.=0/0 [aac @ 0000024d68f7e5c0] channel element 3.1 is not allocated [aac @ 0000024d68f7e5c0] channel element 3.2 is not allocated=0/0 [aac @ 0000024d68f7e5c0] channel element 3.4 is not allocated=0/0 [aac @ 0000024d68f7e5c0] Number of bands (17) exceeds limit (12). [aac @ 0000024d68f7e5c0] channel element 2.2 is not allocated=0/0 [aac @ 0000024d68f7e5c0] Number of bands (25) exceeds limit (23). [aac @ 0000024d68f7e5c0] Sample rate index in program config element does not match the sample rate index configured by the container. [aac @ 0000024d68f7e5c0] Too large remapped id is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented. [aac @ 0000024d68f7e5c0] If you want to help, upload a sample of this file to https://streams.videolan.org/upload/ and contact the ffmpeg-devel mailing list. ([email protected]) [aac @ 0000024d68f7e5c0] Sample rate index in program config element does not match the sample rate index configured by the container.

dbelbert avatar Aug 04 '22 11:08 dbelbert

UDP is an unreliable protocol. You may want to try TCP instead.

saudet avatar Aug 04 '22 12:08 saudet

Sorry for the delayed response, I am already using UDP protocol for video streaming(h264 format) and it is working perfectly.

dbelbert avatar Aug 06 '22 08:08 dbelbert

I can stream aac audio with containers "mpegts" or "flv" but never got it working with "wav". You might want to try these or "rtp" as the format.

Nycrera avatar Aug 12 '22 09:08 Nycrera

I can stream aac audio with containers "mpegts" or "flv" but never got it working with "wav". You might want to try these or "rtp" as the format.

Thank you Nycrera, After changing the format to "flv" it is working fine.

dbelbert avatar Aug 12 '22 20:08 dbelbert