001/******************************************************************************* 002 * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved. 003 * 004 * This file is part of AVPKit. 005 * 006 * AVPKit is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Lesser General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * AVPKit is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with AVPKit. If not, see <http://www.gnu.org/licenses/>. 018 *******************************************************************************/ 019 020package com.avpkit.mediatool.demos; 021import java.awt.Rectangle; 022import java.awt.Robot; 023import java.awt.Toolkit; 024import java.awt.image.BufferedImage; 025import java.util.concurrent.TimeUnit; 026 027import com.avpkit.mediatool.ToolFactory; 028import com.avpkit.mediatool.IMediaWriter; 029import com.avpkit.core.IRational; 030 031/** 032 * Using {@link IMediaWriter}, takes snapshots of your desktop and 033 * encodes them to video. 034 * 035 * @author aclarke 036 * 037 */ 038 039public class CaptureScreenToFile 040{ 041 private static IRational FRAME_RATE=IRational.make(3,1); 042 private static final int SECONDS_TO_RUN_FOR = 15; 043 044 /** 045 * Takes a screen shot of your entire screen and writes it to 046 * output.flv 047 * 048 * @param args 049 */ 050 public static void main(String[] args) 051 { 052 try 053 { 054 final String outFile; 055 if (args.length > 0) 056 outFile = args[0]; 057 else 058 outFile = "output.mp4"; 059 // This is the robot for taking a snapshot of the 060 // screen. It's part of Java AWT 061 final Robot robot = new Robot(); 062 final Toolkit toolkit = Toolkit.getDefaultToolkit(); 063 final Rectangle screenBounds = new Rectangle(toolkit.getScreenSize()); 064 065 // First, let's make a IMediaWriter to write the file. 066 final IMediaWriter writer = ToolFactory.makeWriter(outFile); 067 068 // We tell it we're going to add one video stream, with id 0, 069 // at position 0, and that it will have a fixed frame rate of 070 // FRAME_RATE. 071 writer.addVideoStream(0, 0, 072 FRAME_RATE, 073 screenBounds.width, screenBounds.height); 074 075 // Now, we're going to loop 076 long startTime = System.nanoTime(); 077 for (int index = 0; index < SECONDS_TO_RUN_FOR*FRAME_RATE.getDouble(); index++) 078 { 079 // take the screen shot 080 BufferedImage screen = robot.createScreenCapture(screenBounds); 081 082 // convert to the right image type 083 BufferedImage bgrScreen = convertToType(screen, 084 BufferedImage.TYPE_3BYTE_BGR); 085 086 // encode the image 087 writer.encodeVideo(0,bgrScreen, 088 System.nanoTime()-startTime, TimeUnit.NANOSECONDS); 089 090 System.out.println("encoded image: " +index); 091 092 // sleep for framerate milliseconds 093 Thread.sleep((long) (1000 / FRAME_RATE.getDouble())); 094 095 } 096 // Finally we tell the writer to close and write the trailer if 097 // needed 098 writer.close(); 099 } 100 catch (Throwable e) 101 { 102 System.err.println("an error occurred: " + e.getMessage()); 103 } 104 } 105 /** 106 * Convert a {@link BufferedImage} of any type, to {@link BufferedImage} of a 107 * specified type. If the source image is the same type as the target type, 108 * then original image is returned, otherwise new image of the correct type is 109 * created and the content of the source image is copied into the new image. 110 * 111 * @param sourceImage 112 * the image to be converted 113 * @param targetType 114 * the desired BufferedImage type 115 * 116 * @return a BufferedImage of the specifed target type. 117 * 118 * @see BufferedImage 119 */ 120 121 public static BufferedImage convertToType(BufferedImage sourceImage, 122 int targetType) 123 { 124 BufferedImage image; 125 126 // if the source image is already the target type, return the source image 127 128 if (sourceImage.getType() == targetType) 129 image = sourceImage; 130 131 // otherwise create a new image of the target type and draw the new 132 // image 133 134 else 135 { 136 image = new BufferedImage(sourceImage.getWidth(), 137 sourceImage.getHeight(), targetType); 138 image.getGraphics().drawImage(sourceImage, 0, 0, null); 139 } 140 141 return image; 142 } 143 144}