我想将视频和音频一起录制,并且有很多方法,但是在视频播放之前播放的音频存在问题,可能长度不一样......
从https://stackoverflow.com/questions/19238732/adding-audio-to-xuggler-webacm-capture
部分解决我有一种感觉,我的问题是音频样本的长度,但我不确定如何最好地修复它;拜托,你能帮忙吗?代码:
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import com.xuggle.ferry.IBuffer;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IAudioSamples.Format;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IPixelFormat;
import com.xuggle.xuggler.IRational;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.TestAudioSamplesGenerator;
import com.xuggle.xuggler.io.XugglerIO;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Encoder {
public static int audioTime = 0;
public static long start = System.currentTimeMillis();
public static IMediaWriter writer;
public static void main(String[] args) throws Throwable {
JFrame window = new JFrame("vid");
window.setVisible(true);
File file = new File("output.mov");
List<Webcam> list = Webcam.getWebcams();
for (int i = 0; i < list.size(); i++) {
try {
Webcam cam = list.get(i);
System.out.println("Found this Camera : "+cam.getName());
BufferedImage image = cam.getImage();
} catch (Exception e) {
System.out.println("Exception in cam : " + i);
}
}
writer = ToolFactory.makeWriter(file.getName());
Dimension size = WebcamResolution.QVGA.getSize();
Webcam webcam = Webcam.getDefault();
webcam.setViewSize(size);
webcam.open(true);
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
writer.addAudioStream(1, 0, ICodec.ID.CODEC_ID_AAC, 2, 44100);
long time = (System.currentTimeMillis() - start) * 1000;
for (int i = 0; i < 100; i++) {
System.out.println("Capture frame " + i);
BufferedImage image = ConverterFactory.convertToType(webcam.getImage(), BufferedImage.TYPE_3BYTE_BGR);
IConverter converter = ConverterFactory.createConverter(image, IPixelFormat.Type.YUV420P);
long len = (System.currentTimeMillis() - start) * 1000 - time;
time = (System.currentTimeMillis() - start) * 1000;
IVideoPicture frame = converter.toPicture(image, time);
frame.setKeyFrame(i == 0);
frame.setQuality(0);
writer.encodeVideo(0, frame);
IAudioSamples samples = customAudioStream(len);
writer.encodeAudio(1, samples);
window.setSize(200,200);
window.getContentPane().removeAll();
window.getContentPane().add(new JLabel(new ImageIcon(image)));
window.getContentPane().validate();
window.getContentPane().invalidate();
window.getContentPane().repaint();
// 10 FPS
Thread.sleep(0,500);
}
writer.close();
window.dispose();
System.out.println("Video recorded in file: " + file.getAbsolutePath());
}
public static IAudioSamples customAudioStream(long length){
// audio parameters
int channelCount = 2;
int sampleRate = 44100;
int len = (int)length/1000;
IContainer container = writer.getContainer();
IStream stream = container.getStream(1);
int sampleCount = stream.getStreamCoder().getDefaultAudioFrameSize();
// create a place for audio samples
IAudioSamples samples = IAudioSamples.make(1024*5, channelCount, IAudioSamples.Format.FMT_S16);
TargetDataLine line = null;
AudioFormat audioFormat = new AudioFormat(sampleRate, (int)16, channelCount, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
} catch (LineUnavailableException ex) {
System.out.println("ERROR: "+ex.toString());
}
line.start();
byte[] data = new byte[4096*5];
int sz = line.read(data, 0, data.length);
samples.put(data, 0, 0, sz);
audioTime += (sz);
double sAudioTime = (audioTime)/44.1000;
samples.setComplete(true, sz/4, sampleRate, channelCount, Format.FMT_S16, audioTime/4);
System.out.println(len + " : " + sampleCount + " : " + data.length + " : " + sz + " : " + audioTime + " : " + line.available());
return(samples);
}
}
如果有更好的方法,我也是耳朵。 谢谢! 编