gpt4 book ai didi

java - TargetDataLine 和 Xuggler 用屏幕视频录制音频

转载 作者:行者123 更新时间:2023-11-30 04:33:32 25 4
gpt4 key购买 nike

到目前为止,

TargetDataLine 对我来说是用 Java 捕获麦克风输入的最简单方法。我想对[在屏幕录像机软件中]使用屏幕视频捕获的音频进行编码,以便用户可以创建教程、幻灯片案例等。
我使用 Xuggler 对视频进行编码。
他们确实有一个关于用视频编码音频的教程,但他们从文件中获取音频。就我而言,音频是实时的。



为了对视频进行编码,我使用 com.xuggle.mediaTool.IMediaWriter。 IMediaWriter 对象允许我添加视频流并具有
encodeAudio(intstreamIndex,short[]样本,longtimeStamp,TimeUnittimeUnit)
如果我可以从目标数据行获取样本作为 short[],我就可以使用它。它返回 byte[]
所以两个问题是:

如何将实时音频编码为视频?

如何保持音频数据包的正确时序,以便在正确的时间对其进行编码?

引用文献:
1. TargetDataLine 的 DavaDoc:http://docs.oracle.com/javase/1.4.2/docs/api/javax/sound/sampled/TargetDataLine.html
2.Xuggler 文档:http://build.xuggle.com/view/Stable/job/xuggler_jdk5_stable/javadoc/java/api/index.html



更新

我的捕获视频的代码

public void run(){
final IRational FRAME_RATE = IRational.make(frameRate, 1);
final IMediaWriter writer = ToolFactory.makeWriter(completeFileName);
writer.addVideoStream(0, 0,FRAME_RATE, recordingArea.width, recordingArea.height);
long startTime = System.nanoTime();

while(keepCapturing==true){
image = bot.createScreenCapture(recordingArea);
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
Point globalPosition = pointerInfo.getLocation();

int relativeX = globalPosition.x - recordingArea.x;
int relativeY = globalPosition.y - recordingArea.y;

BufferedImage bgr = convertToType(image,BufferedImage.TYPE_3BYTE_BGR);
if(cursor!=null){
bgr.getGraphics().drawImage(((ImageIcon)cursor).getImage(), relativeX,relativeY,null);
}
try{
writer.encodeVideo(0,bgr,System.nanoTime()-startTime,TimeUnit.NANOSECONDS);
}catch(Exception e){
writer.close();
JOptionPane.showMessageDialog(null,
"Recording will stop abruptly because" +
"an error has occured", "Error",JOptionPane.ERROR_MESSAGE,null);
}

try{
sleep(sleepTime);
}catch(InterruptedException e){
e.printStackTrace();
}
}
writer.close();

}

最佳答案

我最近在这个问题下回答了大部分内容:Xuggler encoding and muxing

代码示例:

writer.addVideoStream(videoStreamIndex, 0, videoCodec, width, height);
writer.addAudioStream(audioStreamIndex, 0, audioCodec, channelCount, sampleRate);

while (... have more data ...)
{
BufferedImage videoFrame = ...;
long videoFrameTime = ...; // this is the time to display this frame
writer.encodeVideo(videoStreamIndex, videoFrame, videoFrameTime, DEFAULT_TIME_UNIT);

short[] audioSamples = ...; // the size of this array should be number of samples * channelCount
long audioSamplesTime = ...; // this is the time to play back this bit of audio
writer.encodeAudio(audioStreamIndex, audioSamples, audioSamplesTime, DEFAULT_TIME_UNIT);
}

对于 TargetDataLine,getMicrosecondPosition()会告诉您audioSamplesTime 所需的时间。这似乎是从 TargetDataLine 打开时开始的。您需要弄清楚如何获取引用同一时钟的视频时间戳,这取决于视频设备和/或捕获视频的方式。只要它们都使用相同的时钟,绝对值并不重要。您可以从视频和音频时间中减去初始值(在流开始时),以便时间戳匹配,但这只是某种近似匹配(在实践中可能足够接近)。

您需要严格按照时间递增顺序调用encodeVideoencodeAudio;您可能需要缓冲一些音频和一些视频以确保可以做到这一点。更多详情here .

关于java - TargetDataLine 和 Xuggler 用屏幕视频录制音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14029555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com