您好,我设法拍摄了 @ 30fps 的视频,或者我们甚至可以从我的想法中获得 @60 fps 的视频,而且我的视频非常流畅
如果有人对此感兴趣,请检查一下。
这个想法很简单,我们希望以 60fps 或 29.97fps(我的视频)的速度对每一帧进行屏幕截图。
分 3 步完成:1) 以 1/60 渲染所有内容作为屏幕的增量时间
2)拍摄每一帧的屏幕截图
3)制作所有这些png文件的视频(我使用adobe Premiere pro)
第 1 步)在 libgdx 中,我扩展了 Game 类并创建了一个新类 MyGame extends Game 或类 MyGame 扩展 ApplicationListener 现在更改其渲染方法以供临时使用
ScreenShotUtils screenShotUtils=new ScreenShotUtils();
@Override
public void render () {
//if (screen != null) screen.render(Gdx.graphics.getDeltaTime());
//write your video fps as 1f/29.97f or 1f/30f
if (screen != null){
screen.render(1f/60f);
screenShotUtils.update();
}
}
Step 2) 使用 ScreenShotUtils 类的 capture 方法截屏 当您需要截屏时调用 capture 方法只需在您的游戏中制作一个按钮来开始和停止录制
//call on start click
screenShotUtils.capture(true);
//call on stop click
screenShotUtils.capture(false);
注意:当你开始抓图游戏会卡顿,它会超级慢,但是渲染增量时间不会让 ui 更新低于 60 fps,你会得到 60 fps 的截图,现在在这个延迟期间玩游戏并且您将在视频发布过程中获得流畅的图像序列
public class ScreenShotUtils {
String filefolder="D:/capturefolder";// your folder to put the images in
String filenameprefix="";
int frameid=0,captureLimit=-1;
private boolean isCapturing=false;
public void setCaptureLimit(int frames){
captureLimit=frames;
}
public boolean isCapturing(){
return isCapturing;
}
public void capture(boolean capture){
if(capture){
if(!isCapturing) {
isCapturing = true;
filenameprefix="Demo"+System.currentTimeMillis();//Images Prefix
frameid=0;
}
}else{
isCapturing=false;
captureLimit=-1;
frameid=0;
}
}
public void capture(boolean capture, int frames){
if(capture){
if(!isCapturing) {
isCapturing = true;
filenameprefix="Demo"+System.currentTimeMillis();//Images Prefix
frameid=0;
}
captureLimit=frames;
}else{
isCapturing=false;
captureLimit=-1;
frameid=0;
}
}
public void update() {
// render before capturing
if(isCapturing) {
if(captureLimit<0)
saveScreenshot();
else
if(captureLimit==0){
isCapturing = false;
captureLimit=-1;
}else{
saveScreenshot();
captureLimit--;
}
}
}
private void saveScreenshot() {
int MAX_DIGITS = 6;
String fname = "" + (frameid++);
int zeros = MAX_DIGITS - fname.length();
for (int i = 0; i < zeros; i++) {
fname = "0" + fname;
}
FileHandle file = new FileHandle(filefolder+"/"+filenameprefix +"-"+ fname+".png");
Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight(), true);
PixmapIO.writePNG(file, pixmap);
pixmap.dispose();
}
private Pixmap getScreenshot(int x, int y, int w, int h, boolean flipY) {
Gdx.gl.glPixelStorei(GL20.GL_PACK_ALIGNMENT, 1);
Pixmap pixmap = new Pixmap(w, h, Pixmap.Format.RGB888);
ByteBuffer pixels = pixmap.getPixels();
Gdx.gl.glReadPixels(x, y, w, h, GL20.GL_RGB, GL20.GL_UNSIGNED_BYTE, pixels);
if (flipY) {
final int numBytes = w * h * 3;
byte[] lines = new byte[numBytes];
final int numBytesPerLine = w * 3;
for (int i = 0; i < h; i++) {
pixels.position((h - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
}
return pixmap;
}
}
3)我使用adobe Premiere pro制作视频,你可以使用其他工具搜索google(将图像序列转换为视频)
https://helpx.adobe.com/premiere-pro/using/importing-still-images.html
部分:将图像作为图像序列导入
注意:我使用格式为 RGB 而不是 RGBA 的屏幕截图,因为 alpha 位弄乱了图像的边界。你可以试试看
此外,您可以修改代码以将文件保存到 android sdcard 我使用桌面版本,只需更改 saveScreenshot 方法的文件句柄
免责声明:我使用了截图代码并从本网站修改了它们http://www.wendytech.de/2012/07/opengl-screen-capture-in-real-time/