I'm trying to play sound from an FFMpegFrameGrabber
by getting the Frame
and sending the audio samples to a SourceDataLine
. Here's what I have so far:
Creating the SourceDataLine
:
int channels = _grabber.getAudioChannels();
int format = _grabber.getSampleFormat();
AudioFormat fmt = new AudioFormat(_grabber.getSampleRate(), format, channels, true, true);
_sourceDataLine=(SourceDataLine)AudioSystem.getLine(new DataLine.Info(SourceDataLine.class, fmt));
_sourceDataLine.open(fmt);
_sourceDataLine.start();
Attempting to play sound (images are handled in the else block):
org.bytedeco.javacv.Frame f = _grabber.grabFrame();
if (f.samples != null && f.samples.length > 0)
{
byte[] bytes = new byte[4096];
for (Buffer buffer : f.samples)
{
FloatBuffer floatBuffer = (FloatBuffer) buffer;
ByteBuffer byteBuffer = ByteBuffer.allocate(floatBuffer.capacity() * 4);
byteBuffer.asFloatBuffer().put(floatBuffer);
byteBuffer.rewind();
byteBuffer.get(bytes);
_sourceDataLine.write(bytes, 0, bytes.length);
}
}
(Note: I tried a few different versions of this and they all have static. The versions I tried included combining the buffers into one large buffer, only trying to play one sample instead of each channel, and changing the audio format to many different permutations.)
The problem is the sound is full of static, and almost completely unintelligible. This is my first time doing any audio programming, so I'm sure I'm doing something completely ridiculous.
I appreciate any help. Thank you.
EDIT
In response to Radiodef, I tried a number of AudioFormats, and I couldn't find one that worked for PCM_FLOAT. I found an example that used this:
fmt = new AudioFormat(AudioFormat.Encoding.PCM_FLOAT, _grabber.getSampleRate(), format, channels, channels, _grabber.getSampleRate(), true);
Note: I tried a few different values for the framesize from examples: channels * format / 8
, channels * 8
with a hardcoded samplerate of 64, channels * 4
with a hardcoded samplerate of 32, and any combinations of those
But it give me this exception:
java.lang.IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_FLOAT 44100.0 Hz, 8 bit, stereo, 2 bytes/frame, is supported.
at javax.sound.sampled.AudioSystem.getLine(Unknown Source)
at com.enplug.player.video.Video.<init>(Video.java:52) <- where I get the SourceDataLine
...
EDIT 2
Sorry for the delay. I appreciate all the help Radiodef.
Here is some output from the FFMpegGrabber that is automatically output.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\Users\Shawn\AppData\Roaming\Enplug Display\Download\Resource\c7cb496d-96ea-4be8-a238-5ffd50955a3e.mp4':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2014-10-02 07:14:38
Duration: 00:00:31.13, start: 0.000000, bitrate: 2412 kb/s
Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 246 kb/s (default)
Metadata:
creation_time : 2014-10-02 07:14:38
handler_name : Core Media Data Handler
Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720, 2157 kb/s, 30 fps, 30 tbr, 600 tbn, 1200 tbc (default)
Metadata:
creation_time : 2014-10-02 07:14:38
handler_name : Core Media Data Handler
encoder : H.264
I have two videos I'm testing with, and the first one (which is the one in the example above) has the following:
Bit rate: 247 kbps
Channels: 2 (stereo)
Audio sample rate: 44 kHz
And the second is:
Bit rate: 161 kbps
Channels: 2 (stereo)
Audio sample rate: 48 kHz
They're both mp4s, and I can provide any details about the video itself if needed.
As for the library, yeah I'm pretty locked into JavaCV. We already have videos running without sound, but we're now trying to add sound to our program.
When I run the sample program from your JSR link I get:
PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian