abwayaxkauchaomai
unread,Oct 6, 2009, 4:58:55 PM10/6/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to xuggler-users
I'm trying to use Xuggler to record a video of the user's monitor and
combine it with audio from microphone input. I'm following the
MediaTools screen grabber example combined with code using the Java
Sound API to access the microphone. The capture class runs in a
separate thread along with a GUI that features a stop/start capture
button.
I have searched this group, the wiki, and the JavaDocs for information
that might help. All the examples I found dealt either with using an
existing sound file or generating sound from scratch, not with using
sound data gathered from a microphone.
I have also considered running a separate thread for capturing audio
into an audio file and merging the two after ending the capture, but I
felt that for larger captures this would not be efficient.
I find that when I try to compile and I create the finalized video
output in mp4, I am only getting video; no audio. I think this is
because the audio isn't correctly being encoded into the mp4
container. Can you please help me debug this problem; where in my code
am I messing up?
************************************************************************************************************
Source code for the capture class below:
************************************************************************************************************
--
/**
* @(#)CaptureThread.java
*
*
* @author
* @version 1.00 2009/10/2
*/
import com.xuggle.xuggler.*;
import com.xuggle.ferry.*;
import com.xuggle.mediatool.*;
import java.awt.*;
import java.awt.image.*;
import java.util.concurrent.TimeUnit;
import javax.sound.sampled.*;
public class CaptureThread extends Thread {
private boolean inCapture = false;
private TargetDataLine line;
private AudioFileFormat.Type targetType;
private AudioInputStream audioInputStream;
private String captureDir;
public CaptureThread() {
// Audio format
AudioFormat audioFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100.0F, 16, 2, 4, 44100.0F, false);
/* Now, we are trying to get a TargetDataLine. The
TargetDataLine is used later to read audio data from it.
If requesting the line was successful, we are opening
it (important!).
*/
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
audioFormat);
try
{
this.line = (TargetDataLine) AudioSystem.getLine(info);
this.line.open(audioFormat);
}
catch (LineUnavailableException e)
{
System.out.println("unable to get a recording line");
e.printStackTrace();
System.exit(1);
}
/* Again for simplicity, we've hardcoded the audio file
type, too.
*/
this.targetType = AudioFileFormat.Type.WAVE;
this.audioInputStream = new AudioInputStream(line);
}
public void startCapture() {
this.inCapture = true;
this.start();
}
public void setCaptureDir(String path) {
captureDir = path;
}
public void stopCapture() {
this.inCapture = false;
}
public void run() {
try {
this.line.start();
this.capture();
} catch(Exception e) {
e.printStackTrace();
}
}
public void capture() throws Exception {
final IRational FRAME_RATE = IRational.make(30);
final int SECONDS_TO_RUN_FOR = 20;
final Robot robot = new Robot();
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Rectangle screenBounds = new Rectangle(toolkit.getScreenSize
());
// First, let's make a IMediaWriter to write the file.
final IMediaWriter writer = ToolFactory.makeWriter(captureDir + "/
output.mp4");
// Add a debugger to the writer
writer.addListener(ToolFactory.makeDebugListener());
// We tell it we're going to add one video stream, with id 0,
// at position 0, and that it will have a fixed frame rate of
// FRAME_RATE.
writer.addVideoStream(0, 0,
FRAME_RATE,
screenBounds.width, screenBounds.height);
// Add audio stream
writer.addAudioStream(1, 0,
1, 44100);
// audio buffer
byte[] audioBuf = new byte[192000];
// Now, we're going to loop
long startTime = System.nanoTime();
while(inCapture) {
//for (int index = 0; index < FRAME_RATE.getDouble(); index++)
//{
// take the screen shot
BufferedImage screen = robot.createScreenCapture(screenBounds);
// convert to the right image type
BufferedImage bgrScreen = xugtest.convertToType(screen,
BufferedImage.TYPE_3BYTE_BGR);
long nanoTs = System.nanoTime()-startTime;
// encode the image to stream #0
writer.encodeVideo(0,bgrScreen,
nanoTs, TimeUnit.NANOSECONDS);
//System.out.println("encoded image: " +index);
// get and encode audio
int nBytesRead = this.line.read(audioBuf, 0, 192000);
System.out.println("Read "+nBytesRead);
// encode audio to stream #1
IBuffer iBuf = IBuffer.make(null,audioBuf,0,192000);
/*System.out.println(iBuf);
for(int i = 0; i < 40960; i++) {
System.out.print((char) audioBuf[i]);
if(i % 100 == 0) System.out.println();
}*/
IAudioSamples smp = IAudioSamples.make(iBuf,
1,IAudioSamples.Format.FMT_S16);
smp.setComplete(true,1,44100,1,IAudioSamples.Format.FMT_S16,
nanoTs / 1000);
smp.put(audioBuf,0,0,192000);
writer.encodeAudio(1,smp);
// increment counter
xugtest.window.increment();
// sleep for framerate milliseconds
Thread.sleep((long) (1000 / FRAME_RATE.getDouble()));
//}
}
// Finally we tell the writer to close and write the trailer if
// needed
this.line.stop();
//this.line.close();
writer.close();
}
}
************************************************************************************************************
************************************************************************************************************
************************************************************************************************************
and here's the contents of test.log:
************************************************************************************************************
2009-10-06 14:16:37,897 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onOpen()
2009-10-06 14:16:37,926 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAddStream(0)
2009-10-06 14:16:37,928 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAddStream(1)
2009-10-06 14:16:38,021 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onOpenStream(0)
2009-10-06 14:16:38,026 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onOpenStream(1)
2009-10-06 14:16:38,027 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWriteHeader()
2009-10-06 14:16:38,096 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWritePacket
(com.xuggle.xuggler.IPacket@81375544[complete:true;dts:2;pts:2;size:
243965;key:true;flags:1;stream index:0;duration:-1;position:-1;time
base:1/30;])
2009-10-06 14:16:38,099 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onVideoPicture
(com.xuggle.xuggler.IVideoPicture@81375920[pixel type:YUV420P;width:
1366;height:768;time stamp:87610;complete:true;size:
1573632;key:true;time base:1/1000000;], BufferedImage@29428e: type = 5
ColorModel: #pixelBits = 24 numComponents = 3 color space =
java.awt.color.ICC_ColorSpace@d0a5d9 transparency = 1 has alpha =
false isAlphaPre = false ByteInterleavedRaster: width = 1366 height =
768 #numDataElements 3 dataOff[0] = 2, 0)
2009-10-06 14:16:38,730 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAudioSamples
(com.xuggle.xuggler.IAudioSamples@81375544[sample rate:44100;channels:
1;format:FMT_S16;time stamp:87610;complete:true;num samples:1;size:
2;key:true;time base:1/1000000;], 1)
2009-10-06 14:16:38,888 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWritePacket
(com.xuggle.xuggler.IPacket@81376480[complete:true;dts:27;pts:27;size:
139679;key:false;flags:0;stream index:0;duration:-1;position:-1;time
base:1/30;])
2009-10-06 14:16:38,900 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onVideoPicture
(com.xuggle.xuggler.IVideoPicture@81375624[pixel type:YUV420P;width:
1366;height:768;time stamp:915825;complete:true;size:
1573632;key:true;time base:1/1000000;], BufferedImage@72ffb: type = 5
ColorModel: #pixelBits = 24 numComponents = 3 color space =
java.awt.color.ICC_ColorSpace@d0a5d9 transparency = 1 has alpha =
false isAlphaPre = false ByteInterleavedRaster: width = 1366 height =
768 #numDataElements 3 dataOff[0] = 2, 0)
2009-10-06 14:16:39,777 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAudioSamples
(com.xuggle.xuggler.IAudioSamples@81375808[sample rate:44100;channels:
1;format:FMT_S16;time stamp:915825;complete:true;num samples:1;size:
2;key:true;time base:1/1000000;], 1)
2009-10-06 14:16:39,982 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWritePacket
(com.xuggle.xuggler.IPacket@81376480[complete:true;dts:60;pts:60;size:
101445;key:false;flags:0;stream index:0;duration:-1;position:-1;time
base:1/30;])
2009-10-06 14:16:39,982 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onVideoPicture
(com.xuggle.xuggler.IVideoPicture@81375808[pixel type:YUV420P;width:
1366;height:768;time stamp:2025722;complete:true;size:
1573632;key:true;time base:1/1000000;], BufferedImage@1193779: type =
5 ColorModel: #pixelBits = 24 numComponents = 3 color space =
java.awt.color.ICC_ColorSpace@d0a5d9 transparency = 1 has alpha =
false isAlphaPre = false ByteInterleavedRaster: width = 1366 height =
768 #numDataElements 3 dataOff[0] = 2, 0)
2009-10-06 14:16:40,984 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAudioSamples
(com.xuggle.xuggler.IAudioSamples@81376048[sample rate:44100;channels:
1;format:FMT_S16;time stamp:2025722;complete:true;num samples:1;size:
2;key:true;time base:1/1000000;], 1)
2009-10-06 14:16:41,141 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWritePacket
(com.xuggle.xuggler.IPacket@83306416[complete:true;dts:95;pts:95;size:
132549;key:false;flags:0;stream index:0;duration:-1;position:-1;time
base:1/30;])
2009-10-06 14:16:41,142 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onVideoPicture
(com.xuggle.xuggler.IVideoPicture@81376080[pixel type:YUV420P;width:
1366;height:768;time stamp:3184314;complete:true;size:
1573632;key:true;time base:1/1000000;], BufferedImage@1f4689e: type =
5 ColorModel: #pixelBits = 24 numComponents = 3 color space =
java.awt.color.ICC_ColorSpace@d0a5d9 transparency = 1 has alpha =
false isAlphaPre = false ByteInterleavedRaster: width = 1366 height =
768 #numDataElements 3 dataOff[0] = 2, 0)
2009-10-06 14:16:42,020 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAudioSamples
(com.xuggle.xuggler.IAudioSamples@81375640[sample rate:44100;channels:
1;format:FMT_S16;time stamp:3184314;complete:true;num samples:1;size:
2;key:true;time base:1/1000000;], 1)
2009-10-06 14:16:42,230 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWritePacket
(com.xuggle.xuggler.IPacket@83306464[complete:true;dts:128;pts:
128;size:15156;key:false;flags:0;stream index:
0;duration:-1;position:-1;time base:1/30;])
2009-10-06 14:16:42,231 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onVideoPicture
(com.xuggle.xuggler.IVideoPicture@81376048[pixel type:YUV420P;width:
1366;height:768;time stamp:4274253;complete:true;size:
1573632;key:true;time base:1/1000000;], BufferedImage@1ce2dd4: type =
5 ColorModel: #pixelBits = 24 numComponents = 3 color space =
java.awt.color.ICC_ColorSpace@d0a5d9 transparency = 1 has alpha =
false isAlphaPre = false ByteInterleavedRaster: width = 1366 height =
768 #numDataElements 3 dataOff[0] = 2, 0)
2009-10-06 14:16:43,108 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onAudioSamples
(com.xuggle.xuggler.IAudioSamples@81375640[sample rate:44100;channels:
1;format:FMT_S16;time stamp:4274253;complete:true;num samples:1;size:
2;key:true;time base:1/1000000;], 1)
2009-10-06 14:16:43,213 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onFlush()
2009-10-06 14:16:43,218 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onWriteTrailer()
2009-10-06 14:16:43,220 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onCloseStream(0)
2009-10-06 14:16:43,220 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onCloseStream(1)
2009-10-06 14:16:43,222 [Thread-3] DEBUG
c.x.mediatool.MediaDebugListener - onClose()
************************************************************************************************************
************************************************************************************************************