The follow steps are what I've done to make Xuggler operate with Processing 2.0b5 or 2.0b6 with Windows 7 64 bit:
Step 1: Download and Install the Xuggler 64 bit Build for Windows. Available here.
Step 2: Download the necessary Xuggler jars, I've zipped them together and can be downloaded from here. I've placed the jars files in the zipped folder within my processing sketch, in a folder called 'code.'
Step 3: You can either download and run my example code from here (jars included), or look at the example code below the video.
Here's an example of some work I did with Xuggler in processing:
My next tutorial will be about how to set up the Youtube data API with processing, to be able to automatically upload these videos to your youtube account.
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.util.concurrent.TimeUnit;
import java.awt.*;
import processing.video.*;
import javax.sound.sampled.*;
IMediaWriter imw;
IStreamCoder isc;
BufferedImage bgr;
int vidRate = 30;
long sTime;
long fTime;
Capture cam;
final int audioStreamIndex = 1;
final int audioStreamId = 1;
final int channelCount = 2;
int sampleRate;
AudioFormat audioFormat;
AudioInputStream audioInputStream;
TargetDataLine aline;
AudioFormat targetType;
byte[] audioBuf;
int audionumber;
int widthCapture=640;
int heightCapture=480;
boolean recording;
void setup() {
frameRate(30);
size(widthCapture, heightCapture, JAVA2D);
cam = new Capture(this, widthCapture, heightCapture);
cam.start();
avSetup();
}
void draw() {
if (cam.available()) {
cam.read();
image(cam.get(), 0, 0);
if (recording) {
if (imw.isOpen()) {
//video recording stuff
long cTime = System.nanoTime()-fTime;
if (cTime >= (double)1000/vidRate) {
bgr.getGraphics().drawImage(cam.getImage(), 0, 0,
new ImageObserver() {
public boolean imageUpdate(Image i, int a, int b, int c, int d, int e) {
return true;
}
}
);
imw.encodeVideo(0, bgr, System.nanoTime()-sTime, TimeUnit.NANOSECONDS);
//audio recording stuff
if (aline.available() == 88200) {
int nBytesRead = aline.read(audioBuf, 0, aline.available());//audioBuf.length);//aline.available());
if (nBytesRead>0) {
IBuffer iBuf = IBuffer.make(null, audioBuf, 0, nBytesRead);
IAudioSamples smp = IAudioSamples.make(iBuf, channelCount, IAudioSamples.Format.FMT_S16);
if (smp!=null) {
long numSample = nBytesRead/smp.getSampleSize();
smp.setComplete(true, numSample, (int) audioFormat.getSampleRate(), audioFormat.getChannels(), IAudioSamples.Format.FMT_S16, (System.nanoTime()-sTime) / 1000);
smp.put(audioBuf, 1, 0, aline.available());
try {
imw.encodeAudio(audionumber, smp);
}
catch(Exception e) {
println("EXCEPTION: " + e);
}
}
}
}
fTime = System.nanoTime();
}
}
}
}
}
public void keyPressed() {
if (key == 'r') {
if (!recording) {
println("recording");
avRecorderSetup();
recording = true;
}
}
if (key == 's') {
if (recording) {
println("saving");
imw.flush();
imw.close();
recording = false;
}
}
}
void avSetup() {
audioFormat = new AudioFormat(44100.0F, 16, channelCount, true, false);
sampleRate = (int) audioFormat.getSampleRate();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
try {
aline = (TargetDataLine) AudioSystem.getLine(info);
aline.open(audioFormat);
aline.start();
println("audio line");
}
catch (LineUnavailableException e)
{
println("unable to get a recording line");
e.printStackTrace();
exit();
}
int bufferSize = (int) audioFormat.getSampleRate() * audioFormat.getFrameSize();
audioBuf = new byte[bufferSize];
targetType = aline.getFormat();
audioInputStream = new AudioInputStream(aline);
}
void avRecorderSetup() {
imw = ToolFactory.makeWriter(sketchPath("D:/myVideo.mp4"));//or "output.avi" or "output.mov"
imw.open();
imw.setForceInterleave(true);
imw.addVideoStream(0, 0, IRational.make((double)vidRate), widthCapture, heightCapture);
audionumber = imw.addAudioStream(audioStreamIndex, audioStreamId, channelCount, sampleRate);
isc = imw.getContainer().getStream(0).getStreamCoder();
bgr = new BufferedImage(widthCapture, heightCapture, BufferedImage.TYPE_3BYTE_BGR);
sTime = fTime = System.nanoTime();
}
Thanks for the tutorial.
ReplyDeleteI noticed an error on the first Xuggler link (first line).
Are you referring to the xuggler imports on the first few lines? So another way to do step 2 is to take those jars and make a xuggler library in the processing libraries folder, and that's how I made mine. I thought it might be easier to just let people download the jars and put it in the code folder. Either way works...
ReplyDeleteI removed those three imports, so it won't throw that library error.
ReplyDeleteThanks for the tutorial. By any chance would you know from where to down load the 32 bit version of Xuggler 64 bit Build for Windows?
ReplyDeleteI'm sorry, I don't know where you can download it...
ReplyDeletecan anyone help me with this code to extract audio from video using xuggler
ReplyDeletemy code is here
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.ICodec;
public class convert {
public static void main(String args[]){
IMediaReader reader = ToolFactory.makeReader("F:/input.flv");
IMediaWriter writer = ToolFactory.makeWriter("F:/output.mp3", reader);
int sampleRate = 128000;
int channels = 1;
writer.addAudioStream(0, 0, ICodec.ID.CODEC_ID_MP3, channels, sampleRate);
while (reader.readPacket() == null);
}
}