javacv
javacv copied to clipboard
Not able to receive streamed audio using FFmpegFrameGrabber
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.
UDP is an unreliable protocol. You may want to try TCP instead.
Sorry for the delayed response, I am already using UDP protocol for video streaming(h264 format) and it is working perfectly.
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.
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.